[clang] cdd6a27 - [ObjC] Copy a block to the heap if it is passed as a variadic argument

Akira Hatanaka via cfe-commits cfe-commits at lists.llvm.org
Wed Jun 24 11:46:59 PDT 2020


Author: Akira Hatanaka
Date: 2020-06-24T11:46:38-07:00
New Revision: cdd6a2788caced6b377af818154138d9983dba5f

URL: https://github.com/llvm/llvm-project/commit/cdd6a2788caced6b377af818154138d9983dba5f
DIFF: https://github.com/llvm/llvm-project/commit/cdd6a2788caced6b377af818154138d9983dba5f.diff

LOG: [ObjC] Copy a block to the heap if it is passed as a variadic argument

Call maybeExtendBlockObject in DefaultVariadicArgumentPromotion so that
the block is copied to the heap when it is passed as a variadic argument
to any calls, not only to C function calls.

rdar://problem/64201532

Added: 
    

Modified: 
    clang/lib/Sema/SemaExpr.cpp
    clang/test/CodeGenObjC/arc-blocks.m

Removed: 
    


################################################################################
diff  --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index ec595ae7d723..bc0248700517 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -964,6 +964,11 @@ ExprResult Sema::DefaultVariadicArgumentPromotion(Expr *E, VariadicCallType CT,
   ExprResult ExprRes = DefaultArgumentPromotion(E);
   if (ExprRes.isInvalid())
     return ExprError();
+
+  // Copy blocks to the heap.
+  if (ExprRes.get()->getType()->isBlockPointerType())
+    maybeExtendBlockObject(ExprRes);
+
   E = ExprRes.get();
 
   // Diagnostics regarding non-POD argument types are
@@ -5941,9 +5946,6 @@ bool Sema::GatherArgumentsForCall(SourceLocation CallLoc, FunctionDecl *FDecl,
       for (Expr *A : Args.slice(ArgIx)) {
         ExprResult Arg = DefaultVariadicArgumentPromotion(A, CallType, FDecl);
         Invalid |= Arg.isInvalid();
-        // Copy blocks to the heap.
-        if (A->getType()->isBlockPointerType())
-          maybeExtendBlockObject(Arg);
         AllArgs.push_back(Arg.get());
       }
     }

diff  --git a/clang/test/CodeGenObjC/arc-blocks.m b/clang/test/CodeGenObjC/arc-blocks.m
index 3851773c68b7..0694155b5f4a 100644
--- a/clang/test/CodeGenObjC/arc-blocks.m
+++ b/clang/test/CodeGenObjC/arc-blocks.m
@@ -747,5 +747,18 @@ id test22(int c, id x) {
   return c ? test22_0() : ({ id (^b)(void) = ^{ return x; }; test22_1(); b(); });
 }
 
+ at interface Test23
+-(void)m:(int)i, ...;
+ at end
+
+// CHECK-COMMON-LABEL: define void @test23(
+// CHECK-COMMON: %[[V9:.*]] = call i8* @llvm.objc.retainBlock(
+// CHECK-COMMON: %[[V10:.*]] = bitcast i8* %[[V9]] to void ()*
+// CHECK-COMMON: call void (i8*, i8*, i32, ...) bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, i32, ...)*)(i8* %{{.*}}, i8* %{{.*}}, i32 123, void ()* %[[V10]])
+
+void test23(id x, Test23 *t) {
+  [t m:123, ^{ (void)x; }];
+}
+
 // CHECK: attributes [[NUW]] = { nounwind }
 // CHECK-UNOPT: attributes [[NUW]] = { nounwind }


        


More information about the cfe-commits mailing list