[cfe-commits] r140867 - in /cfe/trunk: lib/CodeGen/CGExpr.cpp test/CodeGenObjC/objc2-write-barrier-5.m

Fariborz Jahanian fjahanian at apple.com
Fri Sep 30 11:23:36 PDT 2011


Author: fjahanian
Date: Fri Sep 30 13:23:36 2011
New Revision: 140867

URL: http://llvm.org/viewvc/llvm-project?rev=140867&view=rev
Log:
objc gc: assigning to an objc object struct member through an ivar 
pointer to this struct must go through the none ivar writer barrier.

Modified:
    cfe/trunk/lib/CodeGen/CGExpr.cpp
    cfe/trunk/test/CodeGenObjC/objc2-write-barrier-5.m

Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=140867&r1=140866&r2=140867&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExpr.cpp Fri Sep 30 13:23:36 2011
@@ -1213,11 +1213,23 @@
 // generating write-barries API. It is currently a global, ivar,
 // or neither.
 static void setObjCGCLValueClass(const ASTContext &Ctx, const Expr *E,
-                                 LValue &LV) {
+                                 LValue &LV,
+                                 bool IsMemberAccess=false) {
   if (Ctx.getLangOptions().getGC() == LangOptions::NonGC)
     return;
   
   if (isa<ObjCIvarRefExpr>(E)) {
+    QualType ExpTy = E->getType();
+    if (IsMemberAccess && ExpTy->isPointerType()) {
+      // If ivar is a structure pointer, assigning to field of
+      // this struct follows gcc's behavior and makes it a non-ivar 
+      // writer-barrier conservatively.
+      ExpTy = ExpTy->getAs<PointerType>()->getPointeeType();
+      if (ExpTy->isRecordType()) {
+        LV.setObjCIvar(false);
+        return;
+      }
+    }
     LV.setObjCIvar(true);
     ObjCIvarRefExpr *Exp = cast<ObjCIvarRefExpr>(const_cast<Expr*>(E));
     LV.setBaseIvarExp(Exp->getBase());
@@ -1237,12 +1249,12 @@
   }
   
   if (const UnaryOperator *Exp = dyn_cast<UnaryOperator>(E)) {
-    setObjCGCLValueClass(Ctx, Exp->getSubExpr(), LV);
+    setObjCGCLValueClass(Ctx, Exp->getSubExpr(), LV, IsMemberAccess);
     return;
   }
   
   if (const ParenExpr *Exp = dyn_cast<ParenExpr>(E)) {
-    setObjCGCLValueClass(Ctx, Exp->getSubExpr(), LV);
+    setObjCGCLValueClass(Ctx, Exp->getSubExpr(), LV, IsMemberAccess);
     if (LV.isObjCIvar()) {
       // If cast is to a structure pointer, follow gcc's behavior and make it
       // a non-ivar write-barrier.
@@ -1261,17 +1273,17 @@
   }
 
   if (const ImplicitCastExpr *Exp = dyn_cast<ImplicitCastExpr>(E)) {
-    setObjCGCLValueClass(Ctx, Exp->getSubExpr(), LV);
+    setObjCGCLValueClass(Ctx, Exp->getSubExpr(), LV, IsMemberAccess);
     return;
   }
   
   if (const CStyleCastExpr *Exp = dyn_cast<CStyleCastExpr>(E)) {
-    setObjCGCLValueClass(Ctx, Exp->getSubExpr(), LV);
+    setObjCGCLValueClass(Ctx, Exp->getSubExpr(), LV, IsMemberAccess);
     return;
   }
 
   if (const ObjCBridgedCastExpr *Exp = dyn_cast<ObjCBridgedCastExpr>(E)) {
-    setObjCGCLValueClass(Ctx, Exp->getSubExpr(), LV);
+    setObjCGCLValueClass(Ctx, Exp->getSubExpr(), LV, IsMemberAccess);
     return;
   }
 
@@ -1287,9 +1299,9 @@
       LV.setGlobalObjCRef(false);
     return;
   }
-  
+
   if (const MemberExpr *Exp = dyn_cast<MemberExpr>(E)) {
-    setObjCGCLValueClass(Ctx, Exp->getBase(), LV);
+    setObjCGCLValueClass(Ctx, Exp->getBase(), LV, true);
     // We don't know if member is an 'ivar', but this flag is looked at
     // only in the context of LV.isObjCIvar().
     LV.setObjCArray(E->getType()->isArrayType());

Modified: cfe/trunk/test/CodeGenObjC/objc2-write-barrier-5.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/objc2-write-barrier-5.m?rev=140867&r1=140866&r2=140867&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenObjC/objc2-write-barrier-5.m (original)
+++ cfe/trunk/test/CodeGenObjC/objc2-write-barrier-5.m Fri Sep 30 13:23:36 2011
@@ -1,9 +1,9 @@
 // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-gc -emit-llvm -o %t %s
 // RUN: grep objc_assign_ivar %t | count 0
-// RUN: grep objc_assign_strongCast %t | count 5
+// RUN: grep objc_assign_strongCast %t | count 8
 // RUN: %clang_cc1 -x objective-c++ -triple x86_64-apple-darwin10 -fobjc-gc -emit-llvm -o %t %s
 // RUN: grep objc_assign_ivar %t | count 0
-// RUN: grep objc_assign_strongCast %t | count 5
+// RUN: grep objc_assign_strongCast %t | count 8
 
 @interface TestUnarchiver 
 {
@@ -27,3 +27,20 @@
 }
 
 @end
+
+// rdar://10191569
+ at interface I
+{
+  struct S {
+    id _timer;
+  } *p_animationState;
+}
+ at end
+
+ at implementation I
+- (void) Meth {
+  p_animationState->_timer = 0;
+  (*p_animationState)._timer = 0;
+  (&(*p_animationState))->_timer = 0;
+}
+ at end





More information about the cfe-commits mailing list