]> granicus.if.org Git - clang/commitdiff
Fixes a Code Gen. Crash when calling destructor on a __block
authorFariborz Jahanian <fjahanian@apple.com>
Tue, 4 May 2010 00:26:07 +0000 (00:26 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Tue, 4 May 2010 00:26:07 +0000 (00:26 +0000)
variabe. Blocks and their construction/destruction is
wip though.

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

lib/CodeGen/CGDecl.cpp
test/CodeGenCXX/block-destruct.cpp [new file with mode: 0644]

index 244a5323d4b23858cc778d0775d7043ad02b416f..ba3a2b47edb4b1fa2eb8aa1707eb05f6e4e66c26 100644 (file)
@@ -649,6 +649,11 @@ void CodeGenFunction::EmitLocalBlockVarDecl(const VarDecl &D) {
     DtorTy = getContext().getBaseElementType(Array);
   if (const RecordType *RT = DtorTy->getAs<RecordType>())
     if (CXXRecordDecl *ClassDecl = dyn_cast<CXXRecordDecl>(RT->getDecl())) {
+      llvm::Value *Loc = DeclPtr;
+      if (isByRef)
+        Loc = Builder.CreateStructGEP(DeclPtr, getByRefValueLLVMField(&D), 
+                                      D.getNameAsString());
+      
       if (!ClassDecl->hasTrivialDestructor()) {
         const CXXDestructorDecl *D = ClassDecl->getDestructor(getContext());
         assert(D && "EmitLocalBlockVarDecl - destructor is nul");
@@ -661,7 +666,7 @@ void CodeGenFunction::EmitLocalBlockVarDecl(const VarDecl &D) {
             const llvm::Type *BasePtr = ConvertType(BaseElementTy);
             BasePtr = llvm::PointerType::getUnqual(BasePtr);
             llvm::Value *BaseAddrPtr =
-              Builder.CreateBitCast(DeclPtr, BasePtr);
+              Builder.CreateBitCast(Loc, BasePtr);
             EmitCXXAggrDestructorCall(D, Array, BaseAddrPtr);
           
             // Make sure to jump to the exit block.
@@ -673,14 +678,14 @@ void CodeGenFunction::EmitLocalBlockVarDecl(const VarDecl &D) {
             const llvm::Type *BasePtr = ConvertType(BaseElementTy);
             BasePtr = llvm::PointerType::getUnqual(BasePtr);
             llvm::Value *BaseAddrPtr =
-              Builder.CreateBitCast(DeclPtr, BasePtr);
+              Builder.CreateBitCast(Loc, BasePtr);
             EmitCXXAggrDestructorCall(D, Array, BaseAddrPtr);
           }
         } else {
           {
             DelayedCleanupBlock Scope(*this);
             EmitCXXDestructorCall(D, Dtor_Complete, /*ForVirtualBase=*/false,
-                                  DeclPtr);
+                                  Loc);
 
             // Make sure to jump to the exit block.
             EmitBranch(Scope.getCleanupExitBlock());
@@ -688,7 +693,7 @@ void CodeGenFunction::EmitLocalBlockVarDecl(const VarDecl &D) {
           if (Exceptions) {
             EHCleanupBlock Cleanup(*this);
             EmitCXXDestructorCall(D, Dtor_Complete, /*ForVirtualBase=*/false,
-                                  DeclPtr);
+                                  Loc);
           }
         }
       }
diff --git a/test/CodeGenCXX/block-destruct.cpp b/test/CodeGenCXX/block-destruct.cpp
new file mode 100644 (file)
index 0000000..f809ca2
--- /dev/null
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 %s -fblocks -triple x86_64-apple-darwin -emit-llvm -o - | FileCheck %s
+
+struct A { ~A(); };
+
+void f() {
+  __block A a;
+}
+
+// CHECK: call void @_ZN1AD1Ev