mirror of
https://github.com/microsoft/vcpkg.git
synced 2024-12-03 03:59:07 +08:00
113 lines
4.2 KiB
Diff
113 lines
4.2 KiB
Diff
|
From 5fcaeaddccc0f7e370bf7bebce113d8d52e1b1bd Mon Sep 17 00:00:00 2001
|
||
|
From: Shafik Yaghmour <shafik.yaghmour@intel.com>
|
||
|
Date: Tue, 20 Feb 2024 11:22:39 -0800
|
||
|
Subject: [PATCH] [Clang][Sema] Fix incorrect rejection default construction of
|
||
|
union with nontrivial member
|
||
|
|
||
|
In 765d8a192180f8f33618087b15c022fe758044af we impelemented a fix for incorrect deletion of
|
||
|
default constructors in unions. This fix missed a case and so this PR will
|
||
|
extend the fix to cover the additional case.
|
||
|
|
||
|
Fixes: https://github.com/llvm/llvm-project/issues/81774
|
||
|
---
|
||
|
clang/lib/Sema/SemaDeclCXX.cpp | 18 +++++++++++++++---
|
||
|
.../test/CodeGen/union-non-trivial-member.cpp | 17 +++++++++++++++++
|
||
|
clang/test/SemaCXX/cxx0x-nontrivial-union.cpp | 11 +++++++++++
|
||
|
4 files changed, 46 insertions(+), 3 deletions(-)
|
||
|
|
||
|
Bug Fixes to AST Handling
|
||
|
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||
|
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
|
||
|
index 79263bc3ff671..25a4b4381ca25 100644
|
||
|
--- a/clang/lib/Sema/SemaDeclCXX.cpp
|
||
|
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
|
||
|
@@ -9442,9 +9442,21 @@ bool SpecialMemberDeletionInfo::shouldDeleteForSubobjectCall(
|
||
|
|
||
|
int DiagKind = -1;
|
||
|
|
||
|
- if (SMOR.getKind() == Sema::SpecialMemberOverloadResult::NoMemberOrDeleted)
|
||
|
- DiagKind = !Decl ? 0 : 1;
|
||
|
- else if (SMOR.getKind() == Sema::SpecialMemberOverloadResult::Ambiguous)
|
||
|
+ if (SMOR.getKind() == Sema::SpecialMemberOverloadResult::NoMemberOrDeleted) {
|
||
|
+ if (CSM == Sema::CXXDefaultConstructor && Field &&
|
||
|
+ Field->getParent()->isUnion()) {
|
||
|
+ // [class.default.ctor]p2:
|
||
|
+ // A defaulted default constructor for class X is defined as deleted if
|
||
|
+ // - X is a union that has a variant member with a non-trivial default
|
||
|
+ // constructor and no variant member of X has a default member
|
||
|
+ // initializer
|
||
|
+ const auto *RD = cast<CXXRecordDecl>(Field->getParent());
|
||
|
+ if (!RD->hasInClassInitializer())
|
||
|
+ DiagKind = !Decl ? 0 : 1;
|
||
|
+ } else {
|
||
|
+ DiagKind = !Decl ? 0 : 1;
|
||
|
+ }
|
||
|
+ } else if (SMOR.getKind() == Sema::SpecialMemberOverloadResult::Ambiguous)
|
||
|
DiagKind = 2;
|
||
|
else if (!isAccessible(Subobj, Decl))
|
||
|
DiagKind = 3;
|
||
|
diff --git a/clang/test/CodeGen/union-non-trivial-member.cpp b/clang/test/CodeGen/union-non-trivial-member.cpp
|
||
|
index fdc9fd16911e1..8b055a9970fc7 100644
|
||
|
--- a/clang/test/CodeGen/union-non-trivial-member.cpp
|
||
|
+++ b/clang/test/CodeGen/union-non-trivial-member.cpp
|
||
|
@@ -15,14 +15,25 @@ union UnionNonTrivial {
|
||
|
non_trivial_constructor b{};
|
||
|
};
|
||
|
|
||
|
+struct Handle {
|
||
|
+ Handle(int) {}
|
||
|
+};
|
||
|
+
|
||
|
+union UnionNonTrivialEqualInit {
|
||
|
+ int NoState = 0;
|
||
|
+ Handle CustomState;
|
||
|
+};
|
||
|
+
|
||
|
void f() {
|
||
|
UnionInt u1;
|
||
|
UnionNonTrivial u2;
|
||
|
+ UnionNonTrivialEqualInit u3;
|
||
|
}
|
||
|
|
||
|
// CHECK: define dso_local void @_Z1fv()
|
||
|
// CHECK: call void @_ZN8UnionIntC1Ev
|
||
|
// CHECK-NEXT: call void @_ZN15UnionNonTrivialC1Ev
|
||
|
+// CHECK-NEXT: call void @_ZN24UnionNonTrivialEqualInitC1Ev
|
||
|
|
||
|
// CHECK: define {{.*}}void @_ZN8UnionIntC1Ev
|
||
|
// CHECK: call void @_ZN8UnionIntC2Ev
|
||
|
@@ -30,8 +41,14 @@ void f() {
|
||
|
// CHECK: define {{.*}}void @_ZN15UnionNonTrivialC1Ev
|
||
|
// CHECK: call void @_ZN15UnionNonTrivialC2Ev
|
||
|
|
||
|
+// CHECK: define {{.*}}void @_ZN24UnionNonTrivialEqualInitC1Ev
|
||
|
+// CHECK: call void @_ZN24UnionNonTrivialEqualInitC2Ev
|
||
|
+
|
||
|
// CHECK: define {{.*}}void @_ZN8UnionIntC2Ev
|
||
|
// CHECK: store i32 1000
|
||
|
|
||
|
// CHECK: define {{.*}}void @_ZN15UnionNonTrivialC2Ev
|
||
|
// CHECK: call void @_ZN23non_trivial_constructorC1Ev
|
||
|
+
|
||
|
+// CHECK: define {{.*}}void @_ZN24UnionNonTrivialEqualInitC2Ev
|
||
|
+// CHECK: store i32 0
|
||
|
diff --git a/clang/test/SemaCXX/cxx0x-nontrivial-union.cpp b/clang/test/SemaCXX/cxx0x-nontrivial-union.cpp
|
||
|
index c7cdf76d850db..833642b3d739a 100644
|
||
|
--- a/clang/test/SemaCXX/cxx0x-nontrivial-union.cpp
|
||
|
+++ b/clang/test/SemaCXX/cxx0x-nontrivial-union.cpp
|
||
|
@@ -188,3 +188,14 @@ static_assert(U2().b.x == 100, "");
|
||
|
static_assert(U3().b.x == 100, "");
|
||
|
|
||
|
} // namespace GH48416
|
||
|
+
|
||
|
+namespace GH81774 {
|
||
|
+struct Handle {
|
||
|
+ Handle(int) {}
|
||
|
+};
|
||
|
+// Should be well-formed because NoState has a brace-or-equal-initializer.
|
||
|
+union a {
|
||
|
+ int NoState = 0;
|
||
|
+ Handle CustomState;
|
||
|
+} b;
|
||
|
+} // namespace GH81774
|