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

--- Comment #2 from Tom de Vries <vries at gcc dot gnu.org> ---
(In reply to Richard Biener from comment #1)
> do you have an idea why it works with -gdwarf-4 but not -gdwarf-5?

If we do with n == 4 and n == 5:
...
$ rm -f *.c.* ; ./install/bin/g++ test.c -c -g -gdwarf-$n -fdump-tree-all
-fno-eliminate-unused-debug-symbols
...
we find in test.c.t.earlydebug for n == 4:
...
        DIE    0: DW_TAG_member (0x7f5303154140)
          abbrev id: 0 offset: 0 mark: 0
          DW_AT_name: "sa"
          DW_AT_decl_file: "test.c" (0)
          DW_AT_decl_line: 3
          DW_AT_decl_column: 14
          DW_AT_type: die -> 0 (0x7f53031540f0)
          DW_AT_external: 1
          DW_AT_declaration: 1
...
and for n == 5:
...
        DIE    0: DW_TAG_variable (0x7fa1cdced140)
          abbrev id: 0 offset: 0 mark: 0
          DW_AT_name: "sa"
          DW_AT_decl_file: "test.c" (0)
          DW_AT_decl_line: 3
          DW_AT_decl_column: 14
          DW_AT_linkage_name: "_ZN1a2saE"
          DW_AT_type: die -> 0 (0x7fa1cdced0f0)
          DW_AT_external: 1
          DW_AT_declaration: 1
...

So we have DW_TAG_member vs DW_TAG_variable.

There's some piece of code here in prune_unused_types_walk that mentions this
difference:
...
          /* For static data members, the declaration in the class is supposed  
             to have DW_TAG_member tag in DWARF{3,4} but DW_TAG_variable in     
             DWARF5.  DW_TAG_member will be marked, so mark even such           
             DW_TAG_variables in DWARF5, as long as it has DW_AT_const_value    
             attribute.  */
          if (dwarf_version >= 5
              && class_scope_p (die->die_parent)
              && get_AT (die, DW_AT_const_value))
            break;
...
and also removing the DW_AT_const_value part of this clause fixes it.

Looking at the log message for that change:
...
In DWARF4 and earlier, static data members were represented as DW_TAG_member
and the pruning code wouldn't prune those, but in DWARF5 they are represented
as DW_TAG_variable with the class parent and the pruning code prunes those by
default unless they are referenced from a separate definition without the class
parent (out of class definition).
C++17 inline vars have the definitions in the class though and even before
if the static data member isn't ODR used, it doesn't need to be defined, so we
could just never describe those static data members in the debug info.

This change stops the pruning of DW_TAG_variable with DW_AT_const_value
attribute with a class parent for -gdwarf-5 and later.
...

Well, that explains it, but I'm not sure I understand why it's ok not to
describe an undefined static data member.  It changes the appearance of the
type and suggest an odr error when comparing with a CU where the static data
member is defined. Note that this also makes dwz's job harder.

Reply via email to