diff options
author | Fariborz Jahanian <fjahanian@apple.com> | 2011-04-29 21:53:21 +0000 |
---|---|---|
committer | Fariborz Jahanian <fjahanian@apple.com> | 2011-04-29 21:53:21 +0000 |
commit | 99514b9168f6b6d8b2a31cdfa722f46c1055fd05 (patch) | |
tree | 5f65d99e917998726ac993d2579b81111c773853 /clang/lib/CodeGen | |
parent | 6a85f9b42e6c6656843c375ae050d82a7b6b4a91 (diff) | |
download | bcm5719-llvm-99514b9168f6b6d8b2a31cdfa722f46c1055fd05.tar.gz bcm5719-llvm-99514b9168f6b6d8b2a31cdfa722f46c1055fd05.zip |
block variables on lhs need be ir-gen'ed after the
rhs when its 'forwarding' pointer may be modified
in rhs evaluation as result of call to Block_copy.
// rdar://9309454
llvm-svn: 130545
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r-- | clang/lib/CodeGen/CGExprAgg.cpp | 19 |
1 files changed, 18 insertions, 1 deletions
diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp index 87d3819e489..2f2f7c1fe55 100644 --- a/clang/lib/CodeGen/CGExprAgg.cpp +++ b/clang/lib/CodeGen/CGExprAgg.cpp @@ -393,7 +393,24 @@ void AggExprEmitter::VisitBinAssign(const BinaryOperator *E) { E->getRHS()->getType()) && "Invalid assignment"); - // FIXME: __block variables need the RHS evaluated first! + if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E->getLHS())) + if (const VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl())) { + if (VD->hasAttr<BlocksAttr>() && + E->getRHS()->HasSideEffects(CGF.getContext())) { + // When __block variable on LHS, the RHS must be evaluated first + // as it may change the 'forwarding' field via call to Block_copy. + LValue RHS = CGF.EmitLValue(E->getRHS()); + LValue LHS = CGF.EmitLValue(E->getLHS()); + bool GCollection = false; + if (CGF.getContext().getLangOptions().getGCMode()) + GCollection = TypeRequiresGCollection(E->getLHS()->getType()); + // Codegen the RHS so that it stores directly into the LHS. + Dest = AggValueSlot::forLValue(LHS, true, GCollection); + EmitFinalDestCopy(E, RHS, true); + return; + } + } + LValue LHS = CGF.EmitLValue(E->getLHS()); // We have to special case property setters, otherwise we must have |