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