https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118292
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jakub at gcc dot gnu.org, | |jason at gcc dot gnu.org, | |redi at gcc dot gnu.org --- Comment #1 from Jakub Jelinek <jakub at gcc dot gnu.org> --- The reason why it fails and doesn't fail with -Dno_unique_address= is that in the latter case when checking if B has "has all non-static data members and bit-fields in the class and its base classes first declared in the same class" 2110 /* ...has all non-static data members and bit-fields in the class 2111 and its base classes first declared in the same class. */ 2112 for (basefield = TYPE_FIELDS (basetype); basefield; 2113 basefield = DECL_CHAIN (basefield)) 2114 if (TREE_CODE (basefield) == FIELD_DECL 2115 && !(DECL_FIELD_IS_BASE (basefield) 2116 && is_empty_field (basefield))) 2117 { 2118 if (field) 2119 CLASSTYPE_NON_STD_LAYOUT (t) = 1; 2120 else 2121 field = basefield; 2122 break; 2123 } sees basefield with A type and is_empty_field is false because of the e member in A, so B is marked as non-std-layout. In the no_unique_address case, is_empty_field is true for the basefield with A type, I think there was the intent that classes with [[no_unique_address]] empty non-static data member at the beginning are treated ABI-wise the same as if it was a base class instead. And if it is instead struct A : E1 {}; then both GCC and clang agree B is a standard layout class.