Hi,

clang-12 will create the same DWARF for class B with [[no_unique_address]]
either present or not. Despite that class C derived from B has different
layout depending on from which class B it gets derived:

------------------------------------------------------------------------------
struct A {};
struct By { [[no_unique_address]] A a; };
struct Cy : By { char c; } cy;
struct Bn {                       A a; };
struct Cn : Bn { char c; } cn;
#include <iostream>
int main() {
  std::cout << "sizeof(Cy) = " << sizeof(Cy) << " offsetof(Cy, c) = " << 
offsetof(Cy, c) << "\n";
  std::cout << "sizeof(Cn) = " << sizeof(Cn) << " offsetof(Cn, c) = " << 
offsetof(Cn, c) << "\n";
}
// sizeof(Cy) = 1 offsetof(Cy, c) = 0
// sizeof(Cn) = 2 offsetof(Cn, c) = 1
------------------------------------------------------------------------------

gcc-11 creates a different DWARF for the two variants of B but that DWARF does
not look as compliant to me:

------------------------------------------------------------------------------

DW_TAG_structure_type
  DW_AT_name   ("B")
  DW_AT_byte_size      (1)

  DW_TAG_member
    DW_AT_name ("a")
    DW_AT_type (0x0000001e "A")
By:  DW_AT_data_member_location (-1)
Bn:  DW_AT_data_member_location (0x00)

  NULL
------------------------------------------------------------------------------

>From a discussion at https://reviews.llvm.org/D101237 :

(1) Raphael Isemann (teemperor) notes:
    FWIW, I took a look at the DWARF standard and I think that is actually
    something we should already emit in the form of a
    "DW_AT_byte_size 0" attribute at the field? Quote:
        If the size of a data member is not the same as the size of the type
        given for the data member, the data member has either
        a DW_AT_byte_size or a DW_AT_bit_size attribute whose integer constant
        value (see Section 2.19) is the amount of storage needed to hold the
        value of the data member.

(2) David Blaikie maybe meant in the beginning new DW_AT_no_unique_address
    but IIUC that may have been probably later deprecated as not really needed.

(3) One could also omit such member completely but that would break template
    metaprogramming based on such missing types from DWARF.

I do not see many other options. That (1) would look like:

------------------------------------------------------------------------------
DW_TAG_structure_type
  DW_AT_calling_convention       (DW_CC_pass_by_value)
  DW_AT_name     ("B")
  DW_AT_byte_size        (0x01)

  DW_TAG_member
    DW_AT_name   ("a")
    DW_AT_type   (0x00000065 "A")
Bn:
By: DW_AT_byte_size      (0x00)
    DW_AT_data_member_location   (0x00)

  NULL
------------------------------------------------------------------------------


Jan

_______________________________________________
Dwarf-Discuss mailing list
Dwarf-Discuss@lists.dwarfstd.org
http://lists.dwarfstd.org/listinfo.cgi/dwarf-discuss-dwarfstd.org

Reply via email to