From 99514b9168f6b6d8b2a31cdfa722f46c1055fd05 Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Fri, 29 Apr 2011 21:53:21 +0000 Subject: 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 --- clang/lib/CodeGen/CGExprAgg.cpp | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'clang/lib/CodeGen') 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(E->getLHS())) + if (const VarDecl *VD = dyn_cast(DRE->getDecl())) { + if (VD->hasAttr() && + 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 -- cgit v1.2.3