Skip to content

Commit 7318585

Browse files
authored
[clang] Implement CWG1719 "Layout compatibility and cv-qualification revisited" (#82358)
This patch updates our internal notion of `layout-compatible` to ignore cv-qualification, which in turn fixes `__is_layout_compatible` intrinsic.
1 parent 5a023f5 commit 7318585

File tree

5 files changed

+39
-25
lines changed

5 files changed

+39
-25
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,9 +98,8 @@ C++20 Feature Support
9898

9999
- Implemented the `__is_layout_compatible` intrinsic to support
100100
`P0466R5: Layout-compatibility and Pointer-interconvertibility Traits <https://wg21.link/P0466R5>`_.
101-
Note: `CWG1719: Layout compatibility and cv-qualification revisited <https://cplusplus.github.io/CWG/issues/1719.html>`_
102-
and `CWG2759: [[no_unique_address] and common initial sequence <https://cplusplus.github.io/CWG/issues/2759.html>`_
103-
are not yet implemented.
101+
Note: `CWG2759: [[no_unique_address] and common initial sequence <https://cplusplus.github.io/CWG/issues/2759.html>`_
102+
is not yet implemented.
104103

105104
C++23 Feature Support
106105
^^^^^^^^^^^^^^^^^^^^^
@@ -120,6 +119,10 @@ Resolutions to C++ Defect Reports
120119
in the template parameters, but is deduced from a previous argument.
121120
(`#78449: <https://github.com/llvm/llvm-project/issues/78449>`_).
122121

122+
- Type qualifications are now ignored when evaluating layout compatibility
123+
of two types.
124+
(`CWG1719: Layout compatibility and cv-qualification revisited <https://cplusplus.github.io/CWG/issues/1719.html>`_).
125+
123126
C Language Changes
124127
------------------
125128

clang/lib/Sema/SemaChecking.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19124,15 +19124,16 @@ static bool isLayoutCompatible(ASTContext &C, QualType T1, QualType T2) {
1912419124
if (T1.isNull() || T2.isNull())
1912519125
return false;
1912619126

19127-
// C++11 [basic.types] p11:
19128-
// If two types T1 and T2 are the same type, then T1 and T2 are
19129-
// layout-compatible types.
19130-
if (C.hasSameType(T1, T2))
19131-
return true;
19132-
19127+
// C++20 [basic.types] p11:
19128+
// Two types cv1 T1 and cv2 T2 are layout-compatible types
19129+
// if T1 and T2 are the same type, layout-compatible enumerations (9.7.1),
19130+
// or layout-compatible standard-layout class types (11.4).
1913319131
T1 = T1.getCanonicalType().getUnqualifiedType();
1913419132
T2 = T2.getCanonicalType().getUnqualifiedType();
1913519133

19134+
if (C.hasSameType(T1, T2))
19135+
return true;
19136+
1913619137
const Type::TypeClass TC1 = T1->getTypeClass();
1913719138
const Type::TypeClass TC2 = T2->getTypeClass();
1913819139

clang/test/CXX/drs/dr17xx.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ namespace dr1715 { // dr1715: 3.9
4646
#endif
4747
}
4848

49-
namespace dr1719 { // dr1719: no
49+
namespace dr1719 { // dr1719: 19
5050
#if __cplusplus >= 201103L
5151
struct CStruct {
5252
int one;
@@ -66,11 +66,11 @@ struct CStructWithQualifiers {
6666
static_assert(__is_layout_compatible(CStruct, const CStruct2), "");
6767
static_assert(__is_layout_compatible(CStruct, volatile CStruct2), "");
6868
static_assert(__is_layout_compatible(const CStruct, volatile CStruct2), "");
69-
// FIXME: all of the following pairs of types are layout-compatible
70-
static_assert(!__is_layout_compatible(int, const int), "");
71-
static_assert(!__is_layout_compatible(int, volatile int), "");
72-
static_assert(!__is_layout_compatible(const int, volatile int), "");
73-
static_assert(!__is_layout_compatible(CStruct, CStructWithQualifiers), "");
69+
static_assert(__is_layout_compatible(int, const int), "");
70+
static_assert(__is_layout_compatible(int, volatile int), "");
71+
static_assert(__is_layout_compatible(const int, volatile int), "");
72+
static_assert(__is_layout_compatible(CStruct, CStructWithQualifiers), "");
73+
static_assert(__is_layout_compatible(int[], const volatile int[]), "");
7474
#endif
7575
} // namespace dr1719
7676

clang/test/SemaCXX/type-traits.cpp

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1609,7 +1609,12 @@ struct CStructNoUniqueAddress2 {
16091609
[[no_unique_address]] int two;
16101610
};
16111611

1612-
struct CStructAlignment {
1612+
struct alignas(64) CStructAlignment {
1613+
int one;
1614+
int two;
1615+
};
1616+
1617+
struct CStructAlignedMembers {
16131618
int one;
16141619
alignas(16) int two;
16151620
};
@@ -1711,13 +1716,17 @@ void is_layout_compatible(int n)
17111716
{
17121717
static_assert(__is_layout_compatible(void, void), "");
17131718
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
1719+
static_assert(__is_layout_compatible(void, const void), "");
1720+
static_assert(__is_layout_compatible(void, volatile void), "");
1721+
static_assert(__is_layout_compatible(const int, volatile int), "");
17171722
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
1723+
static_assert(__is_layout_compatible(int, const int), "");
1724+
static_assert(__is_layout_compatible(int, volatile int), "");
1725+
static_assert(__is_layout_compatible(const int, volatile int), "");
1726+
static_assert(__is_layout_compatible(int *, int * __restrict), "");
1727+
// Note: atomic qualification matters for layout compatibility.
1728+
static_assert(!__is_layout_compatible(int, _Atomic int), "");
1729+
static_assert(__is_layout_compatible(_Atomic(int), _Atomic int), "");
17211730
static_assert(!__is_layout_compatible(int, unsigned int), "");
17221731
static_assert(!__is_layout_compatible(char, unsigned char), "");
17231732
static_assert(!__is_layout_compatible(char, signed char), "");
@@ -1758,10 +1767,11 @@ void is_layout_compatible(int n)
17581767
static_assert(!__is_layout_compatible(CppStructNonStandardByVirtBase, CppStructNonStandardByVirtBase2), "");
17591768
static_assert(!__is_layout_compatible(CppStructNonStandardBySameBase, CppStructNonStandardBySameBase2), "");
17601769
static_assert(!__is_layout_compatible(CppStructNonStandardBy2ndVirtBase, CppStructNonStandardBy2ndVirtBase2), "");
1761-
static_assert(!__is_layout_compatible(CStruct, CStructWithQualifiers), ""); // FIXME: this is CWG1719
1770+
static_assert(__is_layout_compatible(CStruct, CStructWithQualifiers), "");
17621771
static_assert(__is_layout_compatible(CStruct, CStructNoUniqueAddress) == bool(__has_cpp_attribute(no_unique_address)), ""); // FIXME: this is CWG2759
17631772
static_assert(__is_layout_compatible(CStructNoUniqueAddress, CStructNoUniqueAddress2) == bool(__has_cpp_attribute(no_unique_address)), ""); // FIXME: this is CWG2759
17641773
static_assert(__is_layout_compatible(CStruct, CStructAlignment), "");
1774+
static_assert(__is_layout_compatible(CStruct, CStructAlignedMembers), ""); // FIXME: alignment of members impact common initial sequence
17651775
static_assert(__is_layout_compatible(CStructWithBitfelds, CStructWithBitfelds), "");
17661776
static_assert(__is_layout_compatible(CStructWithBitfelds, CStructWithBitfelds2), "");
17671777
static_assert(!__is_layout_compatible(CStructWithBitfelds, CStructWithBitfelds3), "");

clang/www/cxx_dr_status.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7812,7 +7812,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2>
78127812
<td><a href="https://cplusplus.github.io/CWG/issues/1334.html">1334</a></td>
78137813
<td>NAD</td>
78147814
<td>Layout compatibility and cv-qualification</td>
7815-
<td class="unknown" align="center">Unknown</td>
7815+
<td class="unreleased" align="center">Superseded by <a href="#1719">1719</a></td>
78167816
</tr>
78177817
<tr id="1335">
78187818
<td><a href="https://cplusplus.github.io/CWG/issues/1335.html">1335</a></td>
@@ -10122,7 +10122,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2>
1012210122
<td><a href="https://cplusplus.github.io/CWG/issues/1719.html">1719</a></td>
1012310123
<td>CD4</td>
1012410124
<td>Layout compatibility and cv-qualification revisited</td>
10125-
<td class="unknown" align="center">Unknown</td>
10125+
<td class="unreleased" align="center">Clang 19</td>
1012610126
</tr>
1012710127
<tr id="1720">
1012810128
<td><a href="https://cplusplus.github.io/CWG/issues/1720.html">1720</a></td>

0 commit comments

Comments
 (0)