__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 011233c..6cc573c 100644
--- a/lib/CodeGen/CGExpr.cpp
+++ b/lib/CodeGen/CGExpr.cpp
@@ -1951,10 +1951,10 @@
   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 73bb9ef..ffe1739 100644
--- a/lib/CodeGen/CGExprAgg.cpp
+++ b/lib/CodeGen/CGExprAgg.cpp
@@ -389,6 +389,8 @@
   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 89a3a26..7896504 100644
--- a/lib/CodeGen/CGExprComplex.cpp
+++ b/lib/CodeGen/CGExprComplex.cpp
@@ -602,7 +602,7 @@
   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 ba43471..0569150 100644
--- a/test/CodeGenCXX/volatile-1.cpp
+++ b/test/CodeGenCXX/volatile-1.cpp
@@ -346,9 +346,9 @@
   // 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