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(); }); } +@interface Test23 +-(void)m:(int)i, ...; +@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 } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits