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() {