diff options
-rw-r--r-- | lib/CodeGen/CGBlocks.cpp | 2 | ||||
-rw-r--r-- | test/CodeGenCXX/reference-in-blocks.cpp | 24 |
2 files changed, 25 insertions, 1 deletions
diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp index db24def216..8082b33fd6 100644 --- a/lib/CodeGen/CGBlocks.cpp +++ b/lib/CodeGen/CGBlocks.cpp @@ -532,6 +532,8 @@ llvm::Value *CodeGenFunction::GetAddrOfBlockDecl(const BlockDeclRefExpr *E) { V = Builder.CreateBitCast(V, PtrStructTy); V = Builder.CreateStructGEP(V, getByRefValueLLVMField(VD), VD->getNameAsString()); + if (VD->getType()->isReferenceType()) + V = Builder.CreateLoad(V); } else { const llvm::Type *Ty = CGM.getTypes().ConvertType(VD->getType()); diff --git a/test/CodeGenCXX/reference-in-blocks.cpp b/test/CodeGenCXX/reference-in-blocks.cpp index c020bab0f7..388ec7c4bb 100644 --- a/test/CodeGenCXX/reference-in-blocks.cpp +++ b/test/CodeGenCXX/reference-in-blocks.cpp @@ -9,6 +9,26 @@ T _i; T get() {return _i;}; }; +// rdar: // 7495203 +class A { + public: + A() : field(10), d1(3.14) {} + void F(); + void S() { + printf(" field = %d\n", field); + printf(" field = %f\n", d1); + } + int field; + double d1; +}; + +void A::F() + { + __block A &tlc = *this; + // crashed in code gen (radar 7495203) + ^{ tlc.S(); }(); + } + int main() { // works @@ -16,6 +36,8 @@ int main() { //crashes in godegen? void (^bl2)(range<int>& ) = ^(range<int>& i){printf("Hello Blocks %d\n", i.get()); }; + + A *a = new A; + a->F(); return 0; } - |