Home | History | Annotate | Line # | Download | only in gdb.cp
      1 # Copyright 2019-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 standard_testfile .cc
     17 
     18 if {[test_compiler_info gcc*] && ![supports_statement_frontiers] } {
     19     return -1
     20 }
     21 
     22 # Compile the test source with USE_NEXT_INLINE_H defined (when
     23 # use_header is true), or not defined.
     24 proc do_test { use_header } {
     25     global srcfile testfile
     26 
     27     if { $use_header } {
     28 	# This test will not pass due to poor debug information
     29 	# generated by GCC (at least up to 10.x).  See
     30 	# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94474
     31 	return
     32     }
     33 
     34     set options {c++ debug nowarnings optimize=-O2}
     35     if { [supports_statement_frontiers] } {
     36 	lappend options additional_flags=-gstatement-frontiers
     37     }
     38     if { $use_header } {
     39 	lappend options additional_flags=-DUSE_NEXT_INLINE_H
     40 	set executable "$testfile-with-header"
     41 	set hdrfile "step-and-next-inline.h"
     42 	set prefix "use_header"
     43     } else {
     44 	set executable "$testfile-no-header"
     45 	set hdrfile "$srcfile"
     46 	set prefix "no_header"
     47     }
     48 
     49     if { [prepare_for_testing "failed to prepare" $executable \
     50 	      $srcfile $options] } {
     51 	return -1
     52     }
     53 
     54     with_test_prefix $prefix {
     55 
     56     set main_location [gdb_get_line_number "Beginning of main" $srcfile]
     57 
     58     if {![runto_main]} {
     59 	return
     60     }
     61 
     62     gdb_breakpoint tree_check
     63 
     64     # Check that GDB can correctly stop in `tree_check`.  On some
     65     # targets. gcc will use DW_AT_ranges to represent the addresses of
     66     # tree_check, and in some cases, will create an empty sub-range
     67     # for some of the tree_check code.  To really confuse things, gcc
     68     # will then set the DW_AT_entry_pc to point at the address of the
     69     # empty sub-range.
     70     #
     71     # The result of this is that GDB would stop at the DW_AT_entry_pc,
     72     # but then GDB would fail to realise that this address was inside
     73     # tree_check.
     74     for { set i 1 } { $i < 4 } { incr i } {
     75 	gdb_test "continue" \
     76 	    [multi_line \
     77 		 "Breakpoint $::decimal\\.$i, (?:$::hex in )?tree_check \\(\[^\r\n\]+\\) at \[^\r\n\]+/$hdrfile:$::decimal" \
     78 		 "$::decimal\\s+\[^\r\n\]+"] \
     79 	    "stop at tree_check, $i"
     80     }
     81 
     82     clean_restart $executable
     83 
     84     if ![runto $main_location qualified] {
     85 	return
     86     }
     87 
     88     gdb_test "bt" "\\s*\\#0\\s+main.*" "in main"
     89     set line1 {\t\{}
     90     set line2 {\t  if \(t != NULL}
     91     gdb_test_multiple "step" "step into get_alias_set" {
     92 	-re -wrap $line1 {
     93 	    gdb_test "next" $line2 $gdb_test_name
     94 	}
     95 	-re -wrap $line2 {
     96 	    pass $gdb_test_name
     97 	}
     98     }
     99     gdb_test "bt" "\\s*\\#0\\s+get_alias_set\[^\r\]*${srcfile}:.*" \
    100 	"not in inline 1"
    101 
    102     # It's possible that this first failure (when not using a header
    103     # file) is GCC's fault, though the remaining failures would best
    104     # be fixed by adding location views support (though it could be
    105     # that some easier heuristic could be figured out).  Still, it is
    106     # not certain that the first failure wouldn't also be fixed by
    107     # having location view support, so for now it is tagged as such.
    108     set have_kfail [expr [test_compiler_info gcc*] && !$use_header]
    109 
    110     set ok 1
    111     gdb_test_multiple "next" "next step 1" {
    112 	-re -wrap "if \\(t->x != i\\)" {
    113 	    set ok 0
    114 	    send_gdb "next\n"
    115 	    exp_continue
    116 	}
    117 	-re -wrap ".*TREE_TYPE.* != 1" {
    118 	    if { $ok } {
    119 		pass $gdb_test_name
    120 	    } else {
    121 		if { $have_kfail } {
    122 		    setup_kfail "*-*-*" symtab/25507
    123 		}
    124 		fail $gdb_test_name
    125 	    }
    126 	}
    127     }
    128     gdb_test "bt" "\\s*\\#0\\s+get_alias_set\[^\r\]*${srcfile}:.*" \
    129 	"not in inline 2"
    130 
    131     set ok 1
    132     gdb_test_multiple "next" "next step 2" {
    133 	-re -wrap "return x;" {
    134 	    set ok 0
    135 	    send_gdb "next\n"
    136 	    exp_continue
    137 	}
    138 	-re -wrap ".*TREE_TYPE.* != 2" {
    139 	    if { $ok } {
    140 		pass $gdb_test_name
    141 	    } else {
    142 		if { $have_kfail } {
    143 		    setup_kfail "*-*-*" symtab/25507
    144 		}
    145 		fail $gdb_test_name
    146 	    }
    147 	}
    148     }
    149     gdb_test "bt" "\\s*\\#0\\s+get_alias_set\[^\r\]*${srcfile}:.*" \
    150 	"not in inline 3"
    151 
    152     set ok 1
    153     gdb_test_multiple "next" "next step 3" {
    154 	-re -wrap "return x;" {
    155 	    set ok 0
    156 	    send_gdb "next\n"
    157 	    exp_continue
    158 	}
    159 	-re -wrap ".*TREE_TYPE.* != 3\\)" {
    160 	    if { $ok } {
    161 		pass $gdb_test_name
    162 	    } else {
    163 		if { $have_kfail } {
    164 		    setup_kfail "*-*-*" symtab/25507
    165 		}
    166 		fail $gdb_test_name
    167 	    }
    168 	}
    169     }
    170     gdb_test "bt" "\\s*\\#0\\s+get_alias_set\[^\r\]*${srcfile}:.*" \
    171 	"not in inline 4"
    172 
    173     set ok 1
    174     gdb_test_multiple "next" "next step 4" {
    175 	-re -wrap "(if \\(t != NULL|\} // get_alias_set)" {
    176 	    send_gdb "next\n"
    177 	    exp_continue
    178 	}
    179 	-re -wrap "return x;" {
    180 	    set ok 0
    181 	    send_gdb "next\n"
    182 	    exp_continue
    183 	}
    184 	-re -wrap "return 0.*" {
    185 	    if { $ok } {
    186 		pass $gdb_test_name
    187 	    } else {
    188 		if { $have_kfail } {
    189 		    setup_kfail "*-*-*" symtab/25507
    190 		}
    191 		fail $gdb_test_name
    192 	    }
    193 	}
    194     }
    195     gdb_test "bt" \
    196 	"\\s*\\#0\\s+(main|get_alias_set)\[^\r\]*${srcfile}:.*" \
    197 	"not in inline 5"
    198 
    199     if {!$use_header} {
    200 	# With the debug from GCC 10.x (and earlier) GDB is currently
    201 	# unable to successfully complete the following tests when we
    202 	# are not using a header file.
    203 	kfail symtab/25507 "stepping tests"
    204 	return
    205     }
    206 
    207     clean_restart ${executable}
    208 
    209     if ![runto_main] {
    210 	return
    211     }
    212 
    213     gdb_test "bt" "\\s*\\#0\\s+main.*" "in main pass 2"
    214     gdb_test "step" ".*" "step into get_alias_set pass 2"
    215     gdb_test "bt" "\\s*\\#0\\s+get_alias_set\[^\r\]*${srcfile}:.*" \
    216 	"in get_alias_set pass 2"
    217     gdb_test "step" ".*TREE_TYPE.*" "step 1"
    218     gdb_test "bt" "\\s*\\#0\\s+get_alias_set\[^\r\]*${srcfile}:.*" \
    219 	"not in inline 1 pass 2"
    220     gdb_test "step" ".*if \\(t->x != i\\).*" "step 2"
    221     gdb_test "bt" "\\s*\\#0\\s+\[^\r\]*tree_check\[^\r\]*${hdrfile}:.*" \
    222 	"in inline 1 pass 2"
    223     gdb_test "step" ".*TREE_TYPE.*" "step 3"
    224     gdb_test "bt" "\\s*\\#0\\s+get_alias_set\[^\r\]*${srcfile}:.*" \
    225 	"not in inline 2 pass 2"
    226     gdb_test "step" ".*if \\(t->x != i\\).*" "step 4"
    227     gdb_test "bt" "\\s*\\#0\\s+\[^\r\]*tree_check\[^\r\]*${hdrfile}:.*" \
    228 	"in inline 2 pass 2"
    229     gdb_test "step" ".*TREE_TYPE.*" "step 5"
    230     gdb_test "bt" "\\s*\\#0\\s+get_alias_set\[^\r\]*${srcfile}:.*" \
    231 	"not in inline 3 pass 2"
    232     gdb_test "step" ".*if \\(t->x != i\\).*" "step 6"
    233     gdb_test "bt" "\\s*\\#0\\s+\[^\r\]*tree_check\[^\r\]*${hdrfile}:.*" \
    234 	"in inline 3 pass 2"
    235     gdb_test "step" "return 0.*" "step 7"
    236     gdb_test "bt" \
    237 	"\\s*\\#0\\s+(main|get_alias_set)\[^\r\]*${srcfile}:.*" \
    238 	"not in inline 4 pass 2"
    239     }
    240 }
    241 
    242 do_test 0
    243 do_test 1
    244