https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86582
Bug ID: 86582 Summary: [debug] vla size reported as 0 at Og Product: gcc Version: 9.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: debug Assignee: unassigned at gcc dot gnu.org Reporter: vries at gcc dot gnu.org Target Milestone: --- Consider this test-case, minimized from vla-1.c: ... /* { dg-do run } */ /* { dg-options "-g" } */ int __attribute__((noinline, noclone)) f1 (int i) { char a[i + 1]; a[0] = 5; return a[0]; /* { dg-final { gdb-test . "sizeof (a)" "6" } } */ } int main () { volatile int j; int i = 5; asm volatile ("" : "=r" (i) : "0" (i)); j = f1 (i); return 0; } ... This fails at Og: ... FAIL: gcc.dg/guality/vla-1.c -Og -DPREVENT_OPTIMIZATION line . sizeof (a) == 6 ... The size is reported as 0 by gdb: ... $ gdb vla-1.exe -batch -ex "b 10" -ex "r" -ex "p sizeof(a)" Breakpoint 1 at 0x40049b: file vla-1.c, line 10. Breakpoint 1, f1 (i=<optimized out>) at vla-1.c:10 10 return a[0]; /* { dg-final { gdb-test . "sizeof (a)" "6" } } */ $1 = 0 ... We should be able to report the correct size, because the vla is not optimized away. AFAIU from debugging gdb, the evaluation of this location expression: ... .value 0xe # Location expression size .byte 0xf3 # DW_OP_GNU_entry_value .uleb128 0x1 .byte 0x55 # DW_OP_reg5 .byte 0x23 # DW_OP_plus_uconst .uleb128 0x1 .byte 0x8 # DW_OP_const1u .byte 0x20 .byte 0x24 # DW_OP_shl .byte 0x8 # DW_OP_const1u .byte 0x20 .byte 0x26 # DW_OP_shra .byte 0x31 # DW_OP_lit1 .byte 0x1c # DW_OP_minus .byte 0x9f # DW_OP_stack_value ... fails on the DW_OP_GNU_entry_value. It fails due to this throw in dwarf_expr_reg_to_entry_parameter in gdb: ... /* DW_TAG_call_site_parameter will be missing just if GCC could not determine its value. */ throw_error (NO_ENTRY_VALUE_ERROR, _("Cannot find matching parameter " "at DW_TAG_call_site %s at %s"), paddress (gdbarch, caller_pc), msym == NULL ? "???" : MSYMBOL_PRINT_NAME (msym)); ... I see in main though: ... call f1 .LVL9: ... and ... .uleb128 0x6 # (DIE (0x6a) DW_TAG_call_site) .quad .LVL9 # DW_AT_call_return_pc .long 0x84 # DW_AT_call_origin ... By modifying main to return i, I get in addition: ... .uleb128 0x7 # (DIE (0x77) DW_TAG_call_site_parameter) .uleb128 0x1 # DW_AT_location .byte 0x55 # DW_OP_reg5 .uleb128 0x2 # DW_AT_call_value .byte 0x73 # DW_OP_breg3 .sleb128 0 ... and then gdb prints sizeof(a) as expected. This seems to be cause DW_TAG_call_site_parameter is generated based on REG_CALL_ARG_LOCATION, and in the case without call_site_parameter we have: ... (call_insn 15 39 44 2 (set (reg:SI 0 ax) (call (mem:QI (symbol_ref:DI ("f1") [flags 0x3] <function_decl 0x7f7bc3fc2700 f1>) \ [0 f1 S1 A8]) (const_int 0 [0]))) "vla-1.c":19 722 {*call_value} (expr_list:REG_CALL_ARG_LOCATION (nil) (expr_list:REG_DEAD (reg:SI 5 di) (expr_list:REG_EH_REGION (const_int 0 [0]) (nil)))) (expr_list:SI (use (reg:SI 5 di)) (nil))) ... and in the case with call_site_parameter we have: ... (call_insn 15 14 17 2 (set (reg:SI 0 ax) (call (mem:QI (symbol_ref:DI ("f1") [flags 0x3] <function_decl 0x7f701d65a700 f1>) \ [0 f1 S1 A8]) (const_int 0 [0]))) "vla-1.c":19 722 {*call_value} (expr_list:REG_CALL_ARG_LOCATION (expr_list:REG_DEP_TRUE (concat:SI (reg:SI 5 di) (reg:SI 3 bx [orig:89 i ] [89])) (nil)) (expr_list:REG_DEAD (reg:SI 5 di) (expr_list:REG_EH_REGION (const_int 0 [0]) (nil)))) (expr_list:SI (use (reg:SI 5 di)) (nil))) ... So, why doesn't var-tracking generate the REG_CALL_ARG_LOCATION that we need?