@@ -1558,6 +1558,238 @@ void is_standard_layout()
1558
1558
int t71[F (__is_standard_layout (HasEmptyIndirectBaseAsSecondUnionMember))];
1559
1559
}
1560
1560
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
+
1561
1793
void is_signed ()
1562
1794
{
1563
1795
// int t01[T(__is_signed(char))];
0 commit comments