https://github.com/Endilll updated https://github.com/llvm/llvm-project/pull/82607
>From 22facf44ec3f97fcdc40f2431ec26ca7ef441c67 Mon Sep 17 00:00:00 2001 From: Vlad Serebrennikov <serebrennikov.vladis...@gmail.com> Date: Thu, 22 Feb 2024 13:28:04 +0300 Subject: [PATCH 1/2] [clang] Implement CWG2759 "`[[no_unique_address]` and common initial 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. --- clang/docs/ReleaseNotes.rst | 6 ++- clang/lib/Sema/SemaChecking.cpp | 5 ++ clang/test/CXX/drs/dr27xx.cpp | 83 ++++++++++++++++++++++++++++++ clang/test/SemaCXX/type-traits.cpp | 10 ++-- clang/www/cxx_dr_status.html | 2 +- 5 files changed, 98 insertions(+), 8 deletions(-) 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> >From 71685015f7121dc3a4d9b5d1b3c783b0cc18d30d Mon Sep 17 00:00:00 2001 From: Vlad Serebrennikov <serebrennikov.vladis...@gmail.com> Date: Thu, 22 Feb 2024 14:00:16 +0300 Subject: [PATCH 2/2] Add tests for `[[msvc::no_unique_address]]` --- .../SemaCXX/cxx2a-ms-no-unique-address.cpp | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/clang/test/SemaCXX/cxx2a-ms-no-unique-address.cpp b/clang/test/SemaCXX/cxx2a-ms-no-unique-address.cpp index 42058559a087a5..8c0d3294fd5810 100644 --- a/clang/test/SemaCXX/cxx2a-ms-no-unique-address.cpp +++ b/clang/test/SemaCXX/cxx2a-ms-no-unique-address.cpp @@ -17,3 +17,26 @@ struct [[msvc::no_unique_address]] S { // expected-error {{only applies to non-b int [[msvc::no_unique_address]] c; // expected-error {{cannot be applied to types}} unsupported-error {{cannot be applied to types}} }; + +struct CStructNoUniqueAddress { + int one; + [[no_unique_address]] int two; +}; + +struct CStructMSVCNoUniqueAddress { + int one; + [[msvc::no_unique_address]] int two; + // unsupported-warning@-1 {{unknown attribute 'no_unique_address' ignored}} +}; + +struct CStructMSVCNoUniqueAddress2 { + int one; + [[msvc::no_unique_address]] int two; + // unsupported-warning@-1 {{unknown attribute 'no_unique_address' ignored}} +}; + +static_assert(__has_cpp_attribute(no_unique_address) == 0); +// unsupported-error@-1 {{static assertion failed due to requirement '201803L == 0'}} +static_assert(!__is_layout_compatible(CStructNoUniqueAddress, CStructMSVCNoUniqueAddress), ""); +static_assert(__is_layout_compatible(CStructMSVCNoUniqueAddress, CStructMSVCNoUniqueAddress), ""); +static_assert(__is_layout_compatible(CStructMSVCNoUniqueAddress, CStructMSVCNoUniqueAddress2), ""); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits