]> granicus.if.org Git - clang/commitdiff
A corner case of objc2 gc's write-barrier generation
authorFariborz Jahanian <fjahanian@apple.com>
Mon, 1 Jun 2009 21:29:32 +0000 (21:29 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Mon, 1 Jun 2009 21:29:32 +0000 (21:29 +0000)
for the Next runtime.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@72703 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/Expr.h
lib/AST/Expr.cpp
lib/CodeGen/CGExpr.cpp
test/CodeGenObjC/objc2-strong-cast-2.m

index 92f2025cb4ddfd373ffaeb89608a8f535bdd99a2..98de5f9d382e75087c51cacf924e3f4bcd7b5479 100644 (file)
@@ -254,7 +254,7 @@ public:
 
   /// isOBJCGCCandidate - Return true if this expression may be used in a read/
   /// write barrier. 
-  bool isOBJCGCCandidate() const;
+  bool isOBJCGCCandidate(ASTContext &Ctx) const;
   
   /// IgnoreParens - Ignore parentheses.  If this Expr is a ParenExpr, return
   ///  its subexpression.  If that subexpression is also a ParenExpr, 
index aca5efeb16370077ecb44ae327310d07c8d0d92f..4a53a4123d111314ec0517762e8b8352b54344dc 100644 (file)
@@ -967,33 +967,41 @@ bool Expr::hasGlobalStorage() const {
 
 /// isOBJCGCCandidate - Check if an expression is objc gc'able.
 ///
-bool Expr::isOBJCGCCandidate() const {
+bool Expr::isOBJCGCCandidate(ASTContext &Ctx) const {
   switch (getStmtClass()) {
   default:
     return false;
   case ObjCIvarRefExprClass:
     return true;
   case Expr::UnaryOperatorClass:
-    return cast<UnaryOperator>(this)->getSubExpr()->isOBJCGCCandidate();
+    return cast<UnaryOperator>(this)->getSubExpr()->isOBJCGCCandidate(Ctx);
   case ParenExprClass:
-    return cast<ParenExpr>(this)->getSubExpr()->isOBJCGCCandidate();
+    return cast<ParenExpr>(this)->getSubExpr()->isOBJCGCCandidate(Ctx);
   case ImplicitCastExprClass:
-    return cast<ImplicitCastExpr>(this)->getSubExpr()->isOBJCGCCandidate();
+    return cast<ImplicitCastExpr>(this)->getSubExpr()->isOBJCGCCandidate(Ctx);
   case CStyleCastExprClass:
-    return cast<CStyleCastExpr>(this)->getSubExpr()->isOBJCGCCandidate();
+    return cast<CStyleCastExpr>(this)->getSubExpr()->isOBJCGCCandidate(Ctx);
   case DeclRefExprClass:
   case QualifiedDeclRefExprClass: {
     const Decl *D = cast<DeclRefExpr>(this)->getDecl();
-    if (const VarDecl *VD = dyn_cast<VarDecl>(D))
-      return VD->hasGlobalStorage();
+    if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
+      if (VD->hasGlobalStorage())
+        return true;
+      QualType T = VD->getType();
+      // dereferencing to an object pointer is always a gc'able candidate
+      if (T->isPointerType() && 
+          Ctx.isObjCObjectPointerType(T->getAsPointerType()->getPointeeType()))
+        return true;
+        
+    }
     return false;
   }
   case MemberExprClass: {
     const MemberExpr *M = cast<MemberExpr>(this);
-    return M->getBase()->isOBJCGCCandidate();
+    return M->getBase()->isOBJCGCCandidate(Ctx);
   }
   case ArraySubscriptExprClass:
-    return cast<ArraySubscriptExpr>(this)->getBase()->isOBJCGCCandidate();
+    return cast<ArraySubscriptExpr>(this)->getBase()->isOBJCGCCandidate(Ctx);
   }
 }
 Expr* Expr::IgnoreParens() {
index 155658e92daf30e91ec2a6ede44f6e84052729b5..c5f23879d1c392c7276d80657cf43ee1ea70ebab 100644 (file)
@@ -769,7 +769,7 @@ LValue CodeGenFunction::EmitUnaryOpLValue(const UnaryOperator *E) {
      if (getContext().getLangOptions().ObjC1 &&
          getContext().getLangOptions().getGCMode() != LangOptions::NonGC &&
          LV.isObjCWeak())
-       LValue::SetObjCNonGC(LV, !E->isOBJCGCCandidate());
+       LValue::SetObjCNonGC(LV, !E->isOBJCGCCandidate(getContext()));
      return LV;
     }
   case UnaryOperator::Real:
@@ -904,7 +904,7 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E) {
                                getContext().getObjCGCAttrKind(T));
   if (getContext().getLangOptions().ObjC1 &&
       getContext().getLangOptions().getGCMode() != LangOptions::NonGC)
-    LValue::SetObjCNonGC(LV, !E->isOBJCGCCandidate());
+    LValue::SetObjCNonGC(LV, !E->isOBJCGCCandidate(getContext()));
   return LV;
 }
 
index 61e9b980171683ee409dd7c467f9712537b49c98..b617c9fee4ea583ad0d692fcbda721ee5fd604f2 100644 (file)
@@ -1,5 +1,5 @@
 // RUN: clang-cc -triple x86_64-darwin-10 -fobjc-gc -emit-llvm -o %t %s &&
-// RUN: grep objc_assign_strongCast %t | count 3 &&
+// RUN: grep objc_assign_strongCast %t | count 4 &&
 // RUN: true
 
 @interface A
@@ -19,3 +19,9 @@ void f1(id x) {
   ((T*) &g0)->a[0] = x;
 }
 
+void f2(unsigned idx)
+{
+   id *keys;
+   keys[idx] = 0;
+}
+