diff options
| author | Alan Zhao <ayzhao@google.com> | 2023-03-20 14:53:53 -0700 |
|---|---|---|
| committer | Alan Zhao <ayzhao@google.com> | 2023-03-30 15:06:37 -0700 |
| commit | 7df3c71b508b65284483225685f1ba19777f2bbb (patch) | |
| tree | 2202e30cc3b0264deec615a4c247778bb27c7250 /clang/test/CodeGen/paren-list-agg-init.cpp | |
| parent | 3b11e4097f3ab3fbc44f91e6599d890add0c387e (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.cpp | 72 |
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>(); + } +} |
