The static_assert in the following code fails on clang HEAD 12.0.0
(https://github.com/llvm/llvm-project.git 1c19900f9417bd0b832c1cb70863b2439a18647f)
but should succeed as D is not a standard-layout class.
struct B1 {};
struct B2 { B1 b1; };
struct D : B1, B2 {};
static_assert(!__is_standard_layout(D), "D is not a standard-layout class");
has no element of the set M(S) of types (defined below) as a base class.
M(X) is defined as follows:
...
If X is a non-union class type whose first non-static data member
has type X0 (where said member may be an anonymous union), the
set M(X) consists of X0 and the elements of M(X0).
The setM(D) consists of just B1 because D is a non-union class type
whose first non-static data member has type B1. Then, because D has B1
as a base class, D is not a standard-layout class.
(If D is a standard-layout class, it must be layout compatible with B2.
But sizeof(D) is 2 while sizeof(B2) is 1, which means they can't be
layout compatible.)
Extended Description
The static_assert in the following code fails on clang HEAD 12.0.0 (https://github.com/llvm/llvm-project.git 1c19900f9417bd0b832c1cb70863b2439a18647f) but should succeed as D is not a standard-layout class.
Tested at: https://wandbox.org/permlink/ha8cStNKHEKl2BaJ
The standard says: https://timsong-cpp.github.io/cppwp/n4659/class#7
The set
M(D)
consists of justB1
becauseD
is a non-union class type whose first non-static data member has typeB1
. Then, becauseD
hasB1
as a base class,D
is not a standard-layout class.(If
D
is a standard-layout class, it must be layout compatible withB2
. Butsizeof(D)
is2
whilesizeof(B2)
is1
, which means they can't be layout compatible.)