]> granicus.if.org Git - clang/commitdiff
Fixup codegen for block literals that bleed copy/dispose information
authorMike Stump <mrs@apple.com>
Wed, 25 Mar 2009 17:58:24 +0000 (17:58 +0000)
committerMike Stump <mrs@apple.com>
Wed, 25 Mar 2009 17:58:24 +0000 (17:58 +0000)
from previous block literals.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@67696 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGBlocks.cpp
lib/CodeGen/CodeGenFunction.h
test/CodeGen/blocks-1.c

index 5780fc2958f1ccc00ffac26b394de6f566e8a5bc..eba741bc3c43e756306053e599c575f24e82cfcc 100644 (file)
@@ -35,7 +35,8 @@ Enable__block("f__block",
               llvm::cl::init(true));
 
 llvm::Constant *CodeGenFunction::
-BuildDescriptorBlockDecl(uint64_t Size, const llvm::StructType* Ty,
+BuildDescriptorBlockDecl(bool BlockHasCopyDispose, uint64_t Size,
+                         const llvm::StructType* Ty,
                          std::vector<HelperInfo> *NoteForHelper) {
   const llvm::Type *UnsignedLongTy
     = CGM.getTypes().ConvertType(getContext().UnsignedLongTy);
@@ -155,18 +156,20 @@ llvm::Value *CodeGenFunction::BuildBlockLiteralTmp(const BlockExpr *BE) {
     // __invoke
     uint64_t subBlockSize, subBlockAlign;
     llvm::SmallVector<const Expr *, 8> subBlockDeclRefDecls;
+    bool subBlockHasCopyDispose = false;
     llvm::Function *Fn
       = CodeGenFunction(CGM).GenerateBlockFunction(BE, Info, CurFuncDecl, LocalDeclMap,
                                                    subBlockSize,
                                                    subBlockAlign,
                                                    subBlockDeclRefDecls,
-                                                   BlockHasCopyDispose);
+                                                   subBlockHasCopyDispose);
+    BlockHasCopyDispose |= subBlockHasCopyDispose;
     Elts[3] = Fn;
 
     if (!Enable__block && BlockHasCopyDispose)
       ErrorUnsupported(BE, "block literal that requires copy/dispose");
 
-    if (BlockHasCopyDispose)
+    if (subBlockHasCopyDispose)
       flags |= BLOCK_HAS_COPY_DISPOSE;
 
     // __isa
@@ -186,7 +189,8 @@ llvm::Value *CodeGenFunction::BuildBlockLiteralTmp(const BlockExpr *BE) {
 
     if (subBlockDeclRefDecls.size() == 0) {
       // __descriptor
-      Elts[4] = BuildDescriptorBlockDecl(subBlockSize, 0, 0);
+      assert(subBlockHasCopyDispose == false);
+      Elts[4] = BuildDescriptorBlockDecl(subBlockHasCopyDispose, subBlockSize, 0, 0);
 
       // Optimize to being a global block.
       Elts[0] = CGM.getNSConcreteGlobalBlock();
@@ -318,7 +322,8 @@ llvm::Value *CodeGenFunction::BuildBlockLiteralTmp(const BlockExpr *BE) {
     NoteForHelper.resize(helpersize);
 
     // __descriptor
-    llvm::Value *Descriptor = BuildDescriptorBlockDecl(subBlockSize, Ty,
+    llvm::Value *Descriptor = BuildDescriptorBlockDecl(subBlockHasCopyDispose,
+                                                       subBlockSize, Ty,
                                                        &NoteForHelper);
     Descriptor = Builder.CreateBitCast(Descriptor, PtrToInt8Ty);
     Builder.CreateStore(Descriptor, Builder.CreateStructGEP(V, 4, "block.tmp"));
index acac86d8c2bad24e060379f527eddb706a7d16da..f850cfdc5bc34d3a4334b9654f66fbfd41906efc 100644 (file)
@@ -267,7 +267,8 @@ public:
   //===--------------------------------------------------------------------===//
 
   llvm::Value *BuildBlockLiteralTmp(const BlockExpr *);
-  llvm::Constant *BuildDescriptorBlockDecl(uint64_t Size,
+  llvm::Constant *BuildDescriptorBlockDecl(bool BlockHasCopyDispose,
+                                           uint64_t Size,
                                            const llvm::StructType *,
                                            std::vector<HelperInfo> *);
 
index 5fbe76c15dffebf613206b4e09af80a3875aa8c2..d6fc15952083e4619b83f0e9e575acdd3a6d9891 100644 (file)
@@ -57,6 +57,7 @@ void test5() {
 void test6() {
   __block int i;
   ^{ i=1; }();
+ ^{};
 }
 
 int main() {