From: Fariborz Jahanian Date: Wed, 10 Feb 2010 23:34:57 +0000 (+0000) Subject: Generate the objc_read_weak API when calling X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=263c4dec5f0fda5a77ed99f3ccd456c15cb8720f;p=clang Generate the objc_read_weak API when calling a __weak block. Fixes radar 7628591. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@95822 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp index 05d138b2a2..46b62441d6 100644 --- a/lib/CodeGen/CGBlocks.cpp +++ b/lib/CodeGen/CGBlocks.cpp @@ -13,6 +13,7 @@ #include "CGDebugInfo.h" #include "CodeGenFunction.h" +#include "CGObjCRuntime.h" #include "CodeGenModule.h" #include "clang/AST/DeclObjC.h" #include "llvm/Module.h" @@ -355,7 +356,21 @@ llvm::Value *CodeGenFunction::BuildBlockLiteralTmp(const BlockExpr *BE) { } QualType BPT = BE->getType(); - return Builder.CreateBitCast(V, ConvertType(BPT)); + V = Builder.CreateBitCast(V, ConvertType(BPT)); + // See if this is a __weak block variable and the must call objc_read_weak + // on it. + const FunctionType *ftype = BPT->getPointeeType()->getAs(); + QualType RES = ftype->getResultType(); + if (RES.isObjCGCWeak()) { + // Must cast argument to id* + const llvm::Type *ObjectPtrTy = + ConvertType(CGM.getContext().getObjCIdType()); + const llvm::Type *PtrObjectPtrTy = + llvm::PointerType::getUnqual(ObjectPtrTy); + V = Builder.CreateBitCast(V, PtrObjectPtrTy); + V = CGM.getObjCRuntime().EmitObjCWeakRead(*this, V); + } + return V; } diff --git a/test/CodeGenObjC/objc2-weak-block-call.m b/test/CodeGenObjC/objc2-weak-block-call.m new file mode 100644 index 0000000000..a3514b0caa --- /dev/null +++ b/test/CodeGenObjC/objc2-weak-block-call.m @@ -0,0 +1,29 @@ +// RUN: %clang_cc1 -fblocks -fobjc-gc -triple x86_64-apple-darwin -S %s -o %t-64.s +// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s +// RUN: %clang_cc1 -fblocks -fobjc-gc -triple i386-apple-darwin -S %s -o %t-32.s +// RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s + +@interface MyView +- (void)MyView_sharedInit; +@end + +void foo(MyView *(^obj)(void)) ; + +@implementation MyView +- (void)MyView_sharedInit { + + __block __weak MyView *weakSelf = self; + foo( + ^{ + return weakSelf; + }); + +} +@end + +// CHECK-LP64: callq _objc_read_weak +// CHECK-LP64: callq _objc_read_weak + +// CHECK-LP32: call L_objc_read_weak +// CHECK-LP32: call L_objc_read_weak +