[clang CodeGen] Don't crash on large atomic function parameter.
authorEli Friedman <efriedma@quicinc.com>
Thu, 6 May 2021 19:27:01 +0000 (12:27 -0700)
committerEli Friedman <efriedma@quicinc.com>
Mon, 17 May 2021 20:18:23 +0000 (13:18 -0700)
I wouldn't recommend writing code like the testcase; a function
parameter isn't atomic, so using an atomic type doesn't really make
sense.  But it's valid, so clang shouldn't crash on it.

The code was assuming hasAggregateEvaluationKind(Ty) implies Ty is a
RecordType, which isn't true.  Just use isRecordType() instead.

Differential Revision: https://reviews.llvm.org/D102015

clang/lib/CodeGen/CGCall.cpp
clang/lib/CodeGen/CGDecl.cpp
clang/test/CodeGen/big-atomic-ops.c
clang/test/CodeGenCXX/atomic.cpp

index b665e67..241479d 100644 (file)
@@ -3712,7 +3712,7 @@ void CodeGenFunction::EmitDelegateCallArg(CallArgList &args,
   }
 
   // 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 =
@@ -4283,7 +4283,7 @@ void CodeGenFunction::EmitCallArg(CallArgList &args, const Expr *E,
   // 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.
index 10781db..22bd8d1 100644 (file)
@@ -2473,7 +2473,7 @@ void CodeGenFunction::EmitParmDecl(const VarDecl &D, ParamValue Arg,
     // 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())) {
index c584ffc..0dc43ca 100644 (file)
@@ -311,4 +311,10 @@ void atomic_init_foo()
   // 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
index f40cb6d..e5ecf0c 100644 (file)
@@ -15,3 +15,13 @@ namespace PR11411 {
   }
   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) {}
+}