diff options
author | Fariborz Jahanian <fjahanian@apple.com> | 2010-05-04 00:26:07 +0000 |
---|---|---|
committer | Fariborz Jahanian <fjahanian@apple.com> | 2010-05-04 00:26:07 +0000 |
commit | 3c347f25b507740c3e41de70819f8fbbee4cde89 (patch) | |
tree | a54b07f89851dbc6ab120588ac2fa17d355defc1 | |
parent | e7089b0c6ffe8a8854150b60df00fb544099f77d (diff) |
Fixes a Code Gen. Crash when calling destructor on a __block
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
-rw-r--r-- | lib/CodeGen/CGDecl.cpp | 13 | ||||
-rw-r--r-- | test/CodeGenCXX/block-destruct.cpp | 9 |
2 files changed, 18 insertions, 4 deletions
diff --git a/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp index 244a5323d4..ba3a2b47ed 100644 --- a/lib/CodeGen/CGDecl.cpp +++ b/lib/CodeGen/CGDecl.cpp @@ -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 index 0000000000..f809ca2699 --- /dev/null +++ b/test/CodeGenCXX/block-destruct.cpp @@ -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 |