From: John McCall Date: Mon, 6 Dec 2010 06:10:02 +0000 (+0000) Subject: __block variables require us to evaluate the RHS of an assignment before X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=cd940a1e13e588a43973cd7ae33b5c33a3062739;p=clang __block variables require us to evaluate the RHS of an assignment before the LHS, or else the pointer might be invalid. This is kindof dumb, but go ahead and make sure we're doing that for l-value scalar assignment, which fixes a miscompile of obj-c++.dg/block-seq.mm. Leave a FIXME for how to solve this problem for agg __blocks. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@120992 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index 011233c58f..6cc573c0cf 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -1951,10 +1951,10 @@ LValue CodeGenFunction::EmitBinaryOperatorLValue(const BinaryOperator *E) { assert(E->getOpcode() == BO_Assign && "unexpected binary l-value"); if (!hasAggregateLLVMType(E->getType())) { - // Emit the LHS as an l-value. + // __block variables need the RHS evaluated first. + RValue RV = EmitAnyExpr(E->getRHS()); LValue LV = EmitLValue(E->getLHS()); - // Store the value through the l-value. - EmitStoreThroughLValue(EmitAnyExpr(E->getRHS()), LV, E->getType()); + EmitStoreThroughLValue(RV, LV, E->getType()); return LV; } diff --git a/lib/CodeGen/CGExprAgg.cpp b/lib/CodeGen/CGExprAgg.cpp index 73bb9ef3fb..ffe1739a0e 100644 --- a/lib/CodeGen/CGExprAgg.cpp +++ b/lib/CodeGen/CGExprAgg.cpp @@ -389,6 +389,8 @@ void AggExprEmitter::VisitBinAssign(const BinaryOperator *E) { assert(CGF.getContext().hasSameUnqualifiedType(E->getLHS()->getType(), E->getRHS()->getType()) && "Invalid assignment"); + + // FIXME: __block variables need the RHS evaluated first! LValue LHS = CGF.EmitLValue(E->getLHS()); // We have to special case property setters, otherwise we must have diff --git a/lib/CodeGen/CGExprComplex.cpp b/lib/CodeGen/CGExprComplex.cpp index 89a3a26ed6..7896504d86 100644 --- a/lib/CodeGen/CGExprComplex.cpp +++ b/lib/CodeGen/CGExprComplex.cpp @@ -602,7 +602,7 @@ LValue ComplexExprEmitter::EmitBinAssignLValue(const BinaryOperator *E, TestAndClearIgnoreReal(); TestAndClearIgnoreImag(); - // Emit the RHS. + // Emit the RHS. __block variables need the RHS evaluated first. Val = Visit(E->getRHS()); // Compute the address to store into. diff --git a/test/CodeGenCXX/volatile-1.cpp b/test/CodeGenCXX/volatile-1.cpp index ba43471abf..0569150101 100644 --- a/test/CodeGenCXX/volatile-1.cpp +++ b/test/CodeGenCXX/volatile-1.cpp @@ -346,9 +346,9 @@ void test() { // CHECK-NEXT: volatile store {{.*}}, [[INT]]* @j (j=k,i)=i; + // CHECK-NEXT: volatile load [[INT]]* @i // CHECK-NEXT: volatile load [[INT]]* @k // CHECK-NEXT: volatile store {{.*}}, [[INT]]* @j - // CHECK-NEXT: volatile load [[INT]]* @i // CHECK-NEXT: volatile store {{.*}}, [[INT]]* @i // CHECK-NEXT: ret void