royjacobson updated this revision to Diff 505620.
royjacobson marked an inline comment as done.
royjacobson added a comment.
slimmer codegen test
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D145851/new/
https://reviews.llvm.org/D145851
Files:
clang/docs/ReleaseNotes.rst
clang/lib/Sema/SemaDeclCXX.cpp
clang/test/CodeGen/union-non-trivial-member.cpp
clang/test/SemaCXX/cxx0x-nontrivial-union.cpp
Index: clang/test/SemaCXX/cxx0x-nontrivial-union.cpp
===================================================================
--- clang/test/SemaCXX/cxx0x-nontrivial-union.cpp
+++ clang/test/SemaCXX/cxx0x-nontrivial-union.cpp
@@ -144,3 +144,47 @@
Test2<X> t2x; // expected-error {{call to implicitly-deleted default constructor of 'Test2<X>'}}
}
+
+namespace GH48416 {
+
+struct non_trivial_constructor {
+ constexpr non_trivial_constructor() : x(100) {}
+ int x;
+};
+
+
+union U1 {
+ int a;
+ non_trivial_constructor b; // expected-note {{has a non-trivial default constructor}}
+};
+
+union U2 {
+ int a{1000};
+ non_trivial_constructor b;
+};
+
+union U3 {
+ int a;
+ non_trivial_constructor b{};
+};
+
+union U4 {
+ int a{}; // expected-note {{previous initialization is here}}
+ non_trivial_constructor b{}; // expected-error {{initializing multiple members of union}}
+};
+
+U1 u1; // expected-error {{call to implicitly-deleted default constructor}}
+U2 u2;
+U3 u3;
+U4 u4;
+
+static_assert(U2().a == 1000, "");
+static_assert(U3().a == 1000, "");
+// expected-error@-1 {{static assertion expression is not an integral constant expression}}
+// expected-note@-2 {{read of member 'a' of union with active member 'b'}}
+static_assert(U2().b.x == 100, "");
+// expected-error@-1 {{static assertion expression is not an integral constant expression}}
+// expected-note@-2 {{read of member 'b' of union with active member 'a'}}
+static_assert(U3().b.x == 100, "");
+
+} // namespace GH48416
Index: clang/test/CodeGen/union-non-trivial-member.cpp
===================================================================
--- /dev/null
+++ clang/test/CodeGen/union-non-trivial-member.cpp
@@ -0,0 +1,37 @@
+// RUN: %clang_cc1 --std=c++17 -emit-llvm %s -o - -triple x86_64-unknown-linux-gnu | FileCheck %s
+
+struct non_trivial_constructor {
+ constexpr non_trivial_constructor() : x(100) { }
+ int x;
+};
+
+union UnionInt {
+ int a{1000};
+ non_trivial_constructor b;
+};
+
+union UnionNonTrivial {
+ int a;
+ non_trivial_constructor b{};
+};
+
+void f() {
+ UnionInt u1;
+ UnionNonTrivial u2;
+}
+
+// CHECK: define dso_local void @_Z1fv()
+// CHECK: call void @_ZN8UnionIntC1Ev
+// CHECK-NEXT: call void @_ZN15UnionNonTrivialC1Ev
+
+// CHECK: define {{.*}}void @_ZN8UnionIntC1Ev
+// CHECK: call void @_ZN8UnionIntC2Ev
+
+// CHECK: define {{.*}}void @_ZN15UnionNonTrivialC1Ev
+// CHECK: call void @_ZN15UnionNonTrivialC2Ev
+
+// CHECK: define {{.*}}void @_ZN8UnionIntC2Ev
+// CHECK: store i32 1000
+
+// CHECK: define {{.*}}void @_ZN15UnionNonTrivialC2Ev
+// CHECK: call void @_ZN23non_trivial_constructorC1Ev
Index: clang/lib/Sema/SemaDeclCXX.cpp
===================================================================
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -9157,7 +9157,18 @@
// must be accessible and non-deleted, but need not be trivial. Such a
// destructor is never actually called, but is semantically checked as
// if it were.
- DiagKind = 4;
+ if (CSM == Sema::CXXDefaultConstructor) {
+ // [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 = 4;
+ } else {
+ DiagKind = 4;
+ }
}
if (DiagKind == -1)
Index: clang/docs/ReleaseNotes.rst
===================================================================
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -202,6 +202,8 @@
- Fix crash when evaluating consteval constructor of derived class whose base
has more than one field.
(`#60166 <https://github.com/llvm/llvm-project/issues/60166>`_)
+- Fix incorrect deletion of the default constructor of unions in some
+ cases. (`#48416 <https://github.com/llvm/llvm-project/issues/48416>`_)
Bug Fixes to AST Handling
^^^^^^^^^^^^^^^^^^^^^^^^^
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits