1 # cpexprs.exp - C++ expressions tests
3 # Copyright 2008-2022 Free Software Foundation, Inc.
5 # Contributed by Red Hat, originally written by Keith Seitz.
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.
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.
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/>.
20 # This file is part of the gdb testsuite.
22 # A helper proc which sets a breakpoint at FUNC and attempts to
23 # run to the breakpoint.
24 proc test_breakpoint
{func
} {
27 # Return to the top of the test function every time.
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 } {
35 gdb_breakpoint
"$func"
36 set i
[expr {[string last
: $func] + 1}]
37 set efunc
[string_to_regexp
[string range
$func $i end
]]
39 "Continuing.\r\n\r\nBreakpoint $DEC+,.*$efunc.*" \
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
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
54 # add NAME TYPE PRINT LST
55 # add NAME TYPE PRINT -
56 proc add_type_regexp
{func type print lst
} {
57 global all_functions CONVAR ADDR
59 set all_functions
($func,type
) $type
64 # An exception: since gdb canonicalizes C++ output,
65 # "(void)" must be mutated to "()".
66 regsub {\(void
\)} $print {()} print
68 set all_functions
($func,print
) \
69 "$CONVAR = {$type} $ADDR <[string_to_regexp $print].*>"
73 set all_functions
($func,list) ".*// [string_to_regexp $lst]"
76 proc add
{func type print lst
} {
77 add_type_regexp
$func [string_to_regexp
$type] $print $lst
82 return $all_functions($func,$cmd)
85 # Returns a list of function names for a given command
86 proc get_functions
{cmd
} {
89 foreach i
[array names all_functions
*,$cmd] {
90 if {$all_functions($i) != ""} {
91 set idx
[string last
, $i]
93 lappend result
[string range
$i 0 [expr {$idx - 1}]]
98 return [lsort $result]
101 # Some convenience variables for this test
102 set DEC
{[0-9]}; # a decimal number
103 set HEX
{[0-9a-fA-F
]}; # a hexidecimal number
104 set CONVAR
"\\\$$DEC+"; # convenience variable regexp
105 set ADDR
"0x$HEX+"; # address
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.
113 # The array holding all functions/methods to test. Valid subindexes
114 # are (none need character escaping -- "add" will take care of that):
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 "//")
121 array set all_functions
{}
123 # "Normal" functions/methods
124 add
{test_function
} \
125 {int
(int
, char
**)} \
128 add
{derived
::a_function} \
129 {void
(const derived
* const
)} \
132 add
{base1
::a_function} \
133 {void
(const base1
* const
)} \
136 add
{base2
::a_function} \
137 {void
(const base2
* const
)} \
143 # On targets using the ARM EABI, the constructor is expected to return
145 proc ctor_ret
{ type
} {
146 if { [istarget arm
*-*eabi
*] ||
[is_aarch32_target
] } {
153 proc ctor_prefix
{ type
} {
154 set ret
[ctor_ret
$type]
155 return "${ret}($type * const"
158 proc ctor
{ type arglist
} {
159 if { $arglist != "" } {
160 set arglist
", $arglist"
162 return "[ctor_prefix $type]$arglist)"
165 add
{derived
::derived} \
169 add_type_regexp
{base1
::base1(void
)} \
170 "[string_to_regexp [ctor_prefix base1]], (const )?void \\*\\*( const)?\\)" \
173 add
{base1
::base1(int
)} \
177 add_type_regexp
{base2
::base2} \
178 "[string_to_regexp [ctor_prefix base2]], (const )?void \\*\\*( const)?\\)" \
181 add
{base
::base(void
)} \
185 add
{base
::base(int
)} \
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
197 if { [istarget arm
*-*eabi
*] ||
[is_aarch32_target
] } {
202 return "${ret}($type * const)"
210 # Overloaded methods (all are const)
211 add
{base
::overload(void
) const
} \
212 {int
(const base
* const
)} \
214 {base
::overload(void
) const
}
215 add
{base
::overload(int
) const
} \
216 {int
(const base
* const
, int
)} \
219 add
{base
::overload(short
) const
} \
220 {int
(const base
* const
, short
)} \
223 add
{base
::overload(long
) const
} \
224 {int
(const base
* const
, long
)} \
227 add
{base
::overload(char
*) const
} \
228 {int
(const base
* const
, char
*)} \
231 add
{base
::overload(base
&) const
} \
232 {int
(const base
* const
, base
&)} \
237 add
{base
::operator+} \
238 {int
(const base
* const
, const base
&)} \
241 add
{base
::operator++} \
242 {base
(base
* const
)} \
245 add
{base
::operator+=} \
246 {base
(base
* const
, const base
&)} \
249 add
{base
::operator-} \
250 {int
(const base
* const
, const base
&)} \
253 add
{base
::operator--} \
254 {base
(base
* const
)} \
257 add
{base
::operator-=} \
258 {base
(base
* const
, const base
&)} \
261 add
{base
::operator*} \
262 {int
(const base
* const
, const base
&)} \
265 add
{base
::operator*=} \
266 {base
(base
* const
, const base
&)} \
269 add
{base
::operator/} \
270 {int
(const base
* const
, const base
&)} \
273 add
{base
::operator/=} \
274 {base
(base
* const
, const base
&)} \
277 add
{base
::operator%} \
278 {int
(const base
* const
, const base
&)} \
281 add
{base
::operator%=} \
282 {base
(base
* const
, const base
&)} \
285 add
{base
::operator<} \
286 {bool
(const base
* const
, const base
&)} \
289 add
{base
::operator<=} \
290 {bool
(const base
* const
, const base
&)} \
293 add
{base
::operator>} \
294 {bool
(const base
* const
, const base
&)} \
297 add
{base
::operator>=} \
298 {bool
(const base
* const
, const base
&)} \
301 add
{base
::operator!=} \
302 {bool
(const base
* const
, const base
&)} \
305 add
{base
::operator==} \
306 {bool
(const base
* const
, const base
&)} \
309 add
{base
::operator!} \
310 {bool
(const base
* const
)} \
313 add
{base
::operator&&} \
314 {bool
(const base
* const
, const base
&)} \
317 add
{base
::operator||
} \
318 {bool
(const base
* const
, const base
&)} \
321 add
{base
::operator<<} \
322 {int
(const base
* const
, int
)} \
325 add
{base
::operator<<=} \
326 {base
(base
* const
, int
)} \
329 add
{base
::operator>>} \
330 {int
(const base
* const
, int
)} \
333 add
{base
::operator>>=} \
334 {base
(base
* const
, int
)} \
337 add
{base
::operator~
} \
338 {int
(const base
* const
)} \
341 add
{base
::operator&} \
342 {int
(const base
* const
, const base
&)} \
345 add
{base
::operator&=} \
346 {base
(base
* const
, const base
&)} \
349 add
{base
::operator|
} \
350 {int
(const base
* const
, const base
&)} \
353 add
{base
::operator|
=} \
354 {base
(base
* const
, const base
&)} \
357 add
{base
::operator^
} \
358 {int
(const base
* const
, const base
&)} \
361 add
{base
::operator^
=} \
362 {base
(base
* const
, const base
&)} \
365 add
{base
::operator=} \
366 {base
(base
* const
, const base
&)} \
369 add
{base
::operator()} \
370 {void
(const base
* const
)} \
373 add
{base
::operator[]} \
374 {int
(const base
* const
, int
)} \
377 add
{base
::operator new
} \
381 add
{base
::operator delete
} \
385 add
{base
::operator new
[]} \
389 add
{base
::operator delete
[]} \
393 add
{base
::operator char
*} \
394 {char
*(const base
* const
)} \
397 add
{base
::operator fluff
*} \
398 {fluff
*(const base
* const
)} \
401 add
{base
::operator fluff
**} \
402 {fluff
**(const base
* const
)} \
405 add
{base
::operator int
} \
406 {int
(const base
* const
)} \
409 add
{base
::operator fluff const
* const
*} \
410 {const fluff
* const
*(const base
* const
)} \
415 add
{tclass
<char
>::do_something} \
416 {void
(tclass
<char
> * const
)} \
419 add
{tclass
<int
>::do_something} \
420 {void
(tclass
<int
> * const
)} \
423 add
{tclass
<long
>::do_something} \
424 {void
(tclass
<long
> * const
)} \
427 add
{tclass
<short
>::do_something} \
428 {void
(tclass
<short
> * const
)} \
431 add
{tclass
<base
>::do_something} \
432 {void
(tclass
<base
> * const
)} \
435 add
{flubber
<int
, int
, int
, int
, int
>} \
439 add
{flubber
<int
, int
, int
, int
, short
>} \
443 add
{flubber
<int
, int
, int
, int
, long
>} \
447 add
{flubber
<int
, int
, int
, int
, char
>} \
451 add
{flubber
<int
, int
, int
, short
, int
>} \
455 add
{flubber
<int
, int
, int
, short
, short
>} \
459 add
{flubber
<int
, int
, int
, short
, long
>} \
463 add
{flubber
<int
, int
, int
, short
, char
>} \
467 add
{flubber
<int
, int
, int
, long
, int
>} \
471 add
{flubber
<int
, int
, int
, long
, short
>} \
475 add
{flubber
<int
, int
, int
, long
, long
>} \
479 add
{flubber
<int
, int
, int
, long
, char
>} \
483 add
{flubber
<int
, int
, int
, char
, int
>} \
487 add
{flubber
<int
, int
, int
, char
, short
>} \
491 add
{flubber
<int
, int
, int
, char
, long
>} \
495 add
{flubber
<int
, int
, int
, char
, char
>} \
499 add
{flubber
<int
, int
, short
, int
, int
>} \
503 add
{flubber
<int
, int
, short
, int
, short
>} \
507 add
{flubber
<int
, int
, short
, int
, long
>} \
511 add
{flubber
<int
, int
, short
, int
, char
>} \
515 add
{flubber
<int
, int
, short
, short
, int
>} \
519 add
{flubber
<short
, int
, short
, int
, short
>} \
523 add
{flubber
<long
, short
, long
, short
, long
>} \
527 add
{tclass
<base
>::do_something} \
528 {void
(tclass
<base
> * const
)} \
530 {tclass
<T
>::do_something}
531 add
{policy1
::policy} \
532 [ctor
"policy<int, operation_1<void*> >" "int"] \
533 {policy
<int
, operation_1
<void
*> >::policy} \
534 {policy
<T
, Policy
>::policy}
535 add
{policy2
::policy} \
536 [ctor
"policy<int, operation_2<void*> >" int
] \
537 {policy
<int
, operation_2
<void
*> >::policy} \
538 {policy
<T
, Policy
>::policy}
539 add
{policy3
::policy} \
540 [ctor
"policy<int, operation_3<void*> >" "int"] \
541 {policy
<int
, operation_3
<void
*> >::policy} \
542 {policy
<T
, Policy
>::policy}
543 add
{policy4
::policy} \
544 [ctor
"policy<int, operation_4<void*> >" "int"] \
545 {policy
<int
, operation_4
<void
*> >::policy} \
546 {policy
<T
, Policy
>::policy}
547 add
{policy1
::function} \
549 {operation_1
<void
*>::function} \
550 {operation_1
<T
>::function}
551 add
{policy2
::function} \
553 {operation_2
<void
*>::function} \
554 {operation_2
<T
>::function}
555 add
{policy3
::function} \
557 {operation_3
<void
*>::function} \
558 {operation_3
<T
>::function}
559 add
{policy4
::function} \
561 {operation_4
<void
*>::function} \
562 {operation_4
<T
>::function}
563 add
{policyd
<int
, operation_1
<int
> >::policyd} \
564 [ctor
"policyd<int, operation_1<int> >" "int"] \
566 {policyd
<T
, Policy
>::policyd}
567 add
{policyd1
::policyd} \
568 [ctor
"policyd<int, operation_1<int> >" "int"] \
569 {policyd
<int
, operation_1
<int
> >::policyd} \
570 {policyd
<T
, Policy
>::policyd}
571 add
{policyd
<int
, operation_1
<int
> >::~policyd
} \
572 [dtor
"policyd<int, operation_1<int> >"] \
574 {policyd
<T
, Policy
>::~policyd
}
575 add
{policyd1
::~policyd
} \
576 [dtor
"policyd<int, operation_1<int> >"] \
577 {policyd
<int
, operation_1
<int
> >::~policyd
} \
578 {policyd
<T
, Policy
>::~policyd
}
579 add
{policyd
<long
, operation_1
<long
> >::policyd} \
580 [ctor
"policyd<long, operation_1<long> >" "long"] \
582 {policyd
<T
, Policy
>::policyd}
583 add
{policyd2
::policyd} \
584 [ctor
"policyd<long, operation_1<long> >" "long"] \
585 {policyd
<long
, operation_1
<long
> >::policyd} \
586 {policyd
<T
, Policy
>::policyd}
587 add
{policyd
<long
, operation_1
<long
> >::~policyd
} \
588 [dtor
"policyd<long, operation_1<long> >"] \
590 {policyd
<T
, Policy
>::~policyd
}
591 add
{policyd2
::~policyd
} \
592 [dtor
"policyd<long, operation_1<long> >"] \
593 {policyd
<long
, operation_1
<long
> >::~policyd
} \
594 {policyd
<T
, Policy
>::~policyd
}
595 add
{policyd
<char
, operation_1
<char
> >::policyd} \
596 [ctor
"policyd<char, operation_1<char> >" "char"] \
598 {policyd
<T
, Policy
>::policyd}
599 add
{policyd3
::policyd} \
600 [ctor
"policyd<char, operation_1<char> >" "char"] \
601 {policyd
<char
, operation_1
<char
> >::policyd} \
602 {policyd
<T
, Policy
>::policyd}
603 add
{policyd
<char
, operation_1
<char
> >::~policyd
} \
604 [dtor
"policyd<char, operation_1<char> >"] \
606 {policyd
<T
, Policy
>::~policyd
}
607 add
{policyd3
::~policyd
} \
608 [dtor
"policyd<char, operation_1<char> >"] \
609 {policyd
<char
, operation_1
<char
> >::~policyd
} \
610 {policyd
<T
, Policy
>::~policyd
}
611 add
{policyd
<base
, operation_1
<base
> >::policyd} \
612 [ctor
"policyd<base, operation_1<base> >" "base"] \
614 {policyd
<T
, Policy
>::policyd}
615 add
{policyd4
::policyd} \
616 [ctor
"policyd<base, operation_1<base> >" "base"] \
617 {policyd
<base
, operation_1
<base
> >::policyd} \
618 {policyd
<T
, Policy
>::policyd}
619 add
{policyd
<base
, operation_1
<base
> >::~policyd
} \
620 [dtor
"policyd<base, operation_1<base> >"] \
622 {policyd
<T
, Policy
>::~policyd
}
623 add
{policyd4
::~policyd
} \
624 [dtor
"policyd<base, operation_1<base> >"] \
625 {policyd
<base
, operation_1
<base
> >::~policyd
} \
626 {policyd
<T
, Policy
>::~policyd
}
627 add
{policyd
<tclass
<int
>, operation_1
<tclass
<int
> > >::policyd} \
628 [ctor
"policyd<tclass<int>, operation_1<tclass<int> > >" "tclass<int>"] \
630 {policyd
<T
, Policy
>::policyd}
631 add
{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}
635 add
{policyd
<tclass
<int
>, operation_1
<tclass
<int
> > >::~policyd
} \
636 [dtor
"policyd<tclass<int>, operation_1<tclass<int> > >"] \
638 {policyd
<T
, Policy
>::~policyd
}
639 add
{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
}
643 add
{policyd
<int
, operation_1
<int
> >::function} \
645 {operation_1
<int
>::function}\
646 {operation_1
<T
>::function}
647 add
{policyd1
::function} \
649 {operation_1
<int
>::function} \
650 {operation_1
<T
>::function}
651 add
{policyd2
::function} \
653 {operation_1
<long
>::function} \
654 {operation_1
<T
>::function}
655 add
{policyd
<char
, operation_1
<char
> >::function} \
657 {operation_1
<char
>::function} \
658 {operation_1
<T
>::function}
659 add
{policyd3
::function} \
661 {operation_1
<char
>::function} \
662 {operation_1
<T
>::function}
663 add
{policyd
<base
, operation_1
<base
> >::function} \
665 {operation_1
<base
>::function} \
666 {operation_1
<T
>::function}
667 add
{policyd4
::function} \
669 {operation_1
<base
>::function} \
670 {operation_1
<T
>::function}
671 add
{policyd
<tclass
<int
>, operation_1
<tclass
<int
> > >::function} \
673 {operation_1
<tclass
<int
> >::function} \
674 {operation_1
<T
>::function}
675 add
{policyd5
::function} \
677 {operation_1
<tclass
<int
> >::function} \
678 {operation_1
<T
>::function}
681 if {[skip_cplus_tests
]} { continue }
684 # test running programs
687 standard_testfile cpexprs.cc
689 if {[get_compiler_info
"c++"]} {
693 # Include required flags.
694 set flags
"$flags debug c++"
696 if {[prepare_for_testing
"failed to prepare" $testfile $srcfile "$flags"]} {
701 perror
"couldn't run to breakpoint"
705 # Set the listsize to one. This will help with testing "list".
706 gdb_test
"set listsize 1"
709 foreach name
[get_functions print
] {
710 gdb_test
"print $name" [get
$name print
]
714 foreach name
[get_functions
list] {
715 gdb_test
"list $name" [get
$name list]
718 # Running to breakpoint -- use any function we can "list"
719 foreach name
[get_functions
list] {
720 # Skip "test_function", since test_breakpoint uses it
721 if {[string compare
$name "test_function"] != 0} {
722 test_breakpoint
$name
726 # Test c/v gets recognized even without quoting.
727 foreach cv
{{} { const
} { volatile
} { const volatile
}} {
728 set test
"p 'CV::m(int)$cv'"
729 gdb_test_multiple
$test $test {
730 -re "( = {.*} 0x\[0-9a-f\]+ <CV::m.*>)\r\n$gdb_prompt $" {
731 # = {void (CV * const, CV::t)} 0x400944 <CV::m(int)>
732 set correct
$expect_out(1,string)
736 gdb_test
"p CV::m(int)$cv" [string_to_regexp
$correct]
739 # Test TYPENAME:: gets recognized even in parentheses.
740 gdb_test
"p CV_f(int)" { = {int
\(int
\)} 0x
[0-9a-f
]+ <CV_f
\(int
\)>}
741 gdb_test
"p CV_f(CV::t)" { = {int
\(int
\)} 0x
[0-9a-f
]+ <CV_f
\(int
\)>}
742 gdb_test
"p CV_f(CV::i)" " = 43"
744 gdb_test
"p CV_f('cpexprs.cc'::CV::t)" \
745 { = {int
\(int
\)} 0x
[0-9a-f
]+ <CV_f
\(int
\)>}
747 # Make sure conversion operator names are canonicalized and properly
749 gdb_test
"p base::operator const fluff * const *" \
750 [get
"base::operator fluff const* const*" print
] \
751 "canonicalized conversion operator name 1"
752 gdb_test
"p base::operator const fluff* const*" \
753 [get
"base::operator fluff const* const*" print
] \
754 "canonicalized conversion operator name 2"
755 gdb_test
"p base::operator derived*" \
756 "There is no field named operator derived\\*" \
757 "undefined conversion operator"