summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2011-04-29 21:53:21 +0000
committerFariborz Jahanian <fjahanian@apple.com>2011-04-29 21:53:21 +0000
commit99514b9168f6b6d8b2a31cdfa722f46c1055fd05 (patch)
tree5f65d99e917998726ac993d2579b81111c773853 /clang/lib/CodeGen
parent6a85f9b42e6c6656843c375ae050d82a7b6b4a91 (diff)
downloadbcm5719-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.cpp19
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
OpenPOWER on IntegriCloud