aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/AnalysisBasedWarnings.cpp
diff options
context:
space:
mode:
authorJordan Rose <jordan_rose@apple.com>2012-10-11 16:10:19 +0000
committerJordan Rose <jordan_rose@apple.com>2012-10-11 16:10:19 +0000
commitb5cd1220dd650a358622241237aa595c5d675506 (patch)
tree1b4974ec3c6daf56686833e1202d7125c681f922 /lib/Sema/AnalysisBasedWarnings.cpp
parent7fffce781e6ecbf4058b24df7e5ae3037569aa56 (diff)
-Warc-repeated-use-of-weak: Don't warn on a single read followed by writes.
This is a "safe" pattern, or at least one that cannot be helped by using a strong local variable. However, if the single read is within a loop, it should /always/ be treated as potentially dangerous. <rdar://problem/12437490> git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@165719 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/AnalysisBasedWarnings.cpp')
-rw-r--r--lib/Sema/AnalysisBasedWarnings.cpp40
1 files changed, 36 insertions, 4 deletions
diff --git a/lib/Sema/AnalysisBasedWarnings.cpp b/lib/Sema/AnalysisBasedWarnings.cpp
index 6d09f2c116..b039bc6f92 100644
--- a/lib/Sema/AnalysisBasedWarnings.cpp
+++ b/lib/Sema/AnalysisBasedWarnings.cpp
@@ -27,6 +27,7 @@
#include "clang/AST/StmtObjC.h"
#include "clang/AST/StmtCXX.h"
#include "clang/AST/EvaluatedExprVisitor.h"
+#include "clang/AST/ParentMap.h"
#include "clang/AST/StmtVisitor.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/Analysis/AnalysisContext.h"
@@ -903,10 +904,30 @@ public:
};
}
+static bool isInLoop(const ParentMap &PM, const Stmt *S) {
+ assert(S);
+
+ do {
+ switch (S->getStmtClass()) {
+ case Stmt::DoStmtClass:
+ case Stmt::ForStmtClass:
+ case Stmt::WhileStmtClass:
+ case Stmt::CXXForRangeStmtClass:
+ case Stmt::ObjCForCollectionStmtClass:
+ return true;
+ default:
+ break;
+ }
+ } while ((S = PM.getParent(S)));
+
+ return false;
+}
+
static void diagnoseRepeatedUseOfWeak(Sema &S,
const sema::FunctionScopeInfo *CurFn,
- const Decl *D) {
+ const Decl *D,
+ const ParentMap &PM) {
typedef sema::FunctionScopeInfo::WeakObjectProfileTy WeakObjectProfileTy;
typedef sema::FunctionScopeInfo::WeakObjectUseMap WeakObjectUseMap;
typedef sema::FunctionScopeInfo::WeakUseVector WeakUseVector;
@@ -918,8 +939,6 @@ static void diagnoseRepeatedUseOfWeak(Sema &S,
for (WeakObjectUseMap::const_iterator I = WeakMap.begin(), E = WeakMap.end();
I != E; ++I) {
const WeakUseVector &Uses = I->second;
- if (Uses.size() <= 1)
- continue;
// Find the first read of the weak object.
WeakUseVector::const_iterator UI = Uses.begin(), UE = Uses.end();
@@ -932,6 +951,19 @@ static void diagnoseRepeatedUseOfWeak(Sema &S,
if (UI == UE)
continue;
+ // If there was only one read, followed by any number of writes, and the
+ // read is not within a loop, don't warn.
+ if (UI == Uses.begin()) {
+ WeakUseVector::const_iterator UI2 = UI;
+ for (++UI2; UI2 != UE; ++UI2)
+ if (UI2->isUnsafe())
+ break;
+
+ if (UI2 == UE)
+ if (!isInLoop(PM, UI->getUseExpr()))
+ continue;
+ }
+
UsesByStmt.push_back(StmtUsesPair(UI->getUseExpr(), I));
}
@@ -1519,7 +1551,7 @@ AnalysisBasedWarnings::IssueWarnings(sema::AnalysisBasedWarnings::Policy P,
if (S.getLangOpts().ObjCARCWeak &&
Diags.getDiagnosticLevel(diag::warn_arc_repeated_use_of_weak,
D->getLocStart()) != DiagnosticsEngine::Ignored)
- diagnoseRepeatedUseOfWeak(S, fscope, D);
+ diagnoseRepeatedUseOfWeak(S, fscope, D, AC.getParentMap());
// Collect statistics about the CFG if it was built.
if (S.CollectStats && AC.isCFGBuilt()) {