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.

llvm-svn: 113015
This commit is contained in:
Fariborz Jahanian 2010-09-03 21:36:02 +00:00
parent 367afb5a00
commit 9d798d13f3
2 changed files with 37 additions and 0 deletions

View File

@ -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);

View File

@ -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;
}
}