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 | 921c14322977253a60dcb171f45e468c95fe41f8 (patch) | |
tree | b85c224856580bdeb5720b0e5514e75b1c51421a /lib/Sema/SemaChecking.cpp | |
parent | f58de90e209eac7159a52e75dcd6e99b3a6311a6 (diff) |
objc-arc: Check on a variety of unsafe assignment of retained
objects. // rdar://9495837
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@133806 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaChecking.cpp')
-rw-r--r-- | lib/Sema/SemaChecking.cpp | 43 |
1 files changed, 39 insertions, 4 deletions
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp index 6a09bf0e40..35b6e9abc9 100644 --- a/lib/Sema/SemaChecking.cpp +++ b/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(); + } + } +} |