]> granicus.if.org Git - clang/commitdiff
__block variables require us to evaluate the RHS of an assignment before
authorJohn McCall <rjmccall@apple.com>
Mon, 6 Dec 2010 06:10:02 +0000 (06:10 +0000)
committerJohn McCall <rjmccall@apple.com>
Mon, 6 Dec 2010 06:10:02 +0000 (06:10 +0000)
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

lib/CodeGen/CGExpr.cpp
lib/CodeGen/CGExprAgg.cpp
lib/CodeGen/CGExprComplex.cpp
test/CodeGenCXX/volatile-1.cpp

index 011233c58f4fae2c2b0d77d61c743d2f305b6172..6cc573c0cfc7cafc01f7375642a520d2d06a3e5d 100644 (file)
@@ -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;
   }
 
index 73bb9ef3fb799e3f004e2f0c418ef9541c81eaf2..ffe1739a0ecd296451edcbadfa5165c51b0029bd 100644 (file)
@@ -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
index 89a3a26ed61c6fa143e9c88d76a96e57c1b3bcf9..7896504d86b2a283e9cd3aff220e037162e81a71 100644 (file)
@@ -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.
index ba43471abf1e1d888b6be0aed124057e6e426c69..0569150101c7c1d6bf6e10cc030ae2141d495edc 100644 (file)
@@ -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