================
@@ -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

Reply via email to