-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[clang] Implement CWG2759 "[[no_unique_address]
and common initial sequence"
#82607
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…sequence" This patch implements said defect report resolution by adding additional check to common initial sequence evaluation. Consequently, this fixes CWG2759. No special handling of `[[msvc::no_unique_address]]` is performed, so it should follow `[[no_unique_address]]` behavior.
@llvm/pr-subscribers-clang Author: Vlad Serebrennikov (Endilll) ChangesThis patch implements said defect report resolution by adding additional check to common initial sequence evaluation. Consequently, this fixes CWG2759. No special handling of Full diff: https://github.com/llvm/llvm-project/pull/82607.diff 5 Files Affected:
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index bac166e6c35627..a7c0f2fbbe7604 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -83,8 +83,6 @@ C++20 Feature Support
- Implemented the `__is_layout_compatible` intrinsic to support
`P0466R5: Layout-compatibility and Pointer-interconvertibility Traits <https://wg21.link/P0466R5>`_.
- 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
^^^^^^^^^^^^^^^^^^^^^
@@ -108,6 +106,10 @@ Resolutions to C++ Defect Reports
of two types.
(`CWG1719: Layout compatibility and cv-qualification revisited <https://cplusplus.github.io/CWG/issues/1719.html>`_).
+- ``[[no_unique_address]]`` is now respected when evaluating layout
+ compatibility of two types.
+ (`CWG2759: [[no_unique_address] and common initial sequence <https://cplusplus.github.io/CWG/issues/2759.html>`_).
+
C Language Changes
------------------
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index e8bfb215a5b4c5..aba8852f6cfca4 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -19033,6 +19033,11 @@ static bool isLayoutCompatible(ASTContext &C, FieldDecl *Field1,
return false;
}
+ if (Field1->hasAttr<clang::NoUniqueAddressAttr>() ||
+ Field2->hasAttr<clang::NoUniqueAddressAttr>()) {
+ return false;
+ }
+
return true;
}
diff --git a/clang/test/CXX/drs/dr27xx.cpp b/clang/test/CXX/drs/dr27xx.cpp
index dd3fd5a20163fa..3fdf384bef27a7 100644
--- a/clang/test/CXX/drs/dr27xx.cpp
+++ b/clang/test/CXX/drs/dr27xx.cpp
@@ -10,6 +10,89 @@
// expected-no-diagnostics
#endif
+namespace dr2759 { // dr2759: 19
+#if __cplusplus >= 201103L
+
+struct CStruct {
+ int one;
+ int two;
+};
+
+struct CEmptyStruct {};
+struct CEmptyStruct2 {};
+
+struct CStructNoUniqueAddress {
+ int one;
+ [[no_unique_address]] int two;
+};
+
+struct CStructNoUniqueAddress2 {
+ int one;
+ [[no_unique_address]] int two;
+};
+
+union UnionLayout {
+ int a;
+ double b;
+ CStruct c;
+ [[no_unique_address]] CEmptyStruct d;
+ [[no_unique_address]] CEmptyStruct2 e;
+};
+
+union UnionLayout2 {
+ CStruct c;
+ int a;
+ CEmptyStruct2 e;
+ double b;
+ [[no_unique_address]] CEmptyStruct d;
+};
+
+union UnionLayout3 {
+ CStruct c;
+ int a;
+ double b;
+ [[no_unique_address]] CEmptyStruct d;
+};
+
+struct StructWithAnonUnion {
+ union {
+ int a;
+ double b;
+ CStruct c;
+ [[no_unique_address]] CEmptyStruct d;
+ [[no_unique_address]] CEmptyStruct2 e;
+ };
+};
+
+struct StructWithAnonUnion2 {
+ union {
+ CStruct c;
+ int a;
+ CEmptyStruct2 e;
+ double b;
+ [[no_unique_address]] CEmptyStruct d;
+ };
+};
+
+struct StructWithAnonUnion3 {
+ union {
+ CStruct c;
+ int a;
+ CEmptyStruct2 e;
+ double b;
+ [[no_unique_address]] CEmptyStruct d;
+ } u;
+};
+
+static_assert(__is_layout_compatible(CStruct, CStructNoUniqueAddress) != bool(__has_cpp_attribute(no_unique_address)), "");
+static_assert(__is_layout_compatible(CStructNoUniqueAddress, CStructNoUniqueAddress2) != bool(__has_cpp_attribute(no_unique_address)), "");
+static_assert(!__is_layout_compatible(UnionLayout, UnionLayout2), "");
+static_assert(!__is_layout_compatible(UnionLayout, UnionLayout3), "");
+static_assert(!__is_layout_compatible(StructWithAnonUnion, StructWithAnonUnion2), "");
+static_assert(!__is_layout_compatible(StructWithAnonUnion, StructWithAnonUnion3), "");
+#endif
+} // namespace dr2759
+
namespace dr2789 { // dr2789: 18
#if __cplusplus >= 202302L
template <typename T = int>
diff --git a/clang/test/SemaCXX/type-traits.cpp b/clang/test/SemaCXX/type-traits.cpp
index 2c35d5ee19a4c6..23c339ebdf0826 100644
--- a/clang/test/SemaCXX/type-traits.cpp
+++ b/clang/test/SemaCXX/type-traits.cpp
@@ -1768,8 +1768,8 @@ void is_layout_compatible(int n)
static_assert(!__is_layout_compatible(CppStructNonStandardBySameBase, CppStructNonStandardBySameBase2), "");
static_assert(!__is_layout_compatible(CppStructNonStandardBy2ndVirtBase, CppStructNonStandardBy2ndVirtBase2), "");
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, CStructNoUniqueAddress) != bool(__has_cpp_attribute(no_unique_address)), "");
+ static_assert(__is_layout_compatible(CStructNoUniqueAddress, CStructNoUniqueAddress2) != bool(__has_cpp_attribute(no_unique_address)), "");
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), "");
@@ -1782,10 +1782,10 @@ void is_layout_compatible(int n)
static_assert(!__is_layout_compatible(void(CStruct2::*)(int), void(CStruct2::*)(char)), "");
static_assert(__is_layout_compatible(CStructNested, CStructNested2), "");
static_assert(__is_layout_compatible(UnionLayout, UnionLayout), "");
- static_assert(__is_layout_compatible(UnionLayout, UnionLayout2), "");
+ static_assert(!__is_layout_compatible(UnionLayout, UnionLayout2), "");
static_assert(!__is_layout_compatible(UnionLayout, UnionLayout3), "");
- static_assert(__is_layout_compatible(StructWithAnonUnion, StructWithAnonUnion2), "");
- static_assert(__is_layout_compatible(StructWithAnonUnion, StructWithAnonUnion3), "");
+ static_assert(!__is_layout_compatible(StructWithAnonUnion, StructWithAnonUnion2), "");
+ static_assert(!__is_layout_compatible(StructWithAnonUnion, StructWithAnonUnion3), "");
static_assert(__is_layout_compatible(EnumLayout, EnumClassLayout), "");
static_assert(__is_layout_compatible(EnumForward, EnumForward), "");
static_assert(__is_layout_compatible(EnumForward, EnumClassForward), "");
diff --git a/clang/www/cxx_dr_status.html b/clang/www/cxx_dr_status.html
index 38e2cb63142662..8b638e06f4aab6 100755
--- a/clang/www/cxx_dr_status.html
+++ b/clang/www/cxx_dr_status.html
@@ -16362,7 +16362,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2>
<td><a href="https://cplusplus.github.io/CWG/issues/2759.html">2759</a></td>
<td>DR</td>
<td>[[no_unique_address] and common initial sequence</td>
- <td class="unknown" align="center">Unknown</td>
+ <td class="unreleased" align="center">Clang 19</td>
</tr>
<tr id="2760">
<td><a href="https://cplusplus.github.io/CWG/issues/2760.html">2760</a></td>
|
I do not think the code does that. At the very least, a type with msvc::no_unique_address should not be layout compatible with an equivalent declaration using no_unique_address. Whether two msvc::no_unique_address are layout compatible is less important, because the intent of msvc::no_unique_address is not documented and/or msvc does not implement CWG2759 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, Thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM modulo formatting nits
Co-authored-by: Timm Baeder <[email protected]>
✅ With the latest revision this PR passed the C/C++ code formatter. |
This patch implements said defect report resolution by adding additional check to common initial sequence evaluation. Consequently, this fixes CWG2759.
No special handling of
[[msvc::no_unique_address]]
is performed, so it should follow[[no_unique_address]]
behavior.