}
// Deactivate the cleanup for the callee-destructed param that was pushed.
- if (hasAggregateEvaluationKind(type) && !CurFuncIsThunk &&
+ if (type->isRecordType() && !CurFuncIsThunk &&
type->castAs<RecordType>()->getDecl()->isParamDestroyedInCallee() &&
param->needsDestruction(getContext())) {
EHScopeStack::stable_iterator cleanup =
// 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<RecordType>()->getDecl()->isParamDestroyedInCallee()) {
// If we're using inalloca, use the argument memory. Otherwise, use a
// temporary.
// 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<RecordType>()->getDecl()->isParamDestroyedInCallee()) {
if (QualType::DestructionKind DtorKind =
D.needsDestruction(getContext())) {
// 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
}
void f(Ptr<int> *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) {}
+}