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?

Reply via email to