A corner case of objc2 gc's write-barrier generation
for the Next runtime.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@72703 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index aca5efe..4a53a41 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -967,33 +967,41 @@
 
 /// 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() {