https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101011
Bug ID: 101011 Summary: Inconsistent debug info for "while (1);" Product: gcc Version: 11.1.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: debug Assignee: unassigned at gcc dot gnu.org Reporter: vries at gcc dot gnu.org Target Milestone: --- I. Consider test-cases: ... $ cat -n test.c 1 int 2 main (void) 3 { 4 while (1); 5 6 return 0; 7 } $ cat -n test2.c 1 int 2 main (void) 3 { 4 int spin = 1; 5 while (spin); 6 7 return 0; 8 } ... Compiled with gcc-10: ... $ gcc-10 test.c -g -o 1 $ gcc-10 test2.c -g -o 2 ... we get the same behaviour when setting the breakpoint on the loop line 4/5. We stop twice here: ... $ gdb -q -batch 1 -ex "break 4" -ex run -ex "continue" Breakpoint 1 at 0x40049a: file test.c, line 4. Breakpoint 1, main () at test.c:4 4 while (1); Breakpoint 1, main () at test.c:4 4 while (1); $ ... and here: ... $ gdb -q -batch 2 -ex "break 5" -ex run -ex "continue" Breakpoint 1 at 0x4004a1: file test2.c, line 5. Breakpoint 1, main () at test2.c:5 5 while (spin); Breakpoint 1, main () at test2.c:5 5 while (spin); $ ... Now, with gcc-11: ... $ gcc-11 test.c -g -o 1 $ gcc-11 test2.c -g -o 2 ... we have the same behaviour for test.c: ... $ gdb -q -batch 1 -ex "break 4" -ex run -ex "continue" Breakpoint 1 at 0x40049a: file test.c, line 4. Breakpoint 1, main () at test.c:4 4 while (1); Breakpoint 1, main () at test.c:4 4 while (1); $ ... but for test2.c: ... $ gdb -q -batch 2 -ex "break 5" -ex run -ex "continue" Breakpoint 1 at 0x4004a1: file test2.c, line 5. Breakpoint 1, main () at test2.c:5 5 while (spin); <HANGS> ... II. The difference can be seen in the .s file for test2.c. With gcc-10, we have: ... .loc 1 4 7 movl $1, -4(%rbp) .L2: .loc 1 5 9 discriminator 1 cmpl $0, -4(%rbp) jne .L2 .loc 1 7 10 movl $0, %eax ... but with gcc-11 there's an extra nop, with a corresponding .loc for line 5: ... .loc 1 4 7 movl $1, -4(%rbp) .loc 1 5 9 nop .L2: .loc 1 5 10 discriminator 1 cmpl $0, -4(%rbp) jne .L2 .loc 1 7 10 movl $0, %eax ... III. OTOH, the behaviour has changed, so it's tempting to say that this is a regression. However, my feeling is that this is actually a progression: we stop at the start of the line. Either way: - if this is a regression is needs to be fixed. - if this is a progression, then can we have the same for test.c? IV. FWIW, I tracked down where the nop is inserted. It happens during outof_cfglayout, in fixup_reorder_chain, here: ... if (!INSN_P (BB_END (nb))) BB_END (nb) = emit_insn_after_noloc (gen_nop (), BB_END (nb), nb); INSN_LOCATION (BB_END (nb)) = e->goto_locus; ... V. Funnily enough, with clang the opposite seems to be the case (https://bugs.llvm.org/show_bug.cgi?id=49614 ): the example with test.c hangs, and the example with test2.c finishes.