From: Fariborz Jahanian Date: Sat, 11 Sep 2010 01:27:29 +0000 (+0000) Subject: Fixes an obscure bug in importd block variable layout X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c5904b40c3d76b612fb09c6d2717f646a0af6670;p=clang Fixes an obscure bug in importd block variable layout information when imported variable is used more than once. Originally though to be a bug in importing block varibles. Fixes radar 8417746. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@113675 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp index 04f1ef24b2..d4e703ce03 100644 --- a/lib/CodeGen/CGBlocks.cpp +++ b/lib/CodeGen/CGBlocks.cpp @@ -757,7 +757,7 @@ CodeGenFunction::GenerateBlockFunction(GlobalDecl GD, const BlockExpr *BExpr, // Capture block layout info. here. if (CGM.getContext().getLangOptions().ObjC1) - BlockVarLayout = CGM.getObjCRuntime().GCBlockLayout(*this, Info.DeclRefs); + BlockVarLayout = CGM.getObjCRuntime().GCBlockLayout(*this, BlockLayout); else BlockVarLayout = llvm::Constant::getNullValue(PtrToInt8Ty); diff --git a/lib/CodeGen/CGObjCGNU.cpp b/lib/CodeGen/CGObjCGNU.cpp index d7960beb1d..0b3e31db04 100644 --- a/lib/CodeGen/CGObjCGNU.cpp +++ b/lib/CodeGen/CGObjCGNU.cpp @@ -213,7 +213,7 @@ public: const ObjCInterfaceDecl *Interface, const ObjCIvarDecl *Ivar); virtual llvm::Constant *GCBlockLayout(CodeGen::CodeGenFunction &CGF, - const llvm::SmallVectorImpl &) { + const llvm::SmallVectorImpl &) { return NULLPtr; } }; diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp index 8254135686..73074b6bbe 100644 --- a/lib/CodeGen/CGObjCMac.cpp +++ b/lib/CodeGen/CGObjCMac.cpp @@ -1000,7 +1000,7 @@ public: /// definition is seen. The return value has type ProtocolPtrTy. virtual llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD)=0; virtual llvm::Constant *GCBlockLayout(CodeGen::CodeGenFunction &CGF, - const llvm::SmallVectorImpl &); + const llvm::SmallVectorImpl &); }; @@ -1663,11 +1663,11 @@ static Qualifiers::GC GetGCAttrTypeForType(ASTContext &Ctx, QualType FQT) { } llvm::Constant *CGObjCCommonMac::GCBlockLayout(CodeGen::CodeGenFunction &CGF, - const llvm::SmallVectorImpl &DeclRefs) { + const llvm::SmallVectorImpl &BlockLayout) { llvm::Constant *NullPtr = llvm::Constant::getNullValue(llvm::Type::getInt8PtrTy(VMContext)); if ((CGM.getLangOptions().getGCMode() == LangOptions::NonGC) || - DeclRefs.empty()) + BlockLayout.empty()) return NullPtr; bool hasUnion = false; SkipIvars.clear(); @@ -1678,8 +1678,11 @@ llvm::Constant *CGObjCCommonMac::GCBlockLayout(CodeGen::CodeGenFunction &CGF, // __isa is the first field in block descriptor and must assume by runtime's // convention that it is GC'able. IvarsInfo.push_back(GC_IVAR(0, 1)); - for (size_t i = 0; i < DeclRefs.size(); ++i) { - const BlockDeclRefExpr *BDRE = DeclRefs[i]; + for (size_t i = 0; i < BlockLayout.size(); ++i) { + const Expr *E = BlockLayout[i]; + const BlockDeclRefExpr *BDRE = dyn_cast(E); + if (!BDRE) + continue; const ValueDecl *VD = BDRE->getDecl(); CharUnits Offset = CGF.BlockDecls[VD]; uint64_t FieldOffset = Offset.getQuantity(); diff --git a/lib/CodeGen/CGObjCRuntime.h b/lib/CodeGen/CGObjCRuntime.h index 584760f6f3..c9b0c6d10c 100644 --- a/lib/CodeGen/CGObjCRuntime.h +++ b/lib/CodeGen/CGObjCRuntime.h @@ -220,7 +220,7 @@ public: llvm::Value *SrcPtr, llvm::Value *Size) = 0; virtual llvm::Constant *GCBlockLayout(CodeGen::CodeGenFunction &CGF, - const llvm::SmallVectorImpl &) = 0; + const llvm::SmallVectorImpl &) = 0; }; diff --git a/test/CodeGenObjC/block-var-layout.m b/test/CodeGenObjC/block-var-layout.m index f57d7d99cd..c2a01d35fe 100644 --- a/test/CodeGenObjC/block-var-layout.m +++ b/test/CodeGenObjC/block-var-layout.m @@ -107,6 +107,23 @@ c(); } +// rdar: //8417746 +void CFRelease(id); +void notifyBlock(id dependentBlock) { + id singleObservationToken; + id token; + void (^b)(); + void (^wrapperBlock)() = ^() { + CFRelease(singleObservationToken); + CFRelease(singleObservationToken); + CFRelease(token); + CFRelease(singleObservationToken); + b(); + }; + wrapperBlock(); +} + + // CHECK-LP64: L_OBJC_CLASS_NAME_: // CHECK-LP64-NEXT: .asciz "\0011\024" @@ -121,3 +138,6 @@ c(); // CHECK-LP64: L_OBJC_CLASS_NAME_14: // CHECK-LP64-NEXT: .asciz "\001A\021\022p" + +// CHECK-LP64: L_OBJC_CLASS_NAME_16: +// CHECK-LP64-NEXT: .asciz "\0013"