diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -3712,7 +3712,7 @@ } // Deactivate the cleanup for the callee-destructed param that was pushed. - if (hasAggregateEvaluationKind(type) && !CurFuncIsThunk && + if (type->isRecordType() && !CurFuncIsThunk && type->castAs()->getDecl()->isParamDestroyedInCallee() && param->needsDestruction(getContext())) { EHScopeStack::stable_iterator cleanup = @@ -4283,7 +4283,7 @@ // In the Microsoft C++ ABI, aggregate arguments are destructed by the callee. // However, we still have to push an EH-only cleanup in case we unwind before // we make it to the call. - if (HasAggregateEvalKind && + if (type->isRecordType() && type->castAs()->getDecl()->isParamDestroyedInCallee()) { // If we're using inalloca, use the argument memory. Otherwise, use a // temporary. diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp --- a/clang/lib/CodeGen/CGDecl.cpp +++ b/clang/lib/CodeGen/CGDecl.cpp @@ -2473,7 +2473,7 @@ // Push a destructor cleanup for this parameter if the ABI requires it. // Don't push a cleanup in a thunk for a method that will also emit a // cleanup. - if (hasAggregateEvaluationKind(Ty) && !CurFuncIsThunk && + if (Ty->isRecordType() && !CurFuncIsThunk && Ty->castAs()->getDecl()->isParamDestroyedInCallee()) { if (QualType::DestructionKind DtorKind = D.needsDestruction(getContext())) { diff --git a/clang/test/CodeGen/big-atomic-ops.c b/clang/test/CodeGen/big-atomic-ops.c --- a/clang/test/CodeGen/big-atomic-ops.c +++ b/clang/test/CodeGen/big-atomic-ops.c @@ -311,4 +311,10 @@ // CHECK: } } +// Check this doesn't crash +// CHECK: @test_atomic_array_param( +void test_atomic_array_param(_Atomic(struct foo) a) { + test_atomic_array_param(a); +} + #endif diff --git a/clang/test/CodeGenCXX/atomic.cpp b/clang/test/CodeGenCXX/atomic.cpp --- a/clang/test/CodeGenCXX/atomic.cpp +++ b/clang/test/CodeGenCXX/atomic.cpp @@ -15,3 +15,13 @@ } void f(Ptr *a) { a->f(); } } + +namespace DelegatingParameter { + // Check that we're delegating the complete ctor to the base + // ctor, and that doesn't crash. + // CHECK-LABEL: define void @_ZN19DelegatingParameter1SC1EU7_AtomicNS_1ZE + // CHECK: call void @_ZN19DelegatingParameter1SC2EU7_AtomicNS_1ZE + struct Z { int z[100]; }; + struct S { S(_Atomic Z); }; + S::S(_Atomic Z) {} +}