[clang] Revert "Implement [[msvc::no_unique_address]] (#65675)" (PR #67198)
Amy Huang via cfe-commits
cfe-commits at lists.llvm.org
Fri Sep 22 14:38:49 PDT 2023
https://github.com/amykhuang created https://github.com/llvm/llvm-project/pull/67198
This reverts commit 4a55d426967b9c70f5dea7b3a389e11393a4f4c4.
Reverting because this breaks sphinx documentation, and even with it
fixed the format of the attribute makes the no_unique_address
documentation show up twice.
>From 159cc6b5d3cea0c4b51bd5dac7728a3cfa379f28 Mon Sep 17 00:00:00 2001
From: Amy Huang <akhuang at google.com>
Date: Fri, 22 Sep 2023 14:37:10 -0700
Subject: [PATCH] Revert "Implement [[msvc::no_unique_address]] (#65675)"
This reverts commit 4a55d426967b9c70f5dea7b3a389e11393a4f4c4.
Reverting because this breaks sphinx documentation, and even with it
fixed the format of the attribute makes the no_unique_address
documentation show up twice.
---
clang/include/clang/Basic/Attr.td | 19 +-
clang/include/clang/Basic/AttrDocs.td | 4 -
clang/lib/AST/Decl.cpp | 11 +-
clang/lib/AST/RecordLayoutBuilder.cpp | 53 +--
clang/lib/Parse/ParseDeclCXX.cpp | 3 +-
clang/lib/Sema/SemaDeclAttr.cpp | 10 -
clang/test/Layout/ms-no-unique-address.cpp | 381 ------------------
clang/test/Preprocessor/has_attribute.cpp | 5 +-
.../SemaCXX/cxx2a-ms-no-unique-address.cpp | 19 -
9 files changed, 16 insertions(+), 489 deletions(-)
delete mode 100644 clang/test/Layout/ms-no-unique-address.cpp
delete mode 100644 clang/test/SemaCXX/cxx2a-ms-no-unique-address.cpp
diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index bb8d204f33dc531..21a3b5226623cf2 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -1798,24 +1798,11 @@ def ArmMveStrictPolymorphism : TypeAttr, TargetSpecificAttr<TargetARM> {
let Documentation = [ArmMveStrictPolymorphismDocs];
}
-def NoUniqueAddress : InheritableAttr {
- let Subjects = SubjectList<[NonBitField], ErrorDiag>;
- // No spellings because instances of this attribute are created by
- // MSNoUniqueAddress and ItaniumNoUniqueAddress
- let Spellings = [];
- let Documentation = [NoUniqueAddressDocs];
-}
-
-def MSNoUniqueAddress : InheritableAttr, TargetSpecificAttr<TargetMicrosoftCXXABI> {
- let Subjects = SubjectList<[NonBitField], ErrorDiag>;
- let Spellings = [CXX11<"msvc", "no_unique_address", 201803>];
- let Documentation = [NoUniqueAddressDocs];
-}
-
-def ItaniumNoUniqueAddress : InheritableAttr, TargetSpecificAttr<TargetItaniumCXXABI> {
- let Subjects = SubjectList<[NonBitField], ErrorDiag>;
+def NoUniqueAddress : InheritableAttr, TargetSpecificAttr<TargetItaniumCXXABI> {
let Spellings = [CXX11<"", "no_unique_address", 201803>];
+ let Subjects = SubjectList<[NonBitField], ErrorDiag>;
let Documentation = [NoUniqueAddressDocs];
+ let SimpleHandler = 1;
}
def ReturnsTwice : InheritableAttr {
diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td
index 18428d26b5dc8f2..b13baa46754cfd4 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -1405,10 +1405,6 @@ Example usage:
``[[no_unique_address]]`` is a standard C++20 attribute. Clang supports its use
in C++11 onwards.
-
-On MSVC targets, ``[[no_unique_address]]`` is ignored; use
-``[[msvc::no_unique_address]]`` instead. Currently there is no guarantee of ABI
-compatibility or stability.
}];
}
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index 07aee0d87c835a8..08ae2087cfe70eb 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -4507,14 +4507,9 @@ bool FieldDecl::isZeroSize(const ASTContext &Ctx) const {
// Otherwise, [...] the circumstances under which the object has zero size
// are implementation-defined.
- if (!Ctx.getTargetInfo().getCXXABI().isMicrosoft())
- return true;
-
- // MS ABI: has nonzero size if it is a class type with class type fields,
- // whether or not they have nonzero size
- return !llvm::any_of(CXXRD->fields(), [](const FieldDecl *Field) {
- return Field->getType()->getAs<RecordType>();
- });
+ // FIXME: This might be Itanium ABI specific; we don't yet know what the MS
+ // ABI will do.
+ return true;
}
bool FieldDecl::isPotentiallyOverlapping() const {
diff --git a/clang/lib/AST/RecordLayoutBuilder.cpp b/clang/lib/AST/RecordLayoutBuilder.cpp
index f1f2275da44dcad..8afd88ae7be27b3 100644
--- a/clang/lib/AST/RecordLayoutBuilder.cpp
+++ b/clang/lib/AST/RecordLayoutBuilder.cpp
@@ -2545,10 +2545,7 @@ struct MicrosoftRecordLayoutBuilder {
CharUnits Alignment;
};
typedef llvm::DenseMap<const CXXRecordDecl *, CharUnits> BaseOffsetsMapTy;
- MicrosoftRecordLayoutBuilder(const ASTContext &Context,
- EmptySubobjectMap *EmptySubobjects)
- : Context(Context), EmptySubobjects(EmptySubobjects) {}
-
+ MicrosoftRecordLayoutBuilder(const ASTContext &Context) : Context(Context) {}
private:
MicrosoftRecordLayoutBuilder(const MicrosoftRecordLayoutBuilder &) = delete;
void operator=(const MicrosoftRecordLayoutBuilder &) = delete;
@@ -2598,8 +2595,6 @@ struct MicrosoftRecordLayoutBuilder {
llvm::SmallPtrSetImpl<const CXXRecordDecl *> &HasVtorDispSet,
const CXXRecordDecl *RD) const;
const ASTContext &Context;
- EmptySubobjectMap *EmptySubobjects;
-
/// The size of the record being laid out.
CharUnits Size;
/// The non-virtual size of the record layout.
@@ -2913,7 +2908,8 @@ static bool recordUsesEBO(const RecordDecl *RD) {
}
void MicrosoftRecordLayoutBuilder::layoutNonVirtualBase(
- const CXXRecordDecl *RD, const CXXRecordDecl *BaseDecl,
+ const CXXRecordDecl *RD,
+ const CXXRecordDecl *BaseDecl,
const ASTRecordLayout &BaseLayout,
const ASTRecordLayout *&PreviousBaseLayout) {
// Insert padding between two bases if the left first one is zero sized or
@@ -2946,7 +2942,6 @@ void MicrosoftRecordLayoutBuilder::layoutNonVirtualBase(
}
Bases.insert(std::make_pair(BaseDecl, BaseOffset));
Size += BaseLayout.getNonVirtualSize();
- DataSize = Size;
PreviousBaseLayout = &BaseLayout;
}
@@ -2964,43 +2959,15 @@ void MicrosoftRecordLayoutBuilder::layoutField(const FieldDecl *FD) {
LastFieldIsNonZeroWidthBitfield = false;
ElementInfo Info = getAdjustedElementInfo(FD);
Alignment = std::max(Alignment, Info.Alignment);
-
- const CXXRecordDecl *FieldClass = FD->getType()->getAsCXXRecordDecl();
- bool IsOverlappingEmptyField = FD->isPotentiallyOverlapping() &&
- FieldClass->isEmpty() &&
- FieldClass->fields().empty();
- CharUnits FieldOffset = CharUnits::Zero();
-
- if (UseExternalLayout) {
+ CharUnits FieldOffset;
+ if (UseExternalLayout)
FieldOffset =
Context.toCharUnitsFromBits(External.getExternalFieldOffset(FD));
- } else if (IsUnion) {
+ else if (IsUnion)
FieldOffset = CharUnits::Zero();
- } else if (EmptySubobjects) {
- if (!IsOverlappingEmptyField)
- FieldOffset = DataSize.alignTo(Info.Alignment);
-
- while (!EmptySubobjects->CanPlaceFieldAtOffset(FD, FieldOffset)) {
- const CXXRecordDecl *ParentClass = cast<CXXRecordDecl>(FD->getParent());
- bool HasBases = ParentClass && (!ParentClass->bases().empty() ||
- !ParentClass->vbases().empty());
- if (FieldOffset == CharUnits::Zero() && DataSize != CharUnits::Zero() &&
- HasBases) {
- // MSVC appears to only do this when there are base classes;
- // otherwise it overlaps no_unique_address fields in non-zero offsets.
- FieldOffset = DataSize.alignTo(Info.Alignment);
- } else {
- FieldOffset += Info.Alignment;
- }
- }
- } else {
+ else
FieldOffset = Size.alignTo(Info.Alignment);
- }
placeFieldAtOffset(FieldOffset);
-
- if (!IsOverlappingEmptyField)
- DataSize = std::max(DataSize, FieldOffset + Info.Size);
-
Size = std::max(Size, FieldOffset + Info.Size);
}
@@ -3046,7 +3013,6 @@ void MicrosoftRecordLayoutBuilder::layoutBitField(const FieldDecl *FD) {
Alignment = std::max(Alignment, Info.Alignment);
RemainingBitsInField = Context.toBits(Info.Size) - Width;
}
- DataSize = Size;
}
void
@@ -3072,7 +3038,6 @@ MicrosoftRecordLayoutBuilder::layoutZeroWidthBitField(const FieldDecl *FD) {
Size = FieldOffset;
Alignment = std::max(Alignment, Info.Alignment);
}
- DataSize = Size;
}
void MicrosoftRecordLayoutBuilder::injectVBPtr(const CXXRecordDecl *RD) {
@@ -3339,9 +3304,8 @@ ASTContext::getASTRecordLayout(const RecordDecl *D) const {
const ASTRecordLayout *NewEntry = nullptr;
if (isMsLayout(*this)) {
+ MicrosoftRecordLayoutBuilder Builder(*this);
if (const auto *RD = dyn_cast<CXXRecordDecl>(D)) {
- EmptySubobjectMap EmptySubobjects(*this, RD);
- MicrosoftRecordLayoutBuilder Builder(*this, &EmptySubobjects);
Builder.cxxLayout(RD);
NewEntry = new (*this) ASTRecordLayout(
*this, Builder.Size, Builder.Alignment, Builder.Alignment,
@@ -3353,7 +3317,6 @@ ASTContext::getASTRecordLayout(const RecordDecl *D) const {
Builder.EndsWithZeroSizedObject, Builder.LeadsWithZeroSizedBase,
Builder.Bases, Builder.VBases);
} else {
- MicrosoftRecordLayoutBuilder Builder(*this, /*EmptySubobjects=*/nullptr);
Builder.layout(D);
NewEntry = new (*this) ASTRecordLayout(
*this, Builder.Size, Builder.Alignment, Builder.Alignment,
diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp
index cc93fe7d5461967..5a6b5efbf6c1223 100644
--- a/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/clang/lib/Parse/ParseDeclCXX.cpp
@@ -4374,8 +4374,7 @@ static bool IsBuiltInOrStandardCXX11Attribute(IdentifierInfo *AttrName,
case ParsedAttr::AT_Deprecated:
case ParsedAttr::AT_FallThrough:
case ParsedAttr::AT_CXX11NoReturn:
- case ParsedAttr::AT_MSNoUniqueAddress:
- case ParsedAttr::AT_ItaniumNoUniqueAddress:
+ case ParsedAttr::AT_NoUniqueAddress:
case ParsedAttr::AT_Likely:
case ParsedAttr::AT_Unlikely:
return true;
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index f3839b2c59e0dcf..090a54eedaa07d0 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -8372,10 +8372,6 @@ static void handleNoMergeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
D->addAttr(NoMergeAttr::Create(S.Context, AL));
}
-static void handleNoUniqueAddressAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
- D->addAttr(NoUniqueAddressAttr::Create(S.Context, AL));
-}
-
static void handleSYCLKernelAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
// The 'sycl_kernel' attribute applies only to function templates.
const auto *FD = cast<FunctionDecl>(D);
@@ -9281,12 +9277,6 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL,
case ParsedAttr::AT_NoMerge:
handleNoMergeAttr(S, D, AL);
break;
- case ParsedAttr::AT_MSNoUniqueAddress:
- handleNoUniqueAddressAttr(S, D, AL);
- break;
- case ParsedAttr::AT_ItaniumNoUniqueAddress:
- handleNoUniqueAddressAttr(S, D, AL);
- break;
case ParsedAttr::AT_AvailableOnlyInDefaultEvalMethod:
handleAvailableOnlyInDefaultEvalMethod(S, D, AL);
diff --git a/clang/test/Layout/ms-no-unique-address.cpp b/clang/test/Layout/ms-no-unique-address.cpp
deleted file mode 100644
index 51cfd9a6ae3b77f..000000000000000
--- a/clang/test/Layout/ms-no-unique-address.cpp
+++ /dev/null
@@ -1,381 +0,0 @@
-// RUN: %clang_cc1 -std=c++2a -fsyntax-only -triple x86_64-windows-msvc -fms-compatibility -fdump-record-layouts %s | FileCheck %s
-
-namespace Empty {
- struct A {};
- struct A2 {};
- struct A3 { [[msvc::no_unique_address]] A a; };
- struct alignas(8) A4 {};
-
- struct B {
- [[msvc::no_unique_address]] A a;
- char b;
- };
- static_assert(sizeof(B) == 1);
-
- // CHECK:*** Dumping AST Record Layout
- // CHECK: 0 | struct Empty::B
- // CHECK-NEXT: 0 | struct Empty::A a (empty)
- // CHECK-NEXT: 0 | char b
- // CHECK-NEXT: | [sizeof=1, align=1,
- // CHECK-NEXT: | nvsize=1, nvalign=1]
-
- struct C {
- [[msvc::no_unique_address]] A a;
- [[msvc::no_unique_address]] A2 a2;
- char c;
- };
- static_assert(sizeof(C) == 1);
-
- // CHECK:*** Dumping AST Record Layout
- // CHECK: 0 | struct Empty::C
- // CHECK-NEXT: 0 | struct Empty::A a (empty)
- // CHECK-NEXT: 0 | struct Empty::A2 a2 (empty)
- // CHECK-NEXT: 0 | char c
- // CHECK-NEXT: | [sizeof=1, align=1,
- // CHECK-NEXT: | nvsize=1, nvalign=1]
-
- struct D {
- [[msvc::no_unique_address]] A3 a;
- int i;
- };
- static_assert(sizeof(D) == 8);
-
- // CHECK:*** Dumping AST Record Layout
- // CHECK: 0 | struct Empty::D
- // CHECK-NEXT: 0 | struct Empty::A3 a (empty)
- // CHECK-NEXT: 0 | struct Empty::A a (empty)
- // CHECK-NEXT: 4 | int i
- // CHECK-NEXT: | [sizeof=8, align=4,
- // CHECK-NEXT: | nvsize=8, nvalign=4]
-
- struct E {
- [[msvc::no_unique_address]] A a1;
- [[msvc::no_unique_address]] A a2;
- char e;
- };
- static_assert(sizeof(E) == 2);
-
- // CHECK:*** Dumping AST Record Layout
- // CHECK: 0 | struct Empty::E
- // CHECK-NEXT: 0 | struct Empty::A a1 (empty)
- // CHECK-NEXT: 1 | struct Empty::A a2 (empty)
- // CHECK-NEXT: 0 | char e
- // CHECK-NEXT: | [sizeof=2, align=1,
- // CHECK-NEXT: | nvsize=2, nvalign=1]
-
- struct F {
- ~F();
- [[msvc::no_unique_address]] A a1;
- [[msvc::no_unique_address]] A a2;
- char f;
- };
- static_assert(sizeof(F) == 2);
-
- // CHECK:*** Dumping AST Record Layout
- // CHECK: 0 | struct Empty::F
- // CHECK-NEXT: 0 | struct Empty::A a1 (empty)
- // CHECK-NEXT: 1 | struct Empty::A a2 (empty)
- // CHECK-NEXT: 0 | char f
- // CHECK-NEXT: | [sizeof=2, align=1,
- // CHECK-NEXT: | nvsize=2, nvalign=1]
-
- struct G { [[msvc::no_unique_address]] A a; ~G(); };
- static_assert(sizeof(G) == 1);
-
- // CHECK:*** Dumping AST Record Layout
- // CHECK: 0 | struct Empty::G
- // CHECK-NEXT: 0 | struct Empty::A a (empty)
- // CHECK-NEXT: | [sizeof=1, align=1,
- // CHECK-NEXT: | nvsize=1, nvalign=1]
-
- struct H {
- [[msvc::no_unique_address]] A a;
- [[msvc::no_unique_address]] A b;
- ~H();
- };
- static_assert(sizeof(H) == 2);
-
- // CHECK:*** Dumping AST Record Layout
- // CHECK: 0 | struct Empty::H
- // CHECK-NEXT: 0 | struct Empty::A a (empty)
- // CHECK-NEXT: 1 | struct Empty::A b (empty)
- // CHECK-NEXT: | [sizeof=2, align=1,
- // CHECK-NEXT: | nvsize=2, nvalign=1]
-
- struct I {
- [[msvc::no_unique_address]] A4 a;
- [[msvc::no_unique_address]] A4 b;
- };
- static_assert(sizeof(I) == 16);
-
- // CHECK:*** Dumping AST Record Layout
- // CHECK: 0 | struct Empty::I
- // CHECK-NEXT: 0 | struct Empty::A4 a (empty)
- // CHECK-NEXT: 8 | struct Empty::A4 b (empty)
- // CHECK-NEXT: | [sizeof=16, align=8,
- // CHECK-NEXT: | nvsize=16, nvalign=8]
-
- struct J {
- [[msvc::no_unique_address]] A4 a;
- A4 b;
- };
- static_assert(sizeof(J) == 16);
-
- // MSVC puts a and b at the same offset.
- // CHECK:*** Dumping AST Record Layout
- // CHECK: 0 | struct Empty::J
- // CHECK-NEXT: 0 | struct Empty::A4 a (empty)
- // CHECK-NEXT: 8 | struct Empty::A4 b (empty)
- // CHECK-NEXT: | [sizeof=16, align=8,
- // CHECK-NEXT: | nvsize=16, nvalign=8]
-
- struct K {
- [[msvc::no_unique_address]] A4 a;
- [[msvc::no_unique_address]] char c;
- [[msvc::no_unique_address]] A4 b;
- };
- static_assert(sizeof(K) == 16);
-
- // CHECK:*** Dumping AST Record Layout
- // CHECK: 0 | struct Empty::K
- // CHECK-NEXT: 0 | struct Empty::A4 a (empty)
- // CHECK-NEXT: 0 | char c
- // CHECK-NEXT: 8 | struct Empty::A4 b (empty)
- // CHECK-NEXT: | [sizeof=16, align=8,
- // CHECK-NEXT: | nvsize=16, nvalign=8]
-
- struct OversizedEmpty : A {
- ~OversizedEmpty();
- [[msvc::no_unique_address]] A a;
- };
- static_assert(sizeof(OversizedEmpty) == 1);
-
- // CHECK:*** Dumping AST Record Layout
- // CHECK: 0 | struct Empty::OversizedEmpty
- // CHECK-NEXT: 0 | struct Empty::A (base) (empty)
- // CHECK-NEXT: 0 | struct Empty::A a (empty)
- // CHECK-NEXT: | [sizeof=1, align=1,
- // CHECK-NEXT: | nvsize=1, nvalign=1]
-
- struct HasOversizedEmpty {
- [[msvc::no_unique_address]] OversizedEmpty m;
- };
- static_assert(sizeof(HasOversizedEmpty) == 1);
-
- // CHECK:*** Dumping AST Record Layout
- // CHECK: 0 | struct Empty::HasOversizedEmpty
- // CHECK-NEXT: 0 | struct Empty::OversizedEmpty m (empty)
- // CHECK-NEXT: 0 | struct Empty::A (base) (empty)
- // CHECK-NEXT: 0 | struct Empty::A a (empty)
- // CHECK-NEXT: | [sizeof=1, align=1,
- // CHECK-NEXT: | nvsize=1, nvalign=1]
-
- struct EmptyWithNonzeroDSize {
- [[msvc::no_unique_address]] A a;
- int x;
- [[msvc::no_unique_address]] A b;
- int y;
- [[msvc::no_unique_address]] A c;
- };
- static_assert(sizeof(EmptyWithNonzeroDSize) == 8);
-
- // CHECK:*** Dumping AST Record Layout
- // CHECK: 0 | struct Empty::EmptyWithNonzeroDSize
- // CHECK-NEXT: 0 | struct Empty::A a (empty)
- // CHECK-NEXT: 0 | int x
- // CHECK-NEXT: 1 | struct Empty::A b (empty)
- // CHECK-NEXT: 4 | int y
- // CHECK-NEXT: 2 | struct Empty::A c (empty)
- // CHECK-NEXT: | [sizeof=8, align=4,
- // CHECK-NEXT: | nvsize=8, nvalign=4]
-
- struct EmptyWithNonzeroDSizeNonPOD {
- ~EmptyWithNonzeroDSizeNonPOD();
- [[msvc::no_unique_address]] A a;
- int x;
- [[msvc::no_unique_address]] A b;
- int y;
- [[msvc::no_unique_address]] A c;
- };
- static_assert(sizeof(EmptyWithNonzeroDSizeNonPOD) == 8);
-
- // CHECK:*** Dumping AST Record Layout
- // CHECK: 0 | struct Empty::EmptyWithNonzeroDSizeNonPOD
- // CHECK-NEXT: 0 | struct Empty::A a (empty)
- // CHECK-NEXT: 0 | int x
- // CHECK-NEXT: 1 | struct Empty::A b (empty)
- // CHECK-NEXT: 4 | int y
- // CHECK-NEXT: 2 | struct Empty::A c (empty)
- // CHECK-NEXT: | [sizeof=8, align=4,
- // CHECK-NEXT: | nvsize=8, nvalign=4]
-}
-
-namespace POD {
- struct A { int n; char c[3]; };
- struct B { [[msvc::no_unique_address]] A a; char d; };
- static_assert(sizeof(B) == 12);
-
- // CHECK:*** Dumping AST Record Layout
- // CHECK: 0 | struct POD::B
- // CHECK-NEXT: 0 | struct POD::A a
- // CHECK-NEXT: 0 | int n
- // CHECK-NEXT: 4 | char[3] c
- // CHECK-NEXT: 8 | char d
- // CHECK-NEXT: | [sizeof=12, align=4,
- // CHECK-NEXT: | nvsize=12, nvalign=4]
-}
-
-namespace NonPOD {
- struct A { int n; char c[3]; ~A(); };
- struct B { [[msvc::no_unique_address]] A a; char d; };
- static_assert(sizeof(B) == 12);
-
- // CHECK:*** Dumping AST Record Layout
- // CHECK: 0 | struct NonPOD::B
- // CHECK-NEXT: 0 | struct NonPOD::A a
- // CHECK-NEXT: 0 | int n
- // CHECK-NEXT: 4 | char[3] c
- // CHECK-NEXT: 8 | char d
- // CHECK-NEXT: | [sizeof=12, align=4,
- // CHECK-NEXT: | nvsize=12, nvalign=4]
-}
-
-namespace VBases {
- // The nvsize of an object includes the complete size of its empty subobjects
- // (although it's unclear why). Ensure this corner case is handled properly.
- struct Empty {};
- struct alignas(8) A {}; // dsize 0, nvsize 0, size 8
- struct B : A { char c; }; // dsize 1, nvsize 8, size 8
- static_assert(sizeof(B) == 8);
-
- // CHECK:*** Dumping AST Record Layout
- // CHECK: 0 | struct VBases::B
- // CHECK-NEXT: 0 | struct VBases::A (base) (empty)
- // CHECK-NEXT: 0 | char c
- // CHECK-NEXT: | [sizeof=8, align=8,
- // CHECK-NEXT: | nvsize=8, nvalign=8]
-
- struct V { int n; };
-
- struct C : B, virtual V {};
- static_assert(sizeof(C) == 24);
-
- // CHECK:*** Dumping AST Record Layout
- // CHECK: 0 | struct VBases::C
- // CHECK-NEXT: 0 | struct VBases::B (base)
- // CHECK-NEXT: 0 | struct VBases::A (base) (empty)
- // CHECK-NEXT: 0 | char c
- // CHECK-NEXT: 8 | (C vbtable pointer)
- // CHECK-NEXT: 16 | struct VBases::V (virtual base)
- // CHECK-NEXT: 16 | int n
- // CHECK-NEXT: | [sizeof=24, align=8,
- // CHECK-NEXT: | nvsize=16, nvalign=8]
-
- struct D : virtual Empty {
- [[msvc::no_unique_address]] Empty a;
- };
- static_assert(sizeof(D) == 16);
-
- // CHECK:*** Dumping AST Record Layout
- // CHECK: 0 | struct VBases::D
- // CHECK-NEXT: 0 | (D vbtable pointer)
- // CHECK-NEXT: 8 | struct VBases::Empty a
- // CHECK-NEXT: 16 | struct VBases::Empty (virtual base) (empty)
- // CHECK-NEXT: | [sizeof=16, align=8,
- // CHECK-NEXT: | nvsize=16, nvalign=8]
-
- struct E : virtual V {
- [[msvc::no_unique_address]] B b;
- };
- static_assert(sizeof(E) == 24);
-
- // CHECK:*** Dumping AST Record Layout
- // CHECK: 0 | struct VBases::E
- // CHECK-NEXT: 0 | (E vbtable pointer)
- // CHECK-NEXT: 8 | struct VBases::B b
- // CHECK-NEXT: 8 | struct VBases::A (base) (empty)
- // CHECK-NEXT: 8 | char c
- // CHECK-NEXT: 16 | struct VBases::V (virtual base)
- // CHECK-NEXT: 16 | int n
- // CHECK-NEXT: | [sizeof=24, align=8,
- // CHECK-NEXT: | nvsize=16, nvalign=8]
-
- struct X : virtual A { [[msvc::no_unique_address]] A a; };
- struct F : virtual A {
- [[msvc::no_unique_address]] A a;
- [[msvc::no_unique_address]] X x;
- };
- static_assert(sizeof(F) == 24);
-
- // MSVC places x after a and the total size is 48.
- // CHECK:*** Dumping AST Record Layout
- // CHECK: 0 | struct VBases::F
- // CHECK-NEXT: 0 | (F vbtable pointer)
- // CHECK-NEXT: 8 | struct VBases::A a (empty)
- // CHECK-NEXT: 8 | struct VBases::X x
- // CHECK-NEXT: 8 | (X vbtable pointer)
- // CHECK-NEXT: 16 | struct VBases::A a (empty)
- // CHECK-NEXT: 24 | struct VBases::A (virtual base) (empty)
- // CHECK-NEXT: 24 | struct VBases::A (virtual base) (empty)
- // CHECK-NEXT: | [sizeof=24, align=8,
- // CHECK-NEXT: | nvsize=24, nvalign=8]
-
- struct G : virtual Empty {
- int i;
- [[msvc::no_unique_address]] A a;
- };
- static_assert(sizeof(G) == 16);
-
- // MSVC places a at offset 12.
- // CHECK:*** Dumping AST Record Layout
- // CHECK: 0 | struct VBases::G
- // CHECK-NEXT: 0 | (G vbtable pointer)
- // CHECK-NEXT: 8 | int i
- // CHECK-NEXT: 8 | struct VBases::A a (empty)
- // CHECK-NEXT: 16 | struct VBases::Empty (virtual base) (empty)
- // CHECK-NEXT: | [sizeof=16, align=8,
- // CHECK-NEXT: | nvsize=16, nvalign=8]
-}
-
-namespace ZeroSize {
- struct empty {};
-
- union empty_union {};
-
- struct empty_union_container {
- [[msvc::no_unique_address]] empty_union x;
- };
-
- union union_of_empty {
- [[msvc::no_unique_address]] empty x;
- };
-
- struct struct_of_empty {
- [[msvc::no_unique_address]] empty x;
- };
-
- struct union_of_empty_container {
- [[msvc::no_unique_address]] union_of_empty x;
- };
- static_assert(sizeof(union_of_empty_container) == 1);
- // CHECK:*** Dumping AST Record Layout
- // CHECK: 0 | struct ZeroSize::union_of_empty_container
- // CHECK-NOT: (empty)
- // CHECK: 0 | union ZeroSize::union_of_empty x (empty)
- // CHECK: 0 | struct ZeroSize::empty x (empty)
- // CHECK: | [sizeof=1, align=1,
- // CHECK: | nvsize=1, nvalign=1]
-
- struct struct_of_empty_container {
- [[msvc::no_unique_address]] struct_of_empty x;
- };
- static_assert(sizeof(struct_of_empty_container) == 1);
- // CHECK:*** Dumping AST Record Layout
- // CHECK: 0 | struct ZeroSize::struct_of_empty_container
- // CHECK-NOT: (empty)
- // CHECK: 0 | struct ZeroSize::struct_of_empty x (empty)
- // CHECK: 0 | struct ZeroSize::empty x (empty)
- // CHECK: | [sizeof=1, align=1,
- // CHECK: | nvsize=1, nvalign=1]
-
-}
diff --git a/clang/test/Preprocessor/has_attribute.cpp b/clang/test/Preprocessor/has_attribute.cpp
index 3fb99eda699b3cf..bf0f9b3bc4a8f08 100644
--- a/clang/test/Preprocessor/has_attribute.cpp
+++ b/clang/test/Preprocessor/has_attribute.cpp
@@ -43,7 +43,6 @@ CXX11(fallthrough)
CXX11(likely)
CXX11(maybe_unused)
CXX11(no_unique_address)
-CXX11(msvc::no_unique_address)
CXX11(nodiscard)
CXX11(noreturn)
CXX11(unlikely)
@@ -56,9 +55,7 @@ CXX11(unlikely)
// CHECK: likely: 201803L
// CHECK: maybe_unused: 201603L
// ITANIUM: no_unique_address: 201803L
-// WINDOWS: no_unique_address: 0
-// ITANIUM: msvc::no_unique_address: 0
-// WINDOWS: msvc::no_unique_address: 201803L
+// WINDOWS: no_unique_address: 0
// CHECK: nodiscard: 201907L
// CHECK: noreturn: 200809L
// CHECK: unlikely: 201803L
diff --git a/clang/test/SemaCXX/cxx2a-ms-no-unique-address.cpp b/clang/test/SemaCXX/cxx2a-ms-no-unique-address.cpp
deleted file mode 100644
index 42058559a087a53..000000000000000
--- a/clang/test/SemaCXX/cxx2a-ms-no-unique-address.cpp
+++ /dev/null
@@ -1,19 +0,0 @@
-// RUN: %clang_cc1 -std=c++2a %s -verify=unsupported -triple x86_64-linux-gnu
-// RUN: %clang_cc1 -std=c++2a %s -verify -triple x86_64-windows -fms-compatibility
-
-[[msvc::no_unique_address]] int a; // expected-error {{only applies to non-bit-field non-static data members}} unsupported-warning {{unknown}}
-[[msvc::no_unique_address]] void f(); // expected-error {{only applies to non-bit-field non-static data members}} unsupported-warning {{unknown}}
-struct [[msvc::no_unique_address]] S { // expected-error {{only applies to non-bit-field non-static data members}} unsupported-warning {{unknown}}
- [[msvc::no_unique_address]] int a; // unsupported-warning {{unknown}}
- [[msvc::no_unique_address]] void f(); // expected-error {{only applies to non-bit-field non-static data members}} unsupported-warning {{unknown}}
- [[msvc::no_unique_address]] static int sa;// expected-error {{only applies to non-bit-field non-static data members}} unsupported-warning {{unknown}}
- [[msvc::no_unique_address]] static void sf(); // expected-error {{only applies to non-bit-field non-static data members}} unsupported-warning {{unknown}}
- [[msvc::no_unique_address]] int b : 3; // expected-error {{only applies to non-bit-field non-static data members}} unsupported-warning {{unknown}}
-
- [[msvc::no_unique_address, msvc::no_unique_address]] int duplicated; // ok
- // unsupported-warning at -1 2{{unknown}}
- [[msvc::no_unique_address]] [[msvc::no_unique_address]] int duplicated2; // unsupported-warning 2{{unknown}}
- [[msvc::no_unique_address()]] int arglist; // expected-error {{cannot have an argument list}} unsupported-warning {{unknown}}
-
- int [[msvc::no_unique_address]] c; // expected-error {{cannot be applied to types}} unsupported-error {{cannot be applied to types}}
-};
More information about the cfe-commits
mailing list