aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2009-06-01 21:29:32 +0000
committerFariborz Jahanian <fjahanian@apple.com>2009-06-01 21:29:32 +0000
commit102e390bcb5a1fb1a8fdbc8505e6dfd905374bbd (patch)
tree3e7233d21d45786e723e9eedfa3662cb8782f639
parent6c9b3151a2e9ec09b76296b57069f68e17413319 (diff)
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
-rw-r--r--include/clang/AST/Expr.h2
-rw-r--r--lib/AST/Expr.cpp26
-rw-r--r--lib/CodeGen/CGExpr.cpp4
-rw-r--r--test/CodeGenObjC/objc2-strong-cast-2.m8
4 files changed, 27 insertions, 13 deletions
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<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() {
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;
+}
+