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