Home | History | Annotate | Line # | Download | only in gdb.base
      1 # Copyright 2020-2024 Free Software Foundation, Inc.
      2 
      3 # This program is free software; you can redistribute it and/or modify
      4 # it under the terms of the GNU General Public License as published by
      5 # the Free Software Foundation; either version 3 of the License, or
      6 # (at your option) any later version.
      7 #
      8 # This program is distributed in the hope that it will be useful,
      9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
     10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     11 # GNU General Public License for more details.
     12 #
     13 # You should have received a copy of the GNU General Public License
     14 # along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     15 
     16 # Test 'advance/until LINESPEC' where LINESPEC expands to multiple
     17 # locations.
     18 
     19 standard_testfile .cc
     20 
     21 require allow_cplus_tests
     22 
     23 if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile} \
     24 	  {debug c++}] } {
     25     return -1
     26 }
     27 
     28 set lineno [gdb_get_line_number "multiple locations here"]
     29 
     30 # advance/until to an inlined line number, which has been inlined
     31 # multiple times, when the program is stopped at the same inlined
     32 # function.
     33 proc_with_prefix until_advance_lineno_from_inlined {cmd} {
     34     global lineno
     35 
     36     if ![runto test] {
     37 	return
     38     }
     39 
     40     gdb_breakpoint $lineno
     41     gdb_continue_to_breakpoint "break here"
     42 
     43     set lineno2 [expr $lineno + 1]
     44 
     45     gdb_test "$cmd $lineno2" \
     46 	"inline_func .* at .*:$lineno2.*return i.*" \
     47 	"$cmd line number"
     48 }
     49 
     50 # advance/until to a line number, which has been inlined multiple
     51 # times, when the program is stopped at a non-inlined function.
     52 
     53 proc_with_prefix until_advance_lineno_from_non_inlined {cmd} {
     54     global lineno
     55 
     56     if ![runto test] {
     57 	return
     58     }
     59 
     60     gdb_test "$cmd $lineno" \
     61 	"inline_func .* at .*:$lineno.*multiple locations here.*" \
     62 	"$cmd line number"
     63 }
     64 
     65 # Test advancing to an inlined function, which has been inlined
     66 # multiple times.
     67 
     68 proc_with_prefix until_advance_inline_func {cmd} {
     69     global lineno
     70 
     71     if ![runto test] {
     72 	return
     73     }
     74 
     75     gdb_test "$cmd inline_func" \
     76 	"inline_func .* at .*:$lineno.*multiple locations here.*"
     77 }
     78 
     79 # Test advancing to an overloaded function, which is another form of a
     80 # linespec expanding to multiple locations.  GDB will stop at the
     81 # first overload called.
     82 
     83 proc_with_prefix advance_overload {} {
     84     global lineno
     85 
     86     if ![runto test] {
     87 	return
     88     }
     89 
     90     # Test that advance stops at the first overload called by the
     91     # program.
     92 
     93     gdb_test "advance ovld_func" \
     94 	"ovld_func .* at .*global = 1.*" \
     95 	"first advance stops at ovld_func()"
     96 
     97     # Now test that advance also stops at the other overload called by
     98     # the program.
     99 
    100     # Need to issue the advance twice, because advance also stops upon
    101     # exit from the current stack frame.
    102     gdb_test "advance ovld_func" \
    103 	"test \\(\\) at .*" \
    104 	"second advance stops at caller"
    105 
    106     gdb_test "advance ovld_func" \
    107 	"ovld_func .* at .*global = 2.*" \
    108 	"third advance stops at ovld_func(int)"
    109 }
    110 
    111 # Test "until" to an overloaded function, which is another form of a
    112 # linespec expanding to multiple locations.  Unlike "advance", "until"
    113 # only stops if still in the same frame.  Since the overloaded
    114 # function is a different frame, the program should stop at the caller
    115 # frame instead.
    116 
    117 proc_with_prefix until_overload {} {
    118     global lineno
    119 
    120     if ![runto test] {
    121 	return
    122     }
    123 
    124     # ovld_func is a different frame, so it shouldn't cause a stop.
    125     # Instead, the program should stop at the caller frame.
    126     gdb_test "until ovld_func" \
    127 	"main \\(\\) at .*"
    128 }
    129 
    130 foreach_with_prefix cmd {"until" "advance"} {
    131     until_advance_lineno_from_inlined $cmd
    132     until_advance_lineno_from_non_inlined $cmd
    133     until_advance_inline_func $cmd
    134 }
    135 
    136 advance_overload
    137 until_overload
    138