summaryrefslogtreecommitdiff
path: root/clang/test/CodeGen/paren-list-agg-init.cpp
diff options
context:
space:
mode:
authorAlan Zhao <ayzhao@google.com>2023-03-20 14:53:53 -0700
committerAlan Zhao <ayzhao@google.com>2023-03-30 15:06:37 -0700
commit7df3c71b508b65284483225685f1ba19777f2bbb (patch)
tree2202e30cc3b0264deec615a4c247778bb27c7250 /clang/test/CodeGen/paren-list-agg-init.cpp
parent3b11e4097f3ab3fbc44f91e6599d890add0c387e (diff)
[clang] Fix 2 bugs with parenthesized aggregate initialization
* Fix an issue where temporaries initialized via parenthesized aggregate initialization don't get destroyed. * Fix an issue where aggregate initialization omits calls to class members' move constructors after a TreeTransform. This occurs because the CXXConstructExpr wrapping the call to the move constructor gets unboxed during a TreeTransform of the wrapping FunctionalCastExpr (as with a InitListExpr), but unlike InitListExpr, we dont reperform the InitializationSequence for the list's expressions to regenerate the CXXConstructExpr. This patch fixes this bug by treating CXXParenListInitExpr identically to InitListExpr in this regard. Fixes #61145 Reviewed By: rsmith Differential Revision: https://reviews.llvm.org/D146465
Diffstat (limited to 'clang/test/CodeGen/paren-list-agg-init.cpp')
-rw-r--r--clang/test/CodeGen/paren-list-agg-init.cpp72
1 files changed, 72 insertions, 0 deletions
diff --git a/clang/test/CodeGen/paren-list-agg-init.cpp b/clang/test/CodeGen/paren-list-agg-init.cpp
index a7534fb907d2..a860196d8f50 100644
--- a/clang/test/CodeGen/paren-list-agg-init.cpp
+++ b/clang/test/CodeGen/paren-list-agg-init.cpp
@@ -69,6 +69,27 @@ union U {
char b;
};
+
+namespace gh61145 {
+ // CHECK-DAG: [[STRUCT_VEC:%.*]] = type { i8 }
+ struct Vec {
+ Vec();
+ Vec(Vec&&);
+ ~Vec();
+ };
+
+ // CHECK-DAG: [[STRUCT_S1:%.*]] = type { [[STRUCT_VEC]] }
+ struct S1 {
+ Vec v;
+ };
+
+ // CHECK-DAG: [[STRUCT_S2:%.*]] = type { [[STRUCT_VEC]], i8 }
+ struct S2 {
+ Vec v;
+ char c;
+ };
+}
+
// CHECK-DAG: [[A1:@.*a1.*]] = internal constant [[STRUCT_A]] { i8 3, double 2.000000e+00 }, align 8
constexpr A a1(3.1, 2.0);
// CHECK-DAG: [[A2:@.*a2.*]] = internal constant [[STRUCT_A]] { i8 99, double 0.000000e+00 }, align 8
@@ -349,3 +370,54 @@ void foo18() {
void foo19() {
G g(2);
}
+
+namespace gh61145 {
+ // a.k.a. void make1<0>()
+ // CHECK: define {{.*}} void @_ZN7gh611455make1ILi0EEEvv
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: [[V:%.*v.*]] = alloca [[STRUCT_VEC]], align 1
+ // CHECK-NEXT: [[AGG_TMP_ENSURED:%.*agg.tmp.ensured.*]] = alloca [[STRUCT_S1]], align 1
+ // a.k.a. Vec::Vec()
+ // CHECK-NEXT: call void @_ZN7gh611453VecC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[V]])
+ // CHECK-NEXT: [[V1:%.*v1.*]] = getelementptr inbounds [[STRUCT_S1]], ptr [[AGG_TMP_ENSURED]], i32 0, i32 0
+ // a.k.a. Vec::Vec(Vec&&)
+ // CHECK-NEXT: call void @_ZN7gh611453VecC1EOS0_(ptr noundef nonnull align 1 dereferenceable(1) [[V1]], ptr noundef nonnull align 1 dereferenceable(1) [[V]])
+ // a.k.a. S1::~S1()
+ // CHECK-NEXT: call void @_ZN7gh611452S1D1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_TMP_ENSURED]])
+ // a.k.a.Vec::~Vec()
+ // CHECK-NEXT: call void @_ZN7gh611453VecD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[V]])
+ // CHECK-NEXT: ret void
+ template <int I>
+ void make1() {
+ Vec v;
+ S1((Vec&&) v);
+ }
+
+ // a.k.a. void make1<0>()
+ // CHECK: define {{.*}} void @_ZN7gh611455make2ILi0EEEvv
+ // CHECK-NEXT: entry:
+ // CHECK-NEXT: [[V:%.*v.*]] = alloca [[STRUCT_VEC]], align 1
+ // CHECK-NEXT: [[AGG_TMP_ENSURED:%.*agg.tmp.ensured.*]] = alloca [[STRUCT_S2]], align 1
+ // a.k.a. Vec::Vec()
+ // CHECK-NEXT: call void @_ZN7gh611453VecC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[V]])
+ // CHECK-NEXT: [[V1:%.*v1.*]] = getelementptr inbounds [[STRUCT_S2]], ptr [[AGG_TMP_ENSURED]], i32 0, i32 0
+ // a.k.a. Vec::Vec(Vec&&)
+ // CHECK-NEXT: call void @_ZN7gh611453VecC1EOS0_(ptr noundef nonnull align 1 dereferenceable(1) [[V1]], ptr noundef nonnull align 1 dereferenceable(1) [[V]])
+ // CHECK-NEXT: [[C:%.*c.*]] = getelementptr inbounds [[STRUCT_S2]], ptr [[AGG_TMP_ENSURED]], i32 0, i32
+ // CHECK-NEXT: store i8 0, ptr [[C]], align 1
+ // a.k.a. S2::~S2()
+ // CHECK-NEXT: call void @_ZN7gh611452S2D1Ev(ptr noundef nonnull align 1 dereferenceable(2) [[AGG_TMP_ENSURED]])
+ // a.k.a. Vec::~Vec()
+ // CHECK-NEXT: call void @_ZN7gh611453VecD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[V]])
+ // CHECK-NEXT: ret void
+ template <int I>
+ void make2() {
+ Vec v;
+ S2((Vec&&) v, 0);
+ }
+
+ void foo() {
+ make1<0>();
+ make2<0>();
+ }
+}