[clang] [Clang] Implement diagnostics for why `std::is_standard_layout` is false (PR #144161)
Corentin Jabot via cfe-commits
cfe-commits at lists.llvm.org
Wed Jun 25 05:26:39 PDT 2025
================
@@ -488,3 +488,89 @@ static_assert(__is_trivially_copyable(S12));
// expected-note at -1 {{'S12' is not trivially copyable}} \
// expected-note@#tc-S12 {{'S12' defined here}}
}
+
+namespace standard_layout_tests {
+struct WithVirtual { // #sl-Virtual
+ virtual void foo(); // #sl-Virtual-Foo
+};
+static_assert(__is_standard_layout(WithVirtual));
+// expected-error at -1 {{static assertion failed due to requirement '__is_standard_layout(standard_layout_tests::WithVirtual)'}} \
+// expected-note at -1 {{'WithVirtual' is not standard-layout}} \
+// expected-note at -1 {{because it has a virtual function}} \
+// expected-note@#sl-Virtual-Foo {{'foo' defined here}} \
+// expected-note@#sl-Virtual {{'WithVirtual' defined here}}
+
+struct MixedAccess { // #sl-Mixed
+public:
+ int a; // #sl-MixedF1
+private:
+ int b; // #sl-MixedF2
+};
+static_assert(__is_standard_layout(MixedAccess));
+// expected-error at -1 {{static assertion failed due to requirement '__is_standard_layout(standard_layout_tests::MixedAccess)'}} \
+// expected-note at -1 {{'MixedAccess' is not standard-layout}} \
+// expected-note at -1 {{because it has mixed access specifiers}} \
+// expected-note@#sl-MixedF1 {{'a' defined here}}
+// expected-note@#sl-MixedF2 {{field 'b' has a different access specifier than field 'a'}}
+// expected-note@#sl-Mixed {{'MixedAccess' defined here}}
+
+struct VirtualBase { virtual ~VirtualBase(); }; // #sl-VirtualBase
+struct VB : virtual VirtualBase {}; // #sl-VB
+static_assert(__is_standard_layout(VB));
+// expected-error at -1 {{static assertion failed due to requirement '__is_standard_layout(standard_layout_tests::VB)'}} \
+// expected-note at -1 {{'VB' is not standard-layout}} \
+// expected-note at -1 {{because it has a virtual base 'VirtualBase'}} \
+// expected-note at -1 {{because it has a non-standard-layout base 'VirtualBase'}} \
+// expected-note at -1 {{because it has a virtual function}}
+// expected-note@#sl-VB {{'VB' defined here}}
+// expected-note@#sl-VB {{'~VB' defined here}}
+
+union U { // #sl-U
+public:
+ int x; // #sl-UF1
+private:
+ int y; // #sl-UF2
+};
+static_assert(__is_standard_layout(U));
+// expected-error at -1 {{static assertion failed due to requirement '__is_standard_layout(standard_layout_tests::U)'}} \
+// expected-note at -1 {{'U' is not standard-layout}} \
+// expected-note at -1 {{because it has mixed access specifiers}}
+// expected-note@#sl-UF1 {{'x' defined here}}
+// expected-note@#sl-UF2 {{field 'y' has a different access specifier than field 'x'}}
+// expected-note@#sl-U {{'U' defined here}}
+
+// Single base class is OK
+struct BaseClass{ int a; }; // #sl-BaseClass
+struct DerivedOK : BaseClass {}; // #sl-DerivedOK
+static_assert(__is_standard_layout(DerivedOK));
+
+// Primitive types should be standard layout
+static_assert(__is_standard_layout(int)); // #sl-Int
+static_assert(__is_standard_layout(float)); // #sl-Float
+
+// Multi-level inheritance: Non-standard layout
+struct Base1 { int a; }; // #sl-Base1
+struct Base2 { int b; }; // #sl-Base2
+struct DerivedClass : Base1, Base2 {}; // #sl-DerivedClass
+static_assert(__is_standard_layout(DerivedClass));
+// expected-error at -1 {{static assertion failed due to requirement '__is_standard_layout(standard_layout_tests::DerivedClass)'}} \
+// expected-note at -1 {{'DerivedClass' is not standard-layout}} \
+// expected-note at -1 {{because it has multiple base classes with data members}} \
+// expected-note@#sl-DerivedClass {{'DerivedClass' defined here}}
+
+// Inheritance hierarchy with multiple classes having data members
+struct BaseA { int a; }; // #sl-BaseA
+struct BaseB : BaseA {}; // inherits BaseA, has no new members
+struct BaseC: BaseB { int c; }; // #sl-BaseC
+static_assert(__is_standard_layout(BaseC));
+// expected-error at -1 {{static assertion failed due to requirement '__is_standard_layout(standard_layout_tests::BaseC)'}} \
+// expected-note at -1 {{'BaseC' is not standard-layout}} \
+// expected-note at -1 {{because it has an indirect base 'BaseA' with data members}} \
+// expected-note@#sl-BaseC {{'BaseC' defined here}} \
+// Multiple direct base classes with no data members --> standard layout
+struct BaseX {}; // #sl-BaseX
+struct BaseY {}; // #sl-BaseY
+struct MultiBase : BaseX, BaseY {}; // #sl-MultiBase
----------------
cor3ntin wrote:
@AaronBallman Note that no_unique_address does not interact with the notion of standard layout (you would think that it would, wouldn't you? :D)
https://github.com/llvm/llvm-project/pull/144161
More information about the cfe-commits
mailing list