mirror of
https://github.com/intel/llvm.git
synced 2026-01-20 01:58:44 +08:00
[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.
This commit is contained in:
committed by
GitHub
parent
5a023f564f
commit
73185854a3
@@ -98,9 +98,8 @@ C++20 Feature Support
|
||||
|
||||
- Implemented the `__is_layout_compatible` intrinsic to support
|
||||
`P0466R5: Layout-compatibility and Pointer-interconvertibility Traits <https://wg21.link/P0466R5>`_.
|
||||
Note: `CWG1719: Layout compatibility and cv-qualification revisited <https://cplusplus.github.io/CWG/issues/1719.html>`_
|
||||
and `CWG2759: [[no_unique_address] and common initial sequence <https://cplusplus.github.io/CWG/issues/2759.html>`_
|
||||
are not yet implemented.
|
||||
Note: `CWG2759: [[no_unique_address] and common initial sequence <https://cplusplus.github.io/CWG/issues/2759.html>`_
|
||||
is not yet implemented.
|
||||
|
||||
C++23 Feature Support
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
@@ -120,6 +119,10 @@ Resolutions to C++ Defect Reports
|
||||
in the template parameters, but is deduced from a previous argument.
|
||||
(`#78449: <https://github.com/llvm/llvm-project/issues/78449>`_).
|
||||
|
||||
- Type qualifications are now ignored when evaluating layout compatibility
|
||||
of two types.
|
||||
(`CWG1719: Layout compatibility and cv-qualification revisited <https://cplusplus.github.io/CWG/issues/1719.html>`_).
|
||||
|
||||
C Language Changes
|
||||
------------------
|
||||
|
||||
|
||||
@@ -19124,15 +19124,16 @@ static bool isLayoutCompatible(ASTContext &C, QualType T1, QualType T2) {
|
||||
if (T1.isNull() || T2.isNull())
|
||||
return false;
|
||||
|
||||
// C++11 [basic.types] p11:
|
||||
// If two types T1 and T2 are the same type, then T1 and T2 are
|
||||
// layout-compatible types.
|
||||
if (C.hasSameType(T1, T2))
|
||||
return true;
|
||||
|
||||
// C++20 [basic.types] p11:
|
||||
// Two types cv1 T1 and cv2 T2 are layout-compatible types
|
||||
// if T1 and T2 are the same type, layout-compatible enumerations (9.7.1),
|
||||
// or layout-compatible standard-layout class types (11.4).
|
||||
T1 = T1.getCanonicalType().getUnqualifiedType();
|
||||
T2 = T2.getCanonicalType().getUnqualifiedType();
|
||||
|
||||
if (C.hasSameType(T1, T2))
|
||||
return true;
|
||||
|
||||
const Type::TypeClass TC1 = T1->getTypeClass();
|
||||
const Type::TypeClass TC2 = T2->getTypeClass();
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ namespace dr1715 { // dr1715: 3.9
|
||||
#endif
|
||||
}
|
||||
|
||||
namespace dr1719 { // dr1719: no
|
||||
namespace dr1719 { // dr1719: 19
|
||||
#if __cplusplus >= 201103L
|
||||
struct CStruct {
|
||||
int one;
|
||||
@@ -66,11 +66,11 @@ struct CStructWithQualifiers {
|
||||
static_assert(__is_layout_compatible(CStruct, const CStruct2), "");
|
||||
static_assert(__is_layout_compatible(CStruct, volatile CStruct2), "");
|
||||
static_assert(__is_layout_compatible(const CStruct, volatile CStruct2), "");
|
||||
// FIXME: all of the following pairs of types are layout-compatible
|
||||
static_assert(!__is_layout_compatible(int, const int), "");
|
||||
static_assert(!__is_layout_compatible(int, volatile int), "");
|
||||
static_assert(!__is_layout_compatible(const int, volatile int), "");
|
||||
static_assert(!__is_layout_compatible(CStruct, CStructWithQualifiers), "");
|
||||
static_assert(__is_layout_compatible(int, const int), "");
|
||||
static_assert(__is_layout_compatible(int, volatile int), "");
|
||||
static_assert(__is_layout_compatible(const int, volatile int), "");
|
||||
static_assert(__is_layout_compatible(CStruct, CStructWithQualifiers), "");
|
||||
static_assert(__is_layout_compatible(int[], const volatile int[]), "");
|
||||
#endif
|
||||
} // namespace dr1719
|
||||
|
||||
|
||||
@@ -1609,7 +1609,12 @@ struct CStructNoUniqueAddress2 {
|
||||
[[no_unique_address]] int two;
|
||||
};
|
||||
|
||||
struct CStructAlignment {
|
||||
struct alignas(64) CStructAlignment {
|
||||
int one;
|
||||
int two;
|
||||
};
|
||||
|
||||
struct CStructAlignedMembers {
|
||||
int one;
|
||||
alignas(16) int two;
|
||||
};
|
||||
@@ -1711,13 +1716,17 @@ void is_layout_compatible(int n)
|
||||
{
|
||||
static_assert(__is_layout_compatible(void, void), "");
|
||||
static_assert(!__is_layout_compatible(void, int), "");
|
||||
static_assert(!__is_layout_compatible(void, const void), ""); // FIXME: this is CWG1719
|
||||
static_assert(!__is_layout_compatible(void, volatile void), ""); // FIXME: this is CWG1719
|
||||
static_assert(!__is_layout_compatible(const int, volatile int), ""); // FIXME: this is CWG1719
|
||||
static_assert(__is_layout_compatible(void, const void), "");
|
||||
static_assert(__is_layout_compatible(void, volatile void), "");
|
||||
static_assert(__is_layout_compatible(const int, volatile int), "");
|
||||
static_assert(__is_layout_compatible(int, int), "");
|
||||
static_assert(!__is_layout_compatible(int, const int), ""); // FIXME: this is CWG1719
|
||||
static_assert(!__is_layout_compatible(int, volatile int), ""); // FIXME: this is CWG1719
|
||||
static_assert(!__is_layout_compatible(const int, volatile int), ""); // FIXME: this is CWG1719
|
||||
static_assert(__is_layout_compatible(int, const int), "");
|
||||
static_assert(__is_layout_compatible(int, volatile int), "");
|
||||
static_assert(__is_layout_compatible(const int, volatile int), "");
|
||||
static_assert(__is_layout_compatible(int *, int * __restrict), "");
|
||||
// Note: atomic qualification matters for layout compatibility.
|
||||
static_assert(!__is_layout_compatible(int, _Atomic int), "");
|
||||
static_assert(__is_layout_compatible(_Atomic(int), _Atomic int), "");
|
||||
static_assert(!__is_layout_compatible(int, unsigned int), "");
|
||||
static_assert(!__is_layout_compatible(char, unsigned char), "");
|
||||
static_assert(!__is_layout_compatible(char, signed char), "");
|
||||
@@ -1758,10 +1767,11 @@ void is_layout_compatible(int n)
|
||||
static_assert(!__is_layout_compatible(CppStructNonStandardByVirtBase, CppStructNonStandardByVirtBase2), "");
|
||||
static_assert(!__is_layout_compatible(CppStructNonStandardBySameBase, CppStructNonStandardBySameBase2), "");
|
||||
static_assert(!__is_layout_compatible(CppStructNonStandardBy2ndVirtBase, CppStructNonStandardBy2ndVirtBase2), "");
|
||||
static_assert(!__is_layout_compatible(CStruct, CStructWithQualifiers), ""); // FIXME: this is CWG1719
|
||||
static_assert(__is_layout_compatible(CStruct, CStructWithQualifiers), "");
|
||||
static_assert(__is_layout_compatible(CStruct, CStructNoUniqueAddress) == bool(__has_cpp_attribute(no_unique_address)), ""); // FIXME: this is CWG2759
|
||||
static_assert(__is_layout_compatible(CStructNoUniqueAddress, CStructNoUniqueAddress2) == bool(__has_cpp_attribute(no_unique_address)), ""); // FIXME: this is CWG2759
|
||||
static_assert(__is_layout_compatible(CStruct, CStructAlignment), "");
|
||||
static_assert(__is_layout_compatible(CStruct, CStructAlignedMembers), ""); // FIXME: alignment of members impact common initial sequence
|
||||
static_assert(__is_layout_compatible(CStructWithBitfelds, CStructWithBitfelds), "");
|
||||
static_assert(__is_layout_compatible(CStructWithBitfelds, CStructWithBitfelds2), "");
|
||||
static_assert(!__is_layout_compatible(CStructWithBitfelds, CStructWithBitfelds3), "");
|
||||
|
||||
@@ -7812,7 +7812,7 @@ and <I>POD class</I></td>
|
||||
<td><a href="https://cplusplus.github.io/CWG/issues/1334.html">1334</a></td>
|
||||
<td>NAD</td>
|
||||
<td>Layout compatibility and cv-qualification</td>
|
||||
<td class="unknown" align="center">Unknown</td>
|
||||
<td class="unreleased" align="center">Superseded by <a href="#1719">1719</a></td>
|
||||
</tr>
|
||||
<tr id="1335">
|
||||
<td><a href="https://cplusplus.github.io/CWG/issues/1335.html">1335</a></td>
|
||||
@@ -10122,7 +10122,7 @@ and <I>POD class</I></td>
|
||||
<td><a href="https://cplusplus.github.io/CWG/issues/1719.html">1719</a></td>
|
||||
<td>CD4</td>
|
||||
<td>Layout compatibility and cv-qualification revisited</td>
|
||||
<td class="unknown" align="center">Unknown</td>
|
||||
<td class="unreleased" align="center">Clang 19</td>
|
||||
</tr>
|
||||
<tr id="1720">
|
||||
<td><a href="https://cplusplus.github.io/CWG/issues/1720.html">1720</a></td>
|
||||
|
||||
Reference in New Issue
Block a user