https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105248
Bug ID: 105248 Summary: Missing value or location attribute for constant live variable likely caused by tree-dse at -O1/-O2/-O3 Product: gcc Version: 12.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: debug Assignee: unassigned at gcc dot gnu.org Reporter: assaiante at diag dot uniroma1.it Target Milestone: --- In this minimized C example, variable l_56 is marked as optimized out when stepping on a call to an external function that takes it as an argument. This happens then the optimization level is -O1/-O2/-O3 while at -Og the debug information is correctly defined. The variable has constant value. Apparently, tree-dse optimization is responsible for a missing location attribute in the DWARF DIE associated with variable l_56. If we prevent the compiler from performing such optimization, the generated ASM will be identical but the DWARF location info will be complete, making the variable available in its uses. Please find below a detailed analysis for -O1 on x64 and a quick assessment on past gcc versions where the issue is sometimes not present. $ cat a.c void a() { int *b; short l_47 = 5; int l_56 = 6; int **c = &b; test(l_47, l_56); *c = &l_56; } int main () { a(); } $ cat lib.c #include <stdio.h> void test(int l_47, int l_56) { printf("%d %d", l_47, l_56); } GCC and GDB version: - gcc (GCC) 12.0.0 20211227 (experimental) - commit id: 500d3f0a302 - GNU gdb (GDB) 11.2 GDB trace: $ gcc -O1 -g a.c lib.c -o opt $ gdb -q opt Reading symbols from opt... (gdb) b 7 Breakpoint 1 at 0x40054a: file a.c, line 7. (gdb) r Starting program: /tmp/opt Breakpoint 1, a () at a.c:7 7 test(l_47, l_56); (gdb) info locals b = <optimized out> l_47 = 5 l_56 = <optimized out> c = <synthetic pointer> ASM at -O1: 0000000000400546 <a>: 400546: 48 83 ec 08 sub $0x8,%rsp 40054a: be 06 00 00 00 mov $0x6,%esi 40054f: bf 05 00 00 00 mov $0x5,%edi 400554: b8 00 00 00 00 mov $0x0,%eax 400559: e8 30 00 00 00 callq 40058e <test> 40055e: 48 83 c4 08 add $0x8,%rsp 400562: c3 retq DWARF info at -O1: 0x000000a7: DW_TAG_variable DW_AT_name ("l_56") DW_AT_decl_file ("/tmp/a.c") DW_AT_decl_line (5) DW_AT_decl_column (0x09) DW_AT_type (0x0000003d "int") >From DWARF info we can see how the variable l_56 DIE is completely missing either a const value or a location attribute and this lack of information causes the unavailability of its value during debugging. Through some testing we found out that the optimization that makes the variable not available and that introduces the location overlapping is -ftree-dse. If we add -fno-tree-dse to the previous compilation command line, the issue is not present anymore since the DWARF location is correctly computed with the correct value associated with it. ASM at -O1 with -fno-tree-dse: 0000000000400546 <a>: 400546: 48 83 ec 08 sub $0x8,%rsp 40054a: be 06 00 00 00 mov $0x6,%esi 40054f: bf 05 00 00 00 mov $0x5,%edi 400554: b8 00 00 00 00 mov $0x0,%eax 400559: e8 30 00 00 00 callq 40058e <test> 40055e: 48 83 c4 08 add $0x8,%rsp 400562: c3 retq DWARF info at -O1 with -fno-tree-dse: 0x000000a7: DW_TAG_variable DW_AT_name ("l_56") DW_AT_decl_file ("/tmp/a.c") DW_AT_decl_line (5) DW_AT_decl_column (0x09) DW_AT_type (0x0000003d "int") DW_AT_location (0x0000000e: [0x000000000040054a, 0x000000000040055e): DW_OP_lit6, DW_OP_stack_value) DW_AT_GNU_locviews (0x0000000c) We have also tested older gcc versions (6.4, 7.5, 8.4, 9.3, 10.3, 11.1) and the results are identical to the git version.