From: Mike Stump Date: Fri, 10 Apr 2009 18:52:28 +0000 (+0000) Subject: Fixup codegen for nested blocks that use copy/dispose in the inner X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b7477cf6cf6cf4f132ba7beff42684e59bed15f4;p=clang Fixup codegen for nested blocks that use copy/dispose in the inner blocks, so that the outer blocks use it as well. Radar 6762279 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@68811 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp index a623cf18cf..4e9419ed20 100644 --- a/lib/CodeGen/CGBlocks.cpp +++ b/lib/CodeGen/CGBlocks.cpp @@ -48,10 +48,10 @@ BuildDescriptorBlockDecl(bool BlockHasCopyDispose, uint64_t Size, if (BlockHasCopyDispose) { // copy_func_helper_decl - Elts.push_back(BuildCopyHelper(Ty, *NoteForHelper)); + Elts.push_back(BuildCopyHelper(Ty, NoteForHelper)); // destroy_func_decl - Elts.push_back(BuildDestroyHelper(Ty, *NoteForHelper)); + Elts.push_back(BuildDestroyHelper(Ty, NoteForHelper)); } C = llvm::ConstantStruct::get(Elts); @@ -178,7 +178,6 @@ llvm::Value *CodeGenFunction::BuildBlockLiteralTmp(const BlockExpr *BE) { if (subBlockDeclRefDecls.size() == 0) { // __descriptor - assert(subBlockHasCopyDispose == false); Elts[4] = BuildDescriptorBlockDecl(subBlockHasCopyDispose, subBlockSize, 0, 0); // Optimize to being a global block. @@ -714,7 +713,7 @@ uint64_t BlockFunction::getBlockOffset(const BlockDeclRefExpr *BDRE) { llvm::Constant *BlockFunction:: GenerateCopyHelperFunction(bool BlockHasCopyDispose, const llvm::StructType *T, - std::vector &NoteForHelper) { + std::vector *NoteForHelperp) { QualType R = getContext().VoidTy; FunctionArgList Args; @@ -752,31 +751,36 @@ GenerateCopyHelperFunction(bool BlockHasCopyDispose, const llvm::StructType *T, llvm::Value *SrcObj = CGF.GetAddrOfLocalVar(Src); llvm::Type *PtrPtrT; - PtrPtrT = llvm::PointerType::get(llvm::PointerType::get(T, 0), 0); - SrcObj = Builder.CreateBitCast(SrcObj, PtrPtrT); - SrcObj = Builder.CreateLoad(SrcObj); - - llvm::Value *DstObj = CGF.GetAddrOfLocalVar(Dst); - DstObj = Builder.CreateBitCast(DstObj, llvm::PointerType::get(T, 0)); - - for (unsigned i=0; i < NoteForHelper.size(); ++i) { - int flag = NoteForHelper[i].flag; - int index = NoteForHelper[i].index; - - if ((NoteForHelper[i].flag & BLOCK_FIELD_IS_BYREF) - || NoteForHelper[i].RequiresCopying) { - llvm::Value *Srcv = SrcObj; - Srcv = Builder.CreateStructGEP(Srcv, index); - Srcv = Builder.CreateBitCast(Srcv, - llvm::PointerType::get(PtrToInt8Ty, 0)); - Srcv = Builder.CreateLoad(Srcv); - - llvm::Value *Dstv = Builder.CreateStructGEP(DstObj, index); - Dstv = Builder.CreateBitCast(Dstv, PtrToInt8Ty); - - llvm::Value *N = llvm::ConstantInt::get(llvm::Type::Int32Ty, flag); - llvm::Value *F = getBlockObjectAssign(); - Builder.CreateCall3(F, Dstv, Srcv, N); + + if (NoteForHelperp) { + std::vector &NoteForHelper = *NoteForHelperp; + + PtrPtrT = llvm::PointerType::get(llvm::PointerType::get(T, 0), 0); + SrcObj = Builder.CreateBitCast(SrcObj, PtrPtrT); + SrcObj = Builder.CreateLoad(SrcObj); + + llvm::Value *DstObj = CGF.GetAddrOfLocalVar(Dst); + DstObj = Builder.CreateBitCast(DstObj, llvm::PointerType::get(T, 0)); + + for (unsigned i=0; i < NoteForHelper.size(); ++i) { + int flag = NoteForHelper[i].flag; + int index = NoteForHelper[i].index; + + if ((NoteForHelper[i].flag & BLOCK_FIELD_IS_BYREF) + || NoteForHelper[i].RequiresCopying) { + llvm::Value *Srcv = SrcObj; + Srcv = Builder.CreateStructGEP(Srcv, index); + Srcv = Builder.CreateBitCast(Srcv, + llvm::PointerType::get(PtrToInt8Ty, 0)); + Srcv = Builder.CreateLoad(Srcv); + + llvm::Value *Dstv = Builder.CreateStructGEP(DstObj, index); + Dstv = Builder.CreateBitCast(Dstv, PtrToInt8Ty); + + llvm::Value *N = llvm::ConstantInt::get(llvm::Type::Int32Ty, flag); + llvm::Value *F = getBlockObjectAssign(); + Builder.CreateCall3(F, Dstv, Srcv, N); + } } } @@ -788,7 +792,7 @@ GenerateCopyHelperFunction(bool BlockHasCopyDispose, const llvm::StructType *T, llvm::Constant *BlockFunction:: GenerateDestroyHelperFunction(bool BlockHasCopyDispose, const llvm::StructType* T, - std::vector &NoteForHelper) { + std::vector *NoteForHelperp) { QualType R = getContext().VoidTy; FunctionArgList Args; @@ -821,25 +825,29 @@ GenerateDestroyHelperFunction(bool BlockHasCopyDispose, true); CGF.StartFunction(FD, R, Fn, Args, SourceLocation()); - llvm::Value *SrcObj = CGF.GetAddrOfLocalVar(Src); - llvm::Type *PtrPtrT; - PtrPtrT = llvm::PointerType::get(llvm::PointerType::get(T, 0), 0); - SrcObj = Builder.CreateBitCast(SrcObj, PtrPtrT); - SrcObj = Builder.CreateLoad(SrcObj); - - for (unsigned i=0; i < NoteForHelper.size(); ++i) { - int flag = NoteForHelper[i].flag; - int index = NoteForHelper[i].index; - - if ((NoteForHelper[i].flag & BLOCK_FIELD_IS_BYREF) - || NoteForHelper[i].RequiresCopying) { - llvm::Value *Srcv = SrcObj; - Srcv = Builder.CreateStructGEP(Srcv, index); - Srcv = Builder.CreateBitCast(Srcv, - llvm::PointerType::get(PtrToInt8Ty, 0)); - Srcv = Builder.CreateLoad(Srcv); - - BuildBlockRelease(Srcv, flag); + if (NoteForHelperp) { + std::vector &NoteForHelper = *NoteForHelperp; + + llvm::Value *SrcObj = CGF.GetAddrOfLocalVar(Src); + llvm::Type *PtrPtrT; + PtrPtrT = llvm::PointerType::get(llvm::PointerType::get(T, 0), 0); + SrcObj = Builder.CreateBitCast(SrcObj, PtrPtrT); + SrcObj = Builder.CreateLoad(SrcObj); + + for (unsigned i=0; i < NoteForHelper.size(); ++i) { + int flag = NoteForHelper[i].flag; + int index = NoteForHelper[i].index; + + if ((NoteForHelper[i].flag & BLOCK_FIELD_IS_BYREF) + || NoteForHelper[i].RequiresCopying) { + llvm::Value *Srcv = SrcObj; + Srcv = Builder.CreateStructGEP(Srcv, index); + Srcv = Builder.CreateBitCast(Srcv, + llvm::PointerType::get(PtrToInt8Ty, 0)); + Srcv = Builder.CreateLoad(Srcv); + + BuildBlockRelease(Srcv, flag); + } } } @@ -849,15 +857,15 @@ GenerateDestroyHelperFunction(bool BlockHasCopyDispose, } llvm::Constant *BlockFunction::BuildCopyHelper(const llvm::StructType *T, - std::vector &NoteForHelper) { + std::vector *NoteForHelper) { return CodeGenFunction(CGM).GenerateCopyHelperFunction(BlockHasCopyDispose, T, NoteForHelper); } llvm::Constant *BlockFunction::BuildDestroyHelper(const llvm::StructType *T, - std::vector &NoteForHelper) { + std::vector *NoteForHelperp) { return CodeGenFunction(CGM).GenerateDestroyHelperFunction(BlockHasCopyDispose, - T, NoteForHelper); + T, NoteForHelperp); } llvm::Constant *BlockFunction:: diff --git a/lib/CodeGen/CGBlocks.h b/lib/CodeGen/CGBlocks.h index 3eca891289..58276c294d 100644 --- a/lib/CodeGen/CGBlocks.h +++ b/lib/CodeGen/CGBlocks.h @@ -183,14 +183,14 @@ public: ImplicitParamDecl *getBlockStructDecl() { return BlockStructDecl; } llvm::Constant *GenerateCopyHelperFunction(bool, const llvm::StructType *, - std::vector &); + std::vector *); llvm::Constant *GenerateDestroyHelperFunction(bool, const llvm::StructType *, - std::vector &); + std::vector *); llvm::Constant *BuildCopyHelper(const llvm::StructType *, - std::vector &); + std::vector *); llvm::Constant *BuildDestroyHelper(const llvm::StructType *, - std::vector &); + std::vector *); llvm::Constant *GeneratebyrefCopyHelperFunction(const llvm::Type *, int flag); llvm::Constant *GeneratebyrefDestroyHelperFunction(const llvm::Type *T, int); diff --git a/test/CodeGen/blocks-1.c b/test/CodeGen/blocks-1.c index f2677f3c27..10498cb004 100644 --- a/test/CodeGen/blocks-1.c +++ b/test/CodeGen/blocks-1.c @@ -1,11 +1,11 @@ // RUN: clang-cc %s -emit-llvm -o %t -fblocks && -// RUN: grep "_Block_object_dispose" %t | count 15 && -// RUN: grep "__copy_helper_block_" %t | count 12 && -// RUN: grep "__destroy_helper_block_" %t | count 12 && +// RUN: grep "_Block_object_dispose" %t | count 17 && +// RUN: grep "__copy_helper_block_" %t | count 16 && +// RUN: grep "__destroy_helper_block_" %t | count 16 && // RUN: grep "__Block_byref_id_object_copy_" %t | count 2 && // RUN: grep "__Block_byref_id_object_dispose_" %t | count 2 && // RUN: grep "i32 135)" %t | count 2 && -// RUN: grep "_Block_object_assign" %t | count 9 +// RUN: grep "_Block_object_assign" %t | count 10 #include @@ -57,7 +57,14 @@ void test5() { void test6() { __block int i; ^{ i=1; }(); - ^{}; + ^{}(); +} + +void test7() { + ^{ + __block int i; + ^{ i = 1; }(); + }(); } int main() {