================ @@ -1558,6 +1558,89 @@ void is_standard_layout() int t71[F(__is_standard_layout(HasEmptyIndirectBaseAsSecondUnionMember))]; } +struct CStruct2 { + int one; + int two; +}; + +struct CEmptyStruct2 {}; + +struct CppEmptyStruct2 : CStruct2 {}; +struct CppStructStandard2 : CEmptyStruct2 { + int three; + int four; +}; +struct CppStructNonStandardByBase2 : CStruct2 { + int three; + int four; +}; +struct CppStructNonStandardByVirt2 : CStruct2 { + virtual void method() {} +}; +struct CppStructNonStandardByMemb2 : CStruct2 { + CppStructNonStandardByVirt member; +}; +struct CppStructNonStandardByProt2 : CStruct2 { + int five; +protected: + int six; +}; +struct CppStructNonStandardByVirtBase2 : virtual CStruct2 { +}; +struct CppStructNonStandardBySameBase2 : CEmptyStruct2 { + CEmptyStruct member; +}; +struct CppStructNonStandardBy2ndVirtBase2 : CEmptyStruct2 { + CEmptyStruct member; +}; + +struct CStructWithQualifiers { + const int one; + volatile int two; +}; + +struct CStructNoUniqueAddress { + int one; + [[no_unique_address]] int two; +}; + +struct CStructNoUniqueAddress2 { + int one; + [[no_unique_address]] int two; +}; + +struct CStructAlignment { + int one; + alignas(16) int two; +}; + +struct CStructIncomplete; + +void is_layout_compatible() +{ + static_assert(__is_layout_compatible(void, void), ""); + static_assert(__is_layout_compatible(int, int), ""); + static_assert(__is_layout_compatible(int[], int[]), ""); + static_assert(__is_layout_compatible(int[2], int[2]), ""); + static_assert(__is_layout_compatible(CStruct, CStruct2), ""); + static_assert(__is_layout_compatible(CEmptyStruct, CEmptyStruct2), ""); + static_assert(__is_layout_compatible(CppEmptyStruct, CppEmptyStruct2), ""); + static_assert(__is_layout_compatible(CppStructStandard, CppStructStandard2), ""); + static_assert(!__is_layout_compatible(CppStructNonStandardByBase, CppStructNonStandardByBase2), ""); + static_assert(!__is_layout_compatible(CppStructNonStandardByVirt, CppStructNonStandardByVirt2), ""); + static_assert(!__is_layout_compatible(CppStructNonStandardByMemb, CppStructNonStandardByMemb2), ""); + static_assert(!__is_layout_compatible(CppStructNonStandardByProt, CppStructNonStandardByProt2), ""); + static_assert(!__is_layout_compatible(CppStructNonStandardByVirtBase, CppStructNonStandardByVirtBase2), ""); + static_assert(!__is_layout_compatible(CppStructNonStandardBySameBase, CppStructNonStandardBySameBase2), ""); + static_assert(!__is_layout_compatible(CppStructNonStandardBy2ndVirtBase, CppStructNonStandardBy2ndVirtBase2), ""); + static_assert(!__is_layout_compatible(CStruct, CStructWithQualifiers), ""); // FIXME: this is CWG1719 + static_assert(__is_layout_compatible(CStruct, CStructNoUniqueAddress) == bool(__has_cpp_attribute(no_unique_address)), ""); // FIXME: this is CWG2759 + static_assert(__is_layout_compatible(CStructNoUniqueAddress, CStructNoUniqueAddress2) == bool(__has_cpp_attribute(no_unique_address)), ""); // FIXME: this is CWG2759 + static_assert(__is_layout_compatible(CStruct, CStructAlignment), ""); + static_assert(__is_layout_compatible(CStructIncomplete, CStructIncomplete), ""); + static_assert(!__is_layout_compatible(CStruct, CStructIncomplete), ""); +} ---------------- Endilll wrote:
> A type is layout compatible with its qualified version. e.g., SomeStruct and > const SomeStruct Done. It even works correctly for class types. > Layout compatibility of function types (not function pointer types), e.g., > void(int) and void(int) Done. I added tests for function types, reference to functions, pointers to function, pointers to data members, pointers to member functions. > Diagnostics when given an incomplete type for either operand We don't issue any, as far as I can see. And I don't think we can when the types are the same, ignoring cv qualifiers: > Two types cv1 T1 and cv2 T2 are [layout-compatible > types](http://eel.is/c++draft/basic.types.general#def:type,layout-compatible) > if T1 and T2 are the same type, [layout-compatible > enumerations](http://eel.is/c++draft/dcl.enum#def:layout-compatible,enumeration), > or [layout-compatible standard-layout class > types](http://eel.is/c++draft/class.mem#def:layout-compatible,class)[.](http://eel.is/c++draft/basic.types.general#11.sentence-1) > That int and unsigned int are not layout compatible > That char and signed char/unsigned char are not layout compatible > That an enumeration type and its underlying type are not layout compatible Done. > I think we should add those tests somewhere (either here or in dr1xxx.cpp) so > 1) we know we don't crash on them, 2) we're alerted to behavioral changes in > this area, and 3) better documentation of existing behavior. Agreed. I marked 1334 as superseded as 1719, and added a test for 1719. https://github.com/llvm/llvm-project/pull/81506 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits