diff options
author | Fariborz Jahanian <fjahanian@apple.com> | 2011-06-24 18:25:34 +0000 |
---|---|---|
committer | Fariborz Jahanian <fjahanian@apple.com> | 2011-06-24 18:25:34 +0000 |
commit | 5f98da0ea2bb65e6bc9c0e6007db454cf296b1dd (patch) | |
tree | 18725ae4ffb0cfc2304cd8fca9f4229acc380ddb /clang/lib/Sema/SemaChecking.cpp | |
parent | cb8fa3ec1d8c8b863c61f9d5525f799113050cfd (diff) | |
download | bcm5719-llvm-5f98da0ea2bb65e6bc9c0e6007db454cf296b1dd.tar.gz bcm5719-llvm-5f98da0ea2bb65e6bc9c0e6007db454cf296b1dd.zip |
objc-arc: Check on a variety of unsafe assignment of retained
objects. // rdar://9495837
llvm-svn: 133806
Diffstat (limited to 'clang/lib/Sema/SemaChecking.cpp')
-rw-r--r-- | clang/lib/Sema/SemaChecking.cpp | 43 |
1 files changed, 39 insertions, 4 deletions
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 6a09bf0e40c..35b6e9abc9c 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -3720,15 +3720,50 @@ void Sema::checkRetainCycles(Expr *receiver, Expr *argument) { diagnoseRetainCycle(*this, capturer, owner); } -void Sema::checkUnsafeAssigns(SourceLocation Loc, +bool Sema::checkUnsafeAssigns(SourceLocation Loc, QualType LHS, Expr *RHS) { Qualifiers::ObjCLifetime LT = LHS.getObjCLifetime(); if (LT != Qualifiers::OCL_Weak && LT != Qualifiers::OCL_ExplicitNone) - return; - if (ImplicitCastExpr *cast = dyn_cast<ImplicitCastExpr>(RHS)) - if (cast->getCastKind() == CK_ObjCConsumeObject) + return false; + // strip off any implicit cast added to get to the one arc-specific + while (ImplicitCastExpr *cast = dyn_cast<ImplicitCastExpr>(RHS)) { + if (cast->getCastKind() == CK_ObjCConsumeObject) { Diag(Loc, diag::warn_arc_retained_assign) << (LT == Qualifiers::OCL_ExplicitNone) << RHS->getSourceRange(); + return true; + } + RHS = cast->getSubExpr(); + } + return false; } +void Sema::checkUnsafeExprAssigns(SourceLocation Loc, + Expr *LHS, Expr *RHS) { + QualType LHSType = LHS->getType(); + if (checkUnsafeAssigns(Loc, LHSType, RHS)) + return; + Qualifiers::ObjCLifetime LT = LHSType.getObjCLifetime(); + // FIXME. Check for other life times. + if (LT != Qualifiers::OCL_None) + return; + + if (ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(LHS)) { + if (PRE->isImplicitProperty()) + return; + const ObjCPropertyDecl *PD = PRE->getExplicitProperty(); + if (!PD) + return; + + unsigned Attributes = PD->getPropertyAttributes(); + if (Attributes & ObjCPropertyDecl::OBJC_PR_assign) + while (ImplicitCastExpr *cast = dyn_cast<ImplicitCastExpr>(RHS)) { + if (cast->getCastKind() == CK_ObjCConsumeObject) { + Diag(Loc, diag::warn_arc_retained_property_assign) + << RHS->getSourceRange(); + return; + } + RHS = cast->getSubExpr(); + } + } +} |