[cfe-commits] r130545 - in /cfe/trunk: lib/CodeGen/CGExprAgg.cpp test/CodeGen/block-byref-aggr.c

Fariborz Jahanian fjahanian at apple.com
Fri Apr 29 14:53:21 PDT 2011


Author: fjahanian
Date: Fri Apr 29 16:53:21 2011
New Revision: 130545

URL: http://llvm.org/viewvc/llvm-project?rev=130545&view=rev
Log:
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

Added:
    cfe/trunk/test/CodeGen/block-byref-aggr.c
Modified:
    cfe/trunk/lib/CodeGen/CGExprAgg.cpp

Modified: cfe/trunk/lib/CodeGen/CGExprAgg.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprAgg.cpp?rev=130545&r1=130544&r2=130545&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprAgg.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprAgg.cpp Fri Apr 29 16:53:21 2011
@@ -393,7 +393,24 @@
                                                  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

Added: cfe/trunk/test/CodeGen/block-byref-aggr.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/block-byref-aggr.c?rev=130545&view=auto
==============================================================================
--- cfe/trunk/test/CodeGen/block-byref-aggr.c (added)
+++ cfe/trunk/test/CodeGen/block-byref-aggr.c Fri Apr 29 16:53:21 2011
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - -fblocks -triple x86_64-apple-darwin10 | FileCheck %s
+// rdar://9309454
+
+typedef struct { int v; } RetType;
+
+RetType func();
+
+int main () {
+ __attribute__((__blocks__(byref))) RetType a = {100};
+
+ a = func();
+}
+// CHECK: [[C1:%.*]] = call i32 (...)* @func()
+// CHECK-NEXT: [[CO:%.*]] = getelementptr
+// CHECK-NEXT: store i32 [[C1]], i32* [[CO]]
+// CHECK-NEXT: [[FORWARDING:%.*]] = getelementptr inbounds [[BR:%.*]]* [[A:%.*]], i32 0, i32 1
+// CHECK-NEXT: [[O:%.*]] = load [[BR]]** [[FORWARDING]]





More information about the cfe-commits mailing list