From: Fariborz Jahanian Date: Mon, 1 Jun 2009 21:29:32 +0000 (+0000) Subject: A corner case of objc2 gc's write-barrier generation X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=102e390bcb5a1fb1a8fdbc8505e6dfd905374bbd;p=clang 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/include/clang/AST/Expr.h b/include/clang/AST/Expr.h index 92f2025cb4..98de5f9d38 100644 --- a/include/clang/AST/Expr.h +++ b/include/clang/AST/Expr.h @@ -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, diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index aca5efeb16..4a53a4123d 100644 --- a/lib/AST/Expr.cpp +++ b/lib/AST/Expr.cpp @@ -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(this)->getSubExpr()->isOBJCGCCandidate(); + return cast(this)->getSubExpr()->isOBJCGCCandidate(Ctx); case ParenExprClass: - return cast(this)->getSubExpr()->isOBJCGCCandidate(); + return cast(this)->getSubExpr()->isOBJCGCCandidate(Ctx); case ImplicitCastExprClass: - return cast(this)->getSubExpr()->isOBJCGCCandidate(); + return cast(this)->getSubExpr()->isOBJCGCCandidate(Ctx); case CStyleCastExprClass: - return cast(this)->getSubExpr()->isOBJCGCCandidate(); + return cast(this)->getSubExpr()->isOBJCGCCandidate(Ctx); case DeclRefExprClass: case QualifiedDeclRefExprClass: { const Decl *D = cast(this)->getDecl(); - if (const VarDecl *VD = dyn_cast(D)) - return VD->hasGlobalStorage(); + if (const VarDecl *VD = dyn_cast(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(this); - return M->getBase()->isOBJCGCCandidate(); + return M->getBase()->isOBJCGCCandidate(Ctx); } case ArraySubscriptExprClass: - return cast(this)->getBase()->isOBJCGCCandidate(); + return cast(this)->getBase()->isOBJCGCCandidate(Ctx); } } Expr* Expr::IgnoreParens() { diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index 155658e92d..c5f23879d1 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -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; } diff --git a/test/CodeGenObjC/objc2-strong-cast-2.m b/test/CodeGenObjC/objc2-strong-cast-2.m index 61e9b98017..b617c9fee4 100644 --- a/test/CodeGenObjC/objc2-strong-cast-2.m +++ b/test/CodeGenObjC/objc2-strong-cast-2.m @@ -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; +} +