diff options
-rw-r--r-- | lib/CodeGen/CGExpr.cpp | 17 | ||||
-rw-r--r-- | test/SemaCXX/blocks.cpp | 20 |
2 files changed, 37 insertions, 0 deletions
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index 06c657fa92..b4d0e13993 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -335,6 +335,23 @@ CodeGenFunction::EmitReferenceBindingToExpr(const Expr* E, llvm::Value *Value = EmitExprForReferenceBinding(*this, E, ReferenceTemporary, ReferenceTemporaryDtor, InitializedDecl); + if (E->getType()->isBooleanType()) { + // special handling for __block variable of bool type bound to + // a reference type. + bool block_byref_var = false; + if (const BlockDeclRefExpr *BE = dyn_cast<BlockDeclRefExpr>(E)) + block_byref_var = BE->isByRef(); + else if (const DeclRefExpr *BD = dyn_cast<DeclRefExpr>(E)) { + const NamedDecl *ND = BD->getDecl(); + if (const VarDecl *VD = dyn_cast<VarDecl>(ND)) + block_byref_var = VD->hasAttr<BlocksAttr>(); + } + if (block_byref_var) { + const llvm::Type *T = ConvertTypeForMem(E->getType()); + T = llvm::PointerType::getUnqual(T); + Value = Builder.CreateBitCast(Value, T); + } + } if (!ReferenceTemporaryDtor) return RValue::get(Value); diff --git a/test/SemaCXX/blocks.cpp b/test/SemaCXX/blocks.cpp index baa79e7d89..4fd9941a2e 100644 --- a/test/SemaCXX/blocks.cpp +++ b/test/SemaCXX/blocks.cpp @@ -41,3 +41,23 @@ namespace test2 { return Power(2).calculate(10); } } + +// rdar: // 8382559 +namespace radar8382559 { + void func(bool& outHasProperty); + + int test3() { + __attribute__((__blocks__(byref))) bool hasProperty = false; + bool (^b)() = ^ { + func(hasProperty); + if (hasProperty) + hasProperty = 0; + return hasProperty; + }; + func(hasProperty); + b(); + if (hasProperty) + hasProperty = 1; + return hasProperty = 1; + } +} |