diff options
author | Jordan Rose <jordan_rose@apple.com> | 2012-09-28 22:21:35 +0000 |
---|---|---|
committer | Jordan Rose <jordan_rose@apple.com> | 2012-09-28 22:21:35 +0000 |
commit | 7a2704800943fbb69207e125d28186278712af36 (patch) | |
tree | 0caa71289707359adc8219048e0e384ec227e9a2 /lib/Sema/Sema.cpp | |
parent | 58b6bdcdeb683a3504f2248a409e1f4e85876cee (diff) |
-Warc-repeated-use-of-weak: check ivars and variables as well.
Like properties, loading from a weak ivar twice in the same function can
give you inconsistent results if the object is deallocated between the
two loads. It is safer to assign to a strong local variable and use that.
Second half of <rdar://problem/12280249>.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@164855 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/Sema.cpp')
-rw-r--r-- | lib/Sema/Sema.cpp | 137 |
1 files changed, 77 insertions, 60 deletions
diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp index 84cdb2b6f0..8555562d0d 100644 --- a/lib/Sema/Sema.cpp +++ b/lib/Sema/Sema.cpp @@ -82,65 +82,77 @@ static bool isSelfExpr(const Expr *E) { return M->getSelfDecl() == Param; } +FunctionScopeInfo::WeakObjectProfileTy::BaseInfoTy +FunctionScopeInfo::WeakObjectProfileTy::getBaseInfo(const Expr *E) { + E = E->IgnoreParenCasts(); + + const NamedDecl *D = 0; + bool IsExact = false; + + switch (E->getStmtClass()) { + case Stmt::DeclRefExprClass: + D = cast<DeclRefExpr>(E)->getDecl(); + IsExact = isa<VarDecl>(D); + break; + case Stmt::MemberExprClass: { + const MemberExpr *ME = cast<MemberExpr>(E); + D = ME->getMemberDecl(); + IsExact = isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()); + break; + } + case Stmt::ObjCIvarRefExprClass: { + const ObjCIvarRefExpr *IE = cast<ObjCIvarRefExpr>(E); + D = IE->getDecl(); + IsExact = isSelfExpr(IE->getBase()); + break; + } + case Stmt::PseudoObjectExprClass: { + const PseudoObjectExpr *POE = cast<PseudoObjectExpr>(E); + const ObjCPropertyRefExpr *BaseProp = + dyn_cast<ObjCPropertyRefExpr>(POE->getSyntacticForm()); + if (BaseProp) { + D = getBestPropertyDecl(BaseProp); + + const Expr *DoubleBase = BaseProp->getBase(); + if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(DoubleBase)) + DoubleBase = OVE->getSourceExpr(); + + IsExact = isSelfExpr(DoubleBase); + } + break; + } + default: + break; + } + + return BaseInfoTy(D, IsExact); +} + + FunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy( const ObjCPropertyRefExpr *PropE) - : Base(0, false), Property(getBestPropertyDecl(PropE)) { + : Base(0, true), Property(getBestPropertyDecl(PropE)) { if (PropE->isObjectReceiver()) { const OpaqueValueExpr *OVE = cast<OpaqueValueExpr>(PropE->getBase()); - const Expr *E = OVE->getSourceExpr()->IgnoreParenCasts(); - - switch (E->getStmtClass()) { - case Stmt::DeclRefExprClass: - Base.setPointer(cast<DeclRefExpr>(E)->getDecl()); - Base.setInt(isa<VarDecl>(Base.getPointer())); - break; - case Stmt::MemberExprClass: { - const MemberExpr *ME = cast<MemberExpr>(E); - Base.setPointer(ME->getMemberDecl()); - Base.setInt(isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())); - break; - } - case Stmt::ObjCIvarRefExprClass: { - const ObjCIvarRefExpr *IE = cast<ObjCIvarRefExpr>(E); - Base.setPointer(IE->getDecl()); - if (isSelfExpr(IE->getBase())) - Base.setInt(true); - break; - } - case Stmt::PseudoObjectExprClass: { - const PseudoObjectExpr *POE = cast<PseudoObjectExpr>(E); - const ObjCPropertyRefExpr *BaseProp = - dyn_cast<ObjCPropertyRefExpr>(POE->getSyntacticForm()); - if (BaseProp) { - Base.setPointer(getBestPropertyDecl(BaseProp)); - - const Expr *DoubleBase = BaseProp->getBase(); - if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(DoubleBase)) - DoubleBase = OVE->getSourceExpr(); - - if (isSelfExpr(DoubleBase)) - Base.setInt(true); - } - break; - } - default: - break; - } + const Expr *E = OVE->getSourceExpr(); + Base = getBaseInfo(E); } else if (PropE->isClassReceiver()) { Base.setPointer(PropE->getClassReceiver()); - Base.setInt(true); } else { assert(PropE->isSuperReceiver()); - Base.setInt(true); } } -void FunctionScopeInfo::recordUseOfWeak(const ObjCPropertyRefExpr *RefExpr) { - assert(RefExpr); - WeakUseVector &Uses = - WeakObjectUses[FunctionScopeInfo::WeakObjectProfileTy(RefExpr)]; - Uses.push_back(WeakUseTy(RefExpr, RefExpr->isMessagingGetter())); +FunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy( + const DeclRefExpr *DRE) + : Base(0, true), Property(DRE->getDecl()) { + assert(isa<VarDecl>(Property)); +} + +FunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy( + const ObjCIvarRefExpr *IvarE) + : Base(getBaseInfo(IvarE->getBase())), Property(IvarE->getDecl()) { } void FunctionScopeInfo::markSafeWeakUse(const Expr *E) { @@ -164,22 +176,27 @@ void FunctionScopeInfo::markSafeWeakUse(const Expr *E) { return; } - if (const ObjCPropertyRefExpr *RefExpr = dyn_cast<ObjCPropertyRefExpr>(E)) { - // Has this property been seen as a weak property? - FunctionScopeInfo::WeakObjectUseMap::iterator Uses = - WeakObjectUses.find(FunctionScopeInfo::WeakObjectProfileTy(RefExpr)); - if (Uses == WeakObjectUses.end()) - return; + // Has this weak object been seen before? + FunctionScopeInfo::WeakObjectUseMap::iterator Uses; + if (const ObjCPropertyRefExpr *RefExpr = dyn_cast<ObjCPropertyRefExpr>(E)) + Uses = WeakObjectUses.find(FunctionScopeInfo::WeakObjectProfileTy(RefExpr)); + else if (const ObjCIvarRefExpr *IvarE = dyn_cast<ObjCIvarRefExpr>(E)) + Uses = WeakObjectUses.find(FunctionScopeInfo::WeakObjectProfileTy(IvarE)); + else if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) + Uses = WeakObjectUses.find(FunctionScopeInfo::WeakObjectProfileTy(DRE)); + else + return; - // Has there been a read from the property using this Expr? - FunctionScopeInfo::WeakUseVector::reverse_iterator ThisUse = - std::find(Uses->second.rbegin(), Uses->second.rend(), WeakUseTy(E, true)); - if (ThisUse == Uses->second.rend()) - return; + if (Uses == WeakObjectUses.end()) + return; - ThisUse->markSafe(); + // Has there been a read from the object using this Expr? + FunctionScopeInfo::WeakUseVector::reverse_iterator ThisUse = + std::find(Uses->second.rbegin(), Uses->second.rend(), WeakUseTy(E, true)); + if (ThisUse == Uses->second.rend()) return; - } + + ThisUse->markSafe(); } BlockScopeInfo::~BlockScopeInfo() { } |