On 08/20/2018 03:09 PM, Richard Biener wrote:
> On Fri, 17 Aug 2018, Tom de Vries wrote:
> 
>> I've rewritten the patch to work generically, not just for DW_AT_upper_bound,
>> and to reuse the code already there in add_scalar_info.
>>
>> OK for trunk?
>>
>> Thanks,
>> - Tom
>>
>> [debug] Fix handling of vlas in lto
>>
>> Atm, when running vla-1.c with -O0 -flto, we have:
>> ...
>> FAIL: gcc.dg/guality/vla-1.c -O0 -flto -fuse-linker-plugin \
>>   -fno-fat-lto-objects line 17 sizeof (a) == 6
>> ...
>>
>> The vla a[i + 1] in f1 is gimplified into:
>> ...
>> f1 (int i)
>> {
>>   char a[0:D.1922] [value-expr: *a.0];
>>   char[0:D.1922] * a.0;
>>
>>   D.1921 = i + 1;
>>   D.1926 = (sizetype) D.1921;
>>   a.0 = __builtin_alloca_with_align (D.1926, 8);
>> ...
>>
>> The early debug info for the upper bound of the type of vla a that we stream
>> out is:
>> ...
>>   DIE    0: DW_TAG_subrange_type (0x7f85029a90f0)
>>     DW_AT_upper_bound: location descriptor:
>>       (0x7f85029a9230) DW_OP_GNU_variable_value die -> 0 (0x7f85029a94b0), 0
>>   DIE    0: DW_TAG_variable (0x7f85029a94b0)
>>     DW_AT_name: "D.1922"
>>     DW_AT_type: die -> 0 (0x7f85029a3d70)
>>     DW_AT_artificial: 1
>> ...
>>
>> and in ltrans we have for that same upper bound:
>> ...
>>   DIE    0: DW_TAG_subrange_type (0x7f5183b57d70)
>>     DW_AT_upper_bound: die -> 0 (0x7f5183b576e0)
>>   DIE    0: DW_TAG_variable (0x7f5183b576e0)
>>     DW_AT_name: "D.4278"
>>     DW_AT_abstract_origin: die -> label: vla_1.c.6719312a + 193 
>> (0x7f5183b57730)
>> ...
>> where D.4278 has abstract origin D.1922.
>>
>> The D.4278 die has no DW_AT_location, so when evaluting "sizeof (a)" in the
>> debugger, we can't find the information to get the value of D.4278, and the
>> debugger prints "<optimized out>".
>>
>> This patch fixes that by either:
>> - adding DW_AT_location to the referenced variable die, or
>> - instead of using a ref for the upper bound, using an exprloc.
>>
>> When changing gcc.dg/guality/guality.exp to run the usual flto flavours
>> "-fno-use-linker-plugin -flto-partition=none" and "-fuse-linker-plugin
>> -fno-fat-lto-objects" in combination with O0, Og, O1, O2, O3 and Os, this 
>> patch
>> fixes all (20) failures in vla-1.c, leaving only:
>> ...
>> No symbol "i" in current context.
>> UNSUPPORTED: gcc.dg/guality/vla-1.c  -O3 -flto -fno-use-linker-plugin \
>>   -flto-partition=none line 17 i == 5
>> 'a' has unknown type; cast it to its declared type
>> UNSUPPORTED: gcc.dg/guality/vla-1.c  -O3 -flto -fno-use-linker-plugin \
>>   -flto-partition=none line 17 sizeof (a) == 6
>> ...
>>
>> Bootstrapped and reg-tested on x86_64.
> 
> This looks OK to me.

Committed.

>  Note that with a gdb with DW_OP_variable_value 
> support we should be able to elide the VLA type in the concrete
> instance...
> 

Using this patch we elide the VLA type in the concrete instance for -O2
-flto:
...
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index dd8f438dfd3..5776185d9c6 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -23712,12 +23712,14 @@ gen_variable_die (tree decl, tree origin,
dw_die_ref context_die)
              && variably_modified_type_p
                   (type, decl_function_context (decl_or_origin)))
            {
+#if 0
              if (decl_by_reference_p (decl_or_origin))
                add_type_attribute (var_die, TREE_TYPE (type),
                                    TYPE_UNQUALIFIED, false,
                                    context_die);
              else
                add_type_attribute (var_die, type,
                                    decl_quals (decl_or_origin),
                                    false, context_die);
+#endif
            }

          goto gen_variable_die_location;
...
and using master gdb (which supports DW_OP_variable_value, yay) we get:
...
7        return a[0];          /* { dg-final { gdb-test . "sizeof (a)"
"6" } } */
vla-1.gdb:3: Error in sourced command file:
value has been optimized out
...

When evaluating sizeof (a) in gdb:
- we look for the concrete type die of a
- since that one is elided, we fall back on the type die of the abstract
  origin of a
- that one has an expr location for the upper bound containing a
  DW_OP_variable_value referring to a variable in early debug.
- that variable has no DW_AT_location, so we end up with "value has been
  optimized out"

AFAIU, that's roughly the issue discussed in
PR20426 - "gdb does not interpret DWARF annotating imported units fully"
 ( https://sourceware.org/bugzilla/show_bug.cgi?id=20426 ),.

Is my understanding correct that it's not yet clear how this should be
fixed?

Thanks,
- Tom

> Not sure how we should go forward there - use a configure test or
> simply tell people to update gdb?
> 
> Thanks,
> Richard.
> 
>> 2018-08-17  Tom de Vries  <tdevr...@suse.de>
>>
>>      * dwarf2out.c (add_scalar_info): Don't add reference to existing die
>>      unless the referenced die describes the added property using
>>      DW_AT_location or DW_AT_const_value.  Fall back to exprloc case.
>>      Otherwise, add a DW_AT_location to the referenced die.
>>
>> ---
>>  gcc/dwarf2out.c | 32 ++++++++++++++++++++------------
>>  1 file changed, 20 insertions(+), 12 deletions(-)
>>
>> diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
>> index 9ed473088e7..e1dccb42823 100644
>> --- a/gcc/dwarf2out.c
>> +++ b/gcc/dwarf2out.c
>> @@ -20598,7 +20598,7 @@ static void
>>  add_scalar_info (dw_die_ref die, enum dwarf_attribute attr, tree value,
>>               int forms, struct loc_descr_context *context)
>>  {
>> -  dw_die_ref context_die, decl_die;
>> +  dw_die_ref context_die, decl_die = NULL;
>>    dw_loc_list_ref list;
>>    bool strip_conversions = true;
>>    bool placeholder_seen = false;
>> @@ -20675,7 +20675,7 @@ add_scalar_info (dw_die_ref die, enum 
>> dwarf_attribute attr, tree value,
>>  
>>        if (decl != NULL_TREE)
>>      {
>> -      dw_die_ref decl_die = lookup_decl_die (decl);
>> +      decl_die = lookup_decl_die (decl);
>>  
>>        /* ??? Can this happen, or should the variable have been bound
>>           first?  Probably it can, since I imagine that we try to create
>> @@ -20684,8 +20684,12 @@ add_scalar_info (dw_die_ref die, enum 
>> dwarf_attribute attr, tree value,
>>           later parameter.  */
>>        if (decl_die != NULL)
>>          {
>> -          add_AT_die_ref (die, attr, decl_die);
>> -          return;
>> +          if (get_AT (decl_die, DW_AT_location)
>> +              || get_AT (decl_die, DW_AT_const_value))
>> +            {
>> +              add_AT_die_ref (die, attr, decl_die);
>> +              return;
>> +            }
>>          }
>>      }
>>      }
>> @@ -20729,15 +20733,19 @@ add_scalar_info (dw_die_ref die, enum 
>> dwarf_attribute attr, tree value,
>>        || placeholder_seen)
>>      return;
>>  
>> -  if (current_function_decl == 0)
>> -    context_die = comp_unit_die ();
>> -  else
>> -    context_die = lookup_decl_die (current_function_decl);
>> +  if (!decl_die)
>> +    {
>> +      if (current_function_decl == 0)
>> +    context_die = comp_unit_die ();
>> +      else
>> +    context_die = lookup_decl_die (current_function_decl);
>> +
>> +      decl_die = new_die (DW_TAG_variable, context_die, value);
>> +      add_AT_flag (decl_die, DW_AT_artificial, 1);
>> +      add_type_attribute (decl_die, TREE_TYPE (value), TYPE_QUAL_CONST, 
>> false,
>> +                      context_die);
>> +    }
>>  
>> -  decl_die = new_die (DW_TAG_variable, context_die, value);
>> -  add_AT_flag (decl_die, DW_AT_artificial, 1);
>> -  add_type_attribute (decl_die, TREE_TYPE (value), TYPE_QUAL_CONST, false,
>> -                  context_die);
>>    add_AT_location_description (decl_die, DW_AT_location, list);
>>    add_AT_die_ref (die, attr, decl_die);
>>  }
>>
>>
> 

Reply via email to