https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105159

            Bug ID: 105159
           Summary: -fipa-reference-addressable causes drop of DWARF
                    location info at -Og
           Product: gcc
           Version: 12.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: debug
          Assignee: unassigned at gcc dot gnu.org
          Reporter: dc.delia at protonmail dot com
  Target Milestone: ---

In this code, pointer variable l_515 assigned at line 4 appears as optimized
out at line 6 during source-level debugging, then the newly assigned value at
line 7 is available at line 8. This happens with -Og where
-fipa-reference-addressable makes the involved DWARF location information go
away but the compiled code stays the same. By disabling this option, the value
from line 4 becomes visible too.

We found this issue on gcc commit 500d3f0a302 on an x64 target using gdb 11.2,
while on prior gcc versions the behavior is either the same or the variable is
marked as optimized out the whole time.

$ cat -n a.c
int a, b;
static char c, d;
void foo() {
  char *l_515 = &c;
  char **f = &l_515;
  b++;
  *f = &d;
  d = 0;
}
int main() {
  foo();
  a = c;
}

GDB trace:
$ gcc -Og -g a.c -o opt
$ gdb -q opt
Reading symbols from opt...
(gdb) b 6
Breakpoint 1 at 0x400486: file a.c, line 6.
(gdb) r
Starting program: /home/stepping/57/reduce/opt 

Breakpoint 1, foo () at a.c:6
6         b++;
(gdb) info locals
l_515 = <optimized out>
f = <synthetic pointer>
(gdb) n
8         d = 0;
(gdb) info locals
l_515 = 0x601034 <d> ""
f = <synthetic pointer>

Compiled code of foo function:
0000000000400486 <foo>:
 400486:       83 05 9f 0b 20 00 01    addl   $0x1,0x200b9f(%rip)        #
60102c <b>
 40048d:       c6 05 a0 0b 20 00 00    movb   $0x0,0x200ba0(%rip)        #
601034 <d>
 400494:       c3                      retq

The first two instructions of function foo are associated with line 6 and 8,
respectively.

DWARF at -Og:
0x000000cc:     DW_TAG_variable
                  DW_AT_name    ("l_515")
                  DW_AT_decl_file       ("/home/stepping/57/reduce/a.c")
                  DW_AT_decl_line       (4)
                  DW_AT_decl_column     (0x09)
                  DW_AT_type    (0x000000f3 "char*")
                  DW_AT_location        (0x0000000e: 
                     [0x000000000040048d, 0x0000000000400494): DW_OP_addr
0x601034, DW_OP_stack_value)
                  DW_AT_GNU_locviews    (0x0000000c)


In the DWARF information, there is only one location entry associated with the
instruction at 40048d which is mapped to line 8.

We found out that the optimization that makes the variable disappear is likely
-fipa-reference-addressable. After disabling it, when stepping at line 6 we can
now see the value of pointer l_515, since a new entry appeared in the list in
the DWARF location info of l_515 and is associated with the instruction at
400486, which is mapped to line 6.

DWARF at -Og with -fno-ipa-reference-addressable:
0x000000d2:     DW_TAG_variable
                  DW_AT_name    ("l_515")
                  DW_AT_decl_file       ("/home/stepping/57/reduce/a.c")
                  DW_AT_decl_line       (4)
                  DW_AT_decl_column     (0x09)
                  DW_AT_type    (0x000000f9 "char*")
                  DW_AT_location        (0x00000010: 
                     [0x0000000000400486, 0x000000000040048d): DW_OP_addr
0x601035, DW_OP_stack_value
                     [0x000000000040048d, 0x0000000000400494): DW_OP_addr
0x601034, DW_OP_stack_value)
                  DW_AT_GNU_locviews    (0x0000000c)


This is what we found for a selection of prior gcc versions:
- 6.4, 7.5, 8.4, 9.3: l_515 is marked as optimized out the whole time and DWARF
location info is missing entirely
- 10.3, 11.1: the behavior is like the 500d3f0a302 git version that we tested

Reply via email to