1# cpexprs.exp - C++ expressions tests 2# 3# Copyright 2008-2020 Free Software Foundation, Inc. 4# 5# Contributed by Red Hat, originally written by Keith Seitz. 6# 7# This program is free software; you can redistribute it and/or modify 8# it under the terms of the GNU General Public License as published by 9# the Free Software Foundation; either version 3 of the License, or 10# (at your option) any later version. 11# 12# This program is distributed in the hope that it will be useful, 13# but WITHOUT ANY WARRANTY; without even the implied warranty of 14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15# GNU General Public License for more details. 16# 17# You should have received a copy of the GNU General Public License 18# along with this program. If not, see <http://www.gnu.org/licenses/>. 19 20# This file is part of the gdb testsuite. 21 22# A helper proc which sets a breakpoint at FUNC and attempts to 23# run to the breakpoint. 24proc test_breakpoint {func} { 25 global DEC 26 27 # Return to the top of the test function every time. 28 delete_breakpoints 29 if { ! [gdb_breakpoint test_function] } { 30 fail "set test_function breakpoint for $func" 31 } elseif { [gdb_test "continue" \ 32 "Continuing.\r\n\r\nBreakpoint $DEC+,.*test_function.*" \ 33 ""] != 0 } { 34 fail "continue to test_function for $func" 35 } else { 36 gdb_breakpoint "$func" 37 set i [expr {[string last : $func] + 1}] 38 set efunc [string_to_regexp [string range $func $i end]] 39 gdb_test "continue" \ 40 "Continuing.\r\n\r\nBreakpoint $DEC+,.*$efunc.*" \ 41 "continue to $func" 42 } 43} 44 45# Add a function to the list of tested functions 46# FUNC is the name of the function (which will be passed to gdb commands) 47# TYPE is the type of the function, as expected from the "print" command 48# PRINT is the name of the function, as expected result of the print command 49# *OR* "-", indicating that FUNC should be used (needed for virtual/inherited 50# funcs) 51# LST is either the expected result of the list command (the comment from 52# the source code) *OR* "-", in which case FUNC will be used 53# 54# Usage: 55# add NAME TYPE PRINT LST 56# add NAME TYPE PRINT - 57proc add_type_regexp {func type print lst} { 58 global all_functions CONVAR ADDR 59 60 set all_functions($func,type) $type 61 if {$print == "-"} { 62 set print $func 63 } 64 65 # An exception: since gdb canonicalizes C++ output, 66 # "(void)" must be mutated to "()". 67 regsub {\(void\)} $print {()} print 68 69 set all_functions($func,print) \ 70 "$CONVAR = {$type} $ADDR <[string_to_regexp $print].*>" 71 if {$lst == "-"} { 72 set lst "$func" 73 } 74 set all_functions($func,list) ".*// [string_to_regexp $lst]" 75} 76 77proc add {func type print lst} { 78 add_type_regexp $func [string_to_regexp $type] $print $lst 79} 80 81proc get {func cmd} { 82 global all_functions 83 return $all_functions($func,$cmd) 84} 85 86# Returns a list of function names for a given command 87proc get_functions {cmd} { 88 global all_functions 89 set result {} 90 foreach i [array names all_functions *,$cmd] { 91 if {$all_functions($i) != ""} { 92 set idx [string last , $i] 93 if {$idx != -1} { 94 lappend result [string range $i 0 [expr {$idx - 1}]] 95 } 96 } 97 } 98 99 return [lsort $result] 100} 101 102# Some convenience variables for this test 103set DEC {[0-9]}; # a decimal number 104set HEX {[0-9a-fA-F]}; # a hexidecimal number 105set CONVAR "\\\$$DEC+"; # convenience variable regexp 106set ADDR "0x$HEX+"; # address 107 108# An array of functions/methods that we are testing... 109# Each element consists is indexed by NAME,COMMAND, where 110# NAME is the function name and COMMAND is the gdb command that 111# we are testing. The value of the array for any index pair is 112# the expected result of running COMMAND with the NAME as argument. 113 114# The array holding all functions/methods to test. Valid subindexes 115# are (none need character escaping -- "add" will take care of that): 116 117# add name type print_name list 118# NAME,type: value is type of function 119# NAME,print: value is print name of function (careful w/inherited/virtual!) 120# NAME,list: value is comment in source code on first line of function 121# (without the leading "//") 122array set all_functions {} 123 124# "Normal" functions/methods 125add {test_function} \ 126 {int (int, char **)} \ 127 - \ 128 - 129add {derived::a_function} \ 130 {void (const derived * const)} \ 131 - \ 132 - 133add {base1::a_function} \ 134 {void (const base1 * const)} \ 135 - \ 136 - 137add {base2::a_function} \ 138 {void (const base2 * const)} \ 139 - \ 140 - 141 142# Constructors 143 144# On targets using the ARM EABI, the constructor is expected to return 145# "this". 146proc ctor_ret { type } { 147 if { [istarget arm*-*eabi*] || [is_aarch32_target] } { 148 return "$type *" 149 } else { 150 return "void " 151 } 152} 153 154proc ctor_prefix { type } { 155 set ret [ctor_ret $type] 156 return "${ret}($type * const" 157} 158 159proc ctor { type arglist } { 160 if { $arglist != "" } { 161 set arglist ", $arglist" 162 } 163 return "[ctor_prefix $type]$arglist)" 164} 165 166add {derived::derived} \ 167 [ctor derived ""] \ 168 - \ 169 - 170add_type_regexp {base1::base1(void)} \ 171 "[string_to_regexp [ctor_prefix base1]], (const )?void \\*\\*( const)?\\)" \ 172 - \ 173 - 174add {base1::base1(int)} \ 175 [ctor base1 "int"] \ 176 - \ 177 - 178add_type_regexp {base2::base2} \ 179 "[string_to_regexp [ctor_prefix base2]], (const )?void \\*\\*( const)?\\)" \ 180 - \ 181 - 182add {base::base(void)} \ 183 [ctor base ""] \ 184 - \ 185 - 186add {base::base(int)} \ 187 [ctor base "int"] \ 188 - \ 189 - 190 191# Destructors 192 193# On targets using the ARM EABI, some destructors are expected 194# to return "this". Others are void. For internal reasons, 195# GCC returns void * instead of $type *; RealView appears to do 196# the same. 197proc dtor { type } { 198 if { [istarget arm*-*eabi*] || [is_aarch32_target] } { 199 set ret "void *" 200 } else { 201 set ret "void " 202 } 203 return "${ret}($type * const)" 204} 205 206add {base::~base} \ 207 [dtor base] \ 208 - \ 209 - 210 211# Overloaded methods (all are const) 212add {base::overload(void) const} \ 213 {int (const base * const)} \ 214 - \ 215 {base::overload(void) const} 216add {base::overload(int) const} \ 217 {int (const base * const, int)} \ 218 - \ 219 - 220add {base::overload(short) const} \ 221 {int (const base * const, short)} \ 222 - \ 223 - 224add {base::overload(long) const} \ 225 {int (const base * const, long)} \ 226 - \ 227 - 228add {base::overload(char*) const} \ 229 {int (const base * const, char *)} \ 230 - \ 231 - 232add {base::overload(base&) const} \ 233 {int (const base * const, base &)} \ 234 - \ 235 - 236 237# Operators 238add {base::operator+} \ 239 {int (const base * const, const base &)} \ 240 - \ 241 - 242add {base::operator++} \ 243 {base (base * const)} \ 244 - \ 245 - 246add {base::operator+=} \ 247 {base (base * const, const base &)} \ 248 - \ 249 - 250add {base::operator-} \ 251 {int (const base * const, const base &)} \ 252 - \ 253 - 254add {base::operator--} \ 255 {base (base * const)} \ 256 - \ 257 - 258add {base::operator-=} \ 259 {base (base * const, const base &)} \ 260 - \ 261 - 262add {base::operator*} \ 263 {int (const base * const, const base &)} \ 264 - \ 265 - 266add {base::operator*=} \ 267 {base (base * const, const base &)} \ 268 - \ 269 - 270add {base::operator/} \ 271 {int (const base * const, const base &)} \ 272 - \ 273 - 274add {base::operator/=} \ 275 {base (base * const, const base &)} \ 276 - \ 277 - 278add {base::operator%} \ 279 {int (const base * const, const base &)} \ 280 - \ 281 - 282add {base::operator%=} \ 283 {base (base * const, const base &)} \ 284 - \ 285 - 286add {base::operator<} \ 287 {bool (const base * const, const base &)} \ 288 - \ 289 - 290add {base::operator<=} \ 291 {bool (const base * const, const base &)} \ 292 - \ 293 - 294add {base::operator>} \ 295 {bool (const base * const, const base &)} \ 296 - \ 297 - 298add {base::operator>=} \ 299 {bool (const base * const, const base &)} \ 300 - \ 301 - 302add {base::operator!=} \ 303 {bool (const base * const, const base &)} \ 304 - \ 305 - 306add {base::operator==} \ 307 {bool (const base * const, const base &)} \ 308 - \ 309 - 310add {base::operator!} \ 311 {bool (const base * const)} \ 312 - \ 313 - 314add {base::operator&&} \ 315 {bool (const base * const, const base &)} \ 316 - \ 317 - 318add {base::operator||} \ 319 {bool (const base * const, const base &)} \ 320 - \ 321 - 322add {base::operator<<} \ 323 {int (const base * const, int)} \ 324 - \ 325 - 326add {base::operator<<=} \ 327 {base (base * const, int)} \ 328 - \ 329 - 330add {base::operator>>} \ 331 {int (const base * const, int)} \ 332 - \ 333 - 334add {base::operator>>=} \ 335 {base (base * const, int)} \ 336 - \ 337 - 338add {base::operator~} \ 339 {int (const base * const)} \ 340 - \ 341 - 342add {base::operator&} \ 343 {int (const base * const, const base &)} \ 344 - \ 345 - 346add {base::operator&=} \ 347 {base (base * const, const base &)} \ 348 - \ 349 - 350add {base::operator|} \ 351 {int (const base * const, const base &)} \ 352 - \ 353 - 354add {base::operator|=} \ 355 {base (base * const, const base &)} \ 356 - \ 357 - 358add {base::operator^} \ 359 {int (const base * const, const base &)} \ 360 - \ 361 - 362add {base::operator^=} \ 363 {base (base * const, const base &)} \ 364 - \ 365 - 366add {base::operator=} \ 367 {base (base * const, const base &)} \ 368 - \ 369 - 370add {base::operator()} \ 371 {void (const base * const)} \ 372 - \ 373 - 374add {base::operator[]} \ 375 {int (const base * const, int)} \ 376 - \ 377 - 378add {base::operator new} \ 379 {void *(size_t)} \ 380 - \ 381 - 382add {base::operator delete} \ 383 {void (void *)} \ 384 - \ 385 - 386add {base::operator new[]} \ 387 {void *(size_t)} \ 388 - \ 389 - 390add {base::operator delete[]} \ 391 {void (void *)} \ 392 - \ 393 - 394add {base::operator char*} \ 395 {char *(const base * const)} \ 396 - \ 397 - 398add {base::operator fluff*} \ 399 {fluff *(const base * const)} \ 400 - \ 401 - 402add {base::operator fluff**} \ 403 {fluff **(const base * const)} \ 404 - \ 405 - 406add {base::operator int} \ 407 {int (const base * const)} \ 408 - \ 409 - 410add {base::operator fluff const* const*} \ 411 {const fluff * const *(const base * const)} \ 412 - \ 413 - 414 415# Templates 416add {tclass<char>::do_something} \ 417 {void (tclass<char> * const)} \ 418 - \ 419 - 420add {tclass<int>::do_something} \ 421 {void (tclass<int> * const)} \ 422 - \ 423 - 424add {tclass<long>::do_something} \ 425 {void (tclass<long> * const)} \ 426 - \ 427 - 428add {tclass<short>::do_something} \ 429 {void (tclass<short> * const)} \ 430 - \ 431 - 432add {tclass<base>::do_something} \ 433 {void (tclass<base> * const)} \ 434 - \ 435 - 436add {flubber<int, int, int, int, int>} \ 437 {void (void)} \ 438 - \ 439 flubber 440add {flubber<int, int, int, int, short>} \ 441 {void (void)} \ 442 - \ 443 flubber 444add {flubber<int, int, int, int, long>} \ 445 {void (void)} \ 446 - \ 447 flubber 448add {flubber<int, int, int, int, char>} \ 449 {void (void)} \ 450 - \ 451 flubber 452add {flubber<int, int, int, short, int>} \ 453 {void (void)} \ 454 - \ 455 flubber 456add {flubber<int, int, int, short, short>} \ 457 {void (void)} \ 458 - \ 459 flubber 460add {flubber<int, int, int, short, long>} \ 461 {void (void)} \ 462 - \ 463 flubber 464add {flubber<int, int, int, short, char>} \ 465 {void (void)} \ 466 - \ 467 flubber 468add {flubber<int, int, int, long, int>} \ 469 {void (void)} \ 470 - \ 471 flubber 472add {flubber<int, int, int, long, short>} \ 473 {void (void)} \ 474 - \ 475 flubber 476add {flubber<int, int, int, long, long>} \ 477 {void (void)} \ 478 - \ 479 flubber 480add {flubber<int, int, int, long, char>} \ 481 {void (void)} \ 482 - \ 483 flubber 484add {flubber<int, int, int, char, int>} \ 485 {void (void)} \ 486 - \ 487 flubber 488add {flubber<int, int, int, char, short>} \ 489 {void (void)} \ 490 - \ 491 flubber 492add {flubber<int, int, int, char, long>} \ 493 {void (void)} \ 494 - \ 495 flubber 496add {flubber<int, int, int, char, char>} \ 497 {void (void)} \ 498 - \ 499 flubber 500add {flubber<int, int, short, int, int>} \ 501 {void (void)} \ 502 - \ 503 flubber 504add {flubber<int, int, short, int, short>} \ 505 {void (void)} \ 506 - \ 507 flubber 508add {flubber<int, int, short, int, long>} \ 509 {void (void)} \ 510 - \ 511 flubber 512add {flubber<int, int, short, int, char>} \ 513 {void (void)} \ 514 - \ 515 flubber 516add {flubber<int, int, short, short, int>} \ 517 {void (void)} \ 518 - \ 519 flubber 520add {flubber<short, int, short, int, short>} \ 521 {void (void)} \ 522 - \ 523 flubber 524add {flubber<long, short, long, short, long>} \ 525 {void (void)} \ 526 - \ 527 flubber 528add {tclass<base>::do_something} \ 529 {void (tclass<base> * const)} \ 530 - \ 531 {tclass<T>::do_something} 532add {policy1::policy} \ 533 [ctor "policy<int, operation_1<void*> >" "int"] \ 534 {policy<int, operation_1<void*> >::policy} \ 535 {policy<T, Policy>::policy} 536add {policy2::policy} \ 537 [ctor "policy<int, operation_2<void*> >" int] \ 538 {policy<int, operation_2<void*> >::policy} \ 539 {policy<T, Policy>::policy} 540add {policy3::policy} \ 541 [ctor "policy<int, operation_3<void*> >" "int"] \ 542 {policy<int, operation_3<void*> >::policy} \ 543 {policy<T, Policy>::policy} 544add {policy4::policy} \ 545 [ctor "policy<int, operation_4<void*> >" "int"] \ 546 {policy<int, operation_4<void*> >::policy} \ 547 {policy<T, Policy>::policy} 548add {policy1::function} \ 549 {void (void)} \ 550 {operation_1<void*>::function} \ 551 {operation_1<T>::function} 552add {policy2::function} \ 553 {void (void)} \ 554 {operation_2<void*>::function} \ 555 {operation_2<T>::function} 556add {policy3::function} \ 557 {void (void)} \ 558 {operation_3<void*>::function} \ 559 {operation_3<T>::function} 560add {policy4::function} \ 561 {void (void)} \ 562 {operation_4<void*>::function} \ 563 {operation_4<T>::function} 564add {policyd<int, operation_1<int> >::policyd} \ 565 [ctor "policyd<int, operation_1<int> >" "int"] \ 566 - \ 567 {policyd<T, Policy>::policyd} 568add {policyd1::policyd} \ 569 [ctor "policyd<int, operation_1<int> >" "int"] \ 570 {policyd<int, operation_1<int> >::policyd} \ 571 {policyd<T, Policy>::policyd} 572add {policyd<int, operation_1<int> >::~policyd} \ 573 [dtor "policyd<int, operation_1<int> >"] \ 574 - \ 575 {policyd<T, Policy>::~policyd} 576add {policyd1::~policyd} \ 577 [dtor "policyd<int, operation_1<int> >"] \ 578 {policyd<int, operation_1<int> >::~policyd} \ 579 {policyd<T, Policy>::~policyd} 580add {policyd<long, operation_1<long> >::policyd} \ 581 [ctor "policyd<long, operation_1<long> >" "long"] \ 582 - \ 583 {policyd<T, Policy>::policyd} 584add {policyd2::policyd} \ 585 [ctor "policyd<long, operation_1<long> >" "long"] \ 586 {policyd<long, operation_1<long> >::policyd} \ 587 {policyd<T, Policy>::policyd} 588add {policyd<long, operation_1<long> >::~policyd} \ 589 [dtor "policyd<long, operation_1<long> >"] \ 590 - \ 591 {policyd<T, Policy>::~policyd} 592add {policyd2::~policyd} \ 593 [dtor "policyd<long, operation_1<long> >"] \ 594 {policyd<long, operation_1<long> >::~policyd} \ 595 {policyd<T, Policy>::~policyd} 596add {policyd<char, operation_1<char> >::policyd} \ 597 [ctor "policyd<char, operation_1<char> >" "char"] \ 598 - \ 599 {policyd<T, Policy>::policyd} 600add {policyd3::policyd} \ 601 [ctor "policyd<char, operation_1<char> >" "char"] \ 602 {policyd<char, operation_1<char> >::policyd} \ 603 {policyd<T, Policy>::policyd} 604add {policyd<char, operation_1<char> >::~policyd} \ 605 [dtor "policyd<char, operation_1<char> >"] \ 606 - \ 607 {policyd<T, Policy>::~policyd} 608add {policyd3::~policyd} \ 609 [dtor "policyd<char, operation_1<char> >"] \ 610 {policyd<char, operation_1<char> >::~policyd} \ 611 {policyd<T, Policy>::~policyd} 612add {policyd<base, operation_1<base> >::policyd} \ 613 [ctor "policyd<base, operation_1<base> >" "base"] \ 614 - \ 615 {policyd<T, Policy>::policyd} 616add {policyd4::policyd} \ 617 [ctor "policyd<base, operation_1<base> >" "base"] \ 618 {policyd<base, operation_1<base> >::policyd} \ 619 {policyd<T, Policy>::policyd} 620add {policyd<base, operation_1<base> >::~policyd} \ 621 [dtor "policyd<base, operation_1<base> >"] \ 622 - \ 623 {policyd<T, Policy>::~policyd} 624add {policyd4::~policyd} \ 625 [dtor "policyd<base, operation_1<base> >"] \ 626 {policyd<base, operation_1<base> >::~policyd} \ 627 {policyd<T, Policy>::~policyd} 628add {policyd<tclass<int>, operation_1<tclass<int> > >::policyd} \ 629 [ctor "policyd<tclass<int>, operation_1<tclass<int> > >" "tclass<int>"] \ 630 - \ 631 {policyd<T, Policy>::policyd} 632add {policyd5::policyd} \ 633 [ctor "policyd<tclass<int>, operation_1<tclass<int> > >" "tclass<int>"] \ 634 {policyd<tclass<int>, operation_1<tclass<int> > >::policyd} \ 635 {policyd<T, Policy>::policyd} 636add {policyd<tclass<int>, operation_1<tclass<int> > >::~policyd} \ 637 [dtor "policyd<tclass<int>, operation_1<tclass<int> > >"] \ 638 - \ 639 {policyd<T, Policy>::~policyd} 640add {policyd5::~policyd} \ 641 [dtor "policyd<tclass<int>, operation_1<tclass<int> > >"] \ 642 {policyd<tclass<int>, operation_1<tclass<int> > >::~policyd} \ 643 {policyd<T, Policy>::~policyd} 644add {policyd<int, operation_1<int> >::function} \ 645 {void (void)} \ 646 {operation_1<int>::function}\ 647 {operation_1<T>::function} 648add {policyd1::function} \ 649 {void (void)} \ 650 {operation_1<int>::function} \ 651 {operation_1<T>::function} 652add {policyd2::function} \ 653 {void (void)} \ 654 {operation_1<long>::function} \ 655 {operation_1<T>::function} 656add {policyd<char, operation_1<char> >::function} \ 657 {void (void)} \ 658 {operation_1<char>::function} \ 659 {operation_1<T>::function} 660add {policyd3::function} \ 661 {void (void)} \ 662 {operation_1<char>::function} \ 663 {operation_1<T>::function} 664add {policyd<base, operation_1<base> >::function} \ 665 {void (void)} \ 666 {operation_1<base>::function} \ 667 {operation_1<T>::function} 668add {policyd4::function} \ 669 {void (void)} \ 670 {operation_1<base>::function} \ 671 {operation_1<T>::function} 672add {policyd<tclass<int>, operation_1<tclass<int> > >::function} \ 673 {void (void)} \ 674 {operation_1<tclass<int> >::function} \ 675 {operation_1<T>::function} 676add {policyd5::function} \ 677 {void (void)} \ 678 {operation_1<tclass<int> >::function} \ 679 {operation_1<T>::function} 680 681# Start the test 682if {[skip_cplus_tests]} { continue } 683 684# 685# test running programs 686# 687 688standard_testfile cpexprs.cc 689 690if {[get_compiler_info "c++"]} { 691 return -1 692} 693 694# Include required flags. 695set flags "$flags debug c++" 696 697if {[prepare_for_testing "failed to prepare" $testfile $srcfile "$flags"]} { 698 return -1 699} 700 701if {![runto_main]} { 702 perror "couldn't run to breakpoint" 703 continue 704} 705 706# Set the listsize to one. This will help with testing "list". 707gdb_test "set listsize 1" 708 709# "print METHOD" 710foreach name [get_functions print] { 711 gdb_test "print $name" [get $name print] 712} 713 714# "list METHOD" 715foreach name [get_functions list] { 716 gdb_test "list $name" [get $name list] 717} 718 719# Running to breakpoint -- use any function we can "list" 720foreach name [get_functions list] { 721 # Skip "test_function", since test_breakpoint uses it 722 if {[string compare $name "test_function"] != 0} { 723 test_breakpoint $name 724 } 725} 726 727# Test c/v gets recognized even without quoting. 728foreach cv {{} { const} { volatile} { const volatile}} { 729 set test "p 'CV::m(int)$cv'" 730 gdb_test_multiple $test $test { 731 -re "( = {.*} 0x\[0-9a-f\]+ <CV::m.*>)\r\n$gdb_prompt $" { 732 # = {void (CV * const, CV::t)} 0x400944 <CV::m(int)> 733 set correct $expect_out(1,string) 734 pass $test 735 } 736 } 737 gdb_test "p CV::m(int)$cv" [string_to_regexp $correct] 738} 739 740# Test TYPENAME:: gets recognized even in parentheses. 741gdb_test "p CV_f(int)" { = {int \(int\)} 0x[0-9a-f]+ <CV_f\(int\)>} 742gdb_test "p CV_f(CV::t)" { = {int \(int\)} 0x[0-9a-f]+ <CV_f\(int\)>} 743gdb_test "p CV_f(CV::i)" " = 43" 744 745gdb_test "p CV_f('cpexprs.cc'::CV::t)" \ 746 { = {int \(int\)} 0x[0-9a-f]+ <CV_f\(int\)>} 747 748# Make sure conversion operator names are canonicalized and properly 749# "spelled." 750gdb_test "p base::operator const fluff * const *" \ 751 [get "base::operator fluff const* const*" print] \ 752 "canonicalized conversion operator name 1" 753gdb_test "p base::operator const fluff* const*" \ 754 [get "base::operator fluff const* const*" print] \ 755 "canonicalized conversion operator name 2" 756gdb_test "p base::operator derived*" \ 757 "There is no field named operator derived\\*" \ 758 "undefined conversion operator" 759 760gdb_exit 761return 0 762