@@ -1558,6 +1558,238 @@ void is_standard_layout()
15581558 int t71[F (__is_standard_layout (HasEmptyIndirectBaseAsSecondUnionMember))];
15591559}
15601560
1561+ struct CStruct2 {
1562+ int one;
1563+ int two;
1564+ };
1565+
1566+ struct CEmptyStruct2 {};
1567+
1568+ struct CppEmptyStruct2 : CStruct2 {};
1569+ struct CppStructStandard2 : CEmptyStruct2 {
1570+ int three;
1571+ int four;
1572+ };
1573+ struct CppStructNonStandardByBase2 : CStruct2 {
1574+ int three;
1575+ int four;
1576+ };
1577+ struct CppStructNonStandardByVirt2 : CStruct2 {
1578+ virtual void method () {}
1579+ };
1580+ struct CppStructNonStandardByMemb2 : CStruct2 {
1581+ CppStructNonStandardByVirt member;
1582+ };
1583+ struct CppStructNonStandardByProt2 : CStruct2 {
1584+ int five;
1585+ protected:
1586+ int six;
1587+ };
1588+ struct CppStructNonStandardByVirtBase2 : virtual CStruct2 {
1589+ };
1590+ struct CppStructNonStandardBySameBase2 : CEmptyStruct2 {
1591+ CEmptyStruct member;
1592+ };
1593+ struct CppStructNonStandardBy2ndVirtBase2 : CEmptyStruct2 {
1594+ CEmptyStruct member;
1595+ };
1596+
1597+ struct CStructWithQualifiers {
1598+ const int one;
1599+ volatile int two;
1600+ };
1601+
1602+ struct CStructNoUniqueAddress {
1603+ int one;
1604+ [[no_unique_address]] int two;
1605+ };
1606+
1607+ struct CStructNoUniqueAddress2 {
1608+ int one;
1609+ [[no_unique_address]] int two;
1610+ };
1611+
1612+ struct CStructAlignment {
1613+ int one;
1614+ alignas (16 ) int two;
1615+ };
1616+
1617+ enum EnumLayout : int {};
1618+ enum class EnumClassLayout {};
1619+ enum EnumForward : int ;
1620+ enum class EnumClassForward ;
1621+
1622+ struct CStructIncomplete ;
1623+
1624+ struct CStructNested {
1625+ int a;
1626+ CStruct s;
1627+ int b;
1628+ };
1629+
1630+ struct CStructNested2 {
1631+ int a2;
1632+ CStruct s2;
1633+ int b2;
1634+ };
1635+
1636+ struct CStructWithBitfelds {
1637+ int a : 5 ;
1638+ int : 0 ;
1639+ };
1640+
1641+ struct CStructWithBitfelds2 {
1642+ int a : 5 ;
1643+ int : 0 ;
1644+ };
1645+
1646+ struct CStructWithBitfelds3 {
1647+ int : 0 ;
1648+ int b : 5 ;
1649+ };
1650+
1651+ struct CStructWithBitfelds4 {
1652+ EnumLayout a : 5 ;
1653+ int : 0 ;
1654+ };
1655+
1656+ union UnionLayout {
1657+ int a;
1658+ double b;
1659+ CStruct c;
1660+ [[no_unique_address]] CEmptyStruct d;
1661+ [[no_unique_address]] CEmptyStruct2 e;
1662+ };
1663+
1664+ union UnionLayout2 {
1665+ CStruct c;
1666+ int a;
1667+ CEmptyStruct2 e;
1668+ double b;
1669+ [[no_unique_address]] CEmptyStruct d;
1670+ };
1671+
1672+ union UnionLayout3 {
1673+ CStruct c;
1674+ int a;
1675+ double b;
1676+ [[no_unique_address]] CEmptyStruct d;
1677+ };
1678+
1679+ struct StructWithAnonUnion {
1680+ union {
1681+ int a;
1682+ double b;
1683+ CStruct c;
1684+ [[no_unique_address]] CEmptyStruct d;
1685+ [[no_unique_address]] CEmptyStruct2 e;
1686+ };
1687+ };
1688+
1689+ struct StructWithAnonUnion2 {
1690+ union {
1691+ CStruct c;
1692+ int a;
1693+ CEmptyStruct2 e;
1694+ double b;
1695+ [[no_unique_address]] CEmptyStruct d;
1696+ };
1697+ };
1698+
1699+ struct StructWithAnonUnion3 {
1700+ union {
1701+ CStruct c;
1702+ int a;
1703+ CEmptyStruct2 e;
1704+ double b;
1705+ [[no_unique_address]] CEmptyStruct d;
1706+ } u;
1707+ };
1708+
1709+
1710+ void is_layout_compatible (int n)
1711+ {
1712+ static_assert (__is_layout_compatible (void , void ), " " );
1713+ static_assert (!__is_layout_compatible (void , int ), " " );
1714+ static_assert (!__is_layout_compatible (void , const void ), " " ); // FIXME: this is CWG1719
1715+ static_assert (!__is_layout_compatible (void , volatile void ), " " ); // FIXME: this is CWG1719
1716+ static_assert (!__is_layout_compatible (const int , volatile int ), " " ); // FIXME: this is CWG1719
1717+ static_assert (__is_layout_compatible (int , int ), " " );
1718+ static_assert (!__is_layout_compatible (int , const int ), " " ); // FIXME: this is CWG1719
1719+ static_assert (!__is_layout_compatible (int , volatile int ), " " ); // FIXME: this is CWG1719
1720+ static_assert (!__is_layout_compatible (const int , volatile int ), " " ); // FIXME: this is CWG1719
1721+ static_assert (!__is_layout_compatible (int , unsigned int ), " " );
1722+ static_assert (!__is_layout_compatible (char , unsigned char ), " " );
1723+ static_assert (!__is_layout_compatible (char , signed char ), " " );
1724+ static_assert (!__is_layout_compatible (unsigned char , signed char ), " " );
1725+ static_assert (__is_layout_compatible (int [], int []), " " );
1726+ static_assert (__is_layout_compatible (int [2 ], int [2 ]), " " );
1727+ static_assert (!__is_layout_compatible (int [n], int [2 ]), " " ); // FIXME: VLAs should be rejected
1728+ static_assert (!__is_layout_compatible (int [n], int [n]), " " ); // FIXME: VLAs should be rejected
1729+ static_assert (__is_layout_compatible (int &, int &), " " );
1730+ static_assert (!__is_layout_compatible (int &, char &), " " );
1731+ static_assert (__is_layout_compatible (void (int ), void (int )), " " );
1732+ static_assert (!__is_layout_compatible (void (int ), void (char )), " " );
1733+ static_assert (__is_layout_compatible (void (&)(int ), void (&)(int )), " " );
1734+ static_assert (!__is_layout_compatible (void (&)(int ), void (&)(char )), " " );
1735+ static_assert (__is_layout_compatible (void (*)(int ), void (*)(int )), " " );
1736+ static_assert (!__is_layout_compatible (void (*)(int ), void (*)(char )), " " );
1737+ using function_type = void ();
1738+ using function_type2 = void (char );
1739+ static_assert (__is_layout_compatible (const function_type, const function_type), " " );
1740+ // expected-warning@-1 {{'const' qualifier on function type 'function_type' (aka 'void ()') has no effect}}
1741+ // expected-warning@-2 {{'const' qualifier on function type 'function_type' (aka 'void ()') has no effect}}
1742+ static_assert (__is_layout_compatible (function_type, const function_type), " " );
1743+ // expected-warning@-1 {{'const' qualifier on function type 'function_type' (aka 'void ()') has no effect}}
1744+ static_assert (!__is_layout_compatible (const function_type, const function_type2), " " );
1745+ // expected-warning@-1 {{'const' qualifier on function type 'function_type' (aka 'void ()') has no effect}}
1746+ // expected-warning@-2 {{'const' qualifier on function type 'function_type2' (aka 'void (char)') has no effect}}
1747+ static_assert (__is_layout_compatible (CStruct, CStruct2), " " );
1748+ static_assert (__is_layout_compatible (CStruct, const CStruct2), " " );
1749+ static_assert (__is_layout_compatible (CStruct, volatile CStruct2), " " );
1750+ static_assert (__is_layout_compatible (const CStruct, volatile CStruct2), " " );
1751+ static_assert (__is_layout_compatible (CEmptyStruct, CEmptyStruct2), " " );
1752+ static_assert (__is_layout_compatible (CppEmptyStruct, CppEmptyStruct2), " " );
1753+ static_assert (__is_layout_compatible (CppStructStandard, CppStructStandard2), " " );
1754+ static_assert (!__is_layout_compatible (CppStructNonStandardByBase, CppStructNonStandardByBase2), " " );
1755+ static_assert (!__is_layout_compatible (CppStructNonStandardByVirt, CppStructNonStandardByVirt2), " " );
1756+ static_assert (!__is_layout_compatible (CppStructNonStandardByMemb, CppStructNonStandardByMemb2), " " );
1757+ static_assert (!__is_layout_compatible (CppStructNonStandardByProt, CppStructNonStandardByProt2), " " );
1758+ static_assert (!__is_layout_compatible (CppStructNonStandardByVirtBase, CppStructNonStandardByVirtBase2), " " );
1759+ static_assert (!__is_layout_compatible (CppStructNonStandardBySameBase, CppStructNonStandardBySameBase2), " " );
1760+ static_assert (!__is_layout_compatible (CppStructNonStandardBy2ndVirtBase, CppStructNonStandardBy2ndVirtBase2), " " );
1761+ static_assert (!__is_layout_compatible (CStruct, CStructWithQualifiers), " " ); // FIXME: this is CWG1719
1762+ static_assert (__is_layout_compatible (CStruct, CStructNoUniqueAddress) == bool (__has_cpp_attribute (no_unique_address)), " " ); // FIXME: this is CWG2759
1763+ static_assert (__is_layout_compatible (CStructNoUniqueAddress, CStructNoUniqueAddress2) == bool (__has_cpp_attribute (no_unique_address)), " " ); // FIXME: this is CWG2759
1764+ static_assert (__is_layout_compatible (CStruct, CStructAlignment), " " );
1765+ static_assert (__is_layout_compatible (CStructWithBitfelds, CStructWithBitfelds), " " );
1766+ static_assert (__is_layout_compatible (CStructWithBitfelds, CStructWithBitfelds2), " " );
1767+ static_assert (!__is_layout_compatible (CStructWithBitfelds, CStructWithBitfelds3), " " );
1768+ static_assert (!__is_layout_compatible (CStructWithBitfelds, CStructWithBitfelds4), " " );
1769+ static_assert (__is_layout_compatible (int CStruct2::*, int CStruct2::*), " " );
1770+ static_assert (!__is_layout_compatible (int CStruct2::*, char CStruct2::*), " " );
1771+ static_assert (__is_layout_compatible (void (CStruct2::*)(int ), void (CStruct2::*)(int )), " " );
1772+ static_assert (!__is_layout_compatible (void (CStruct2::*)(int ), void (CStruct2::*)(char )), " " );
1773+ static_assert (__is_layout_compatible (CStructNested, CStructNested2), " " );
1774+ static_assert (__is_layout_compatible (UnionLayout, UnionLayout), " " );
1775+ static_assert (__is_layout_compatible (UnionLayout, UnionLayout2), " " );
1776+ static_assert (!__is_layout_compatible (UnionLayout, UnionLayout3), " " );
1777+ static_assert (__is_layout_compatible (StructWithAnonUnion, StructWithAnonUnion2), " " );
1778+ static_assert (__is_layout_compatible (StructWithAnonUnion, StructWithAnonUnion3), " " );
1779+ static_assert (__is_layout_compatible (EnumLayout, EnumClassLayout), " " );
1780+ static_assert (__is_layout_compatible (EnumForward, EnumForward), " " );
1781+ static_assert (__is_layout_compatible (EnumForward, EnumClassForward), " " );
1782+ // Layout compatibility for enums might be relaxed in the future. See https://github.com/cplusplus/CWG/issues/39#issuecomment-1184791364
1783+ static_assert (!__is_layout_compatible (EnumLayout, int ), " " );
1784+ static_assert (!__is_layout_compatible (EnumClassLayout, int ), " " );
1785+ static_assert (!__is_layout_compatible (EnumForward, int ), " " );
1786+ static_assert (!__is_layout_compatible (EnumClassForward, int ), " " );
1787+ // FIXME: the following should be rejected (array of unknown bound and void are the only allowed incomplete types)
1788+ static_assert (__is_layout_compatible (CStructIncomplete, CStructIncomplete), " " );
1789+ static_assert (!__is_layout_compatible (CStruct, CStructIncomplete), " " );
1790+ static_assert (__is_layout_compatible (CStructIncomplete[2 ], CStructIncomplete[2 ]), " " );
1791+ }
1792+
15611793void is_signed ()
15621794{
15631795 // int t01[T(__is_signed(char))];
0 commit comments