summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2010-09-03 21:36:02 +0000
committerFariborz Jahanian <fjahanian@apple.com>2010-09-03 21:36:02 +0000
commit7925561e702430c0d632c5e5db1a74673b44ea18 (patch)
treeca9145927530b5e5d918f9651c9571852809fc69
parenta96a6906601cb5f40ba54cd750c9f87e04568f7d (diff)
Cope with llvm's reference to bool type of 'i1' vs. clang's
type of 'i8' for the same for __block variables of type bool. refixes radar 8382559. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@113015 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/CodeGen/CGExpr.cpp17
-rw-r--r--test/SemaCXX/blocks.cpp20
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;
+ }
+}