aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2008-04-18 20:54:29 +0000
committerTed Kremenek <kremenek@apple.com>2008-04-18 20:54:29 +0000
commit95cc1bae89ac68626d6f4d389e189ce1ef3aa7f6 (patch)
tree329013af8c1456752d42f1f2fe908533a7fa629b
parentb0533965f1b4db020692e3b23ca7b3bc15bf5897 (diff)
Generalize caching mechanism for bugs reports. Now individual BugTypes
can decide the policy on how to cache related bugs. This allows us to properly to handle warning about multiple leaks in the same location in the ref count checker (not yet done). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@49918 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/Analysis/PathSensitive/BugReporter.h24
-rw-r--r--lib/Analysis/BasicObjCFoundationChecks.cpp2
-rw-r--r--lib/Analysis/BugReporter.cpp13
-rw-r--r--lib/Analysis/CFRefCount.cpp4
-rw-r--r--lib/Analysis/DeadStores.cpp6
-rw-r--r--lib/Analysis/GRSimpleVals.cpp21
6 files changed, 39 insertions, 31 deletions
diff --git a/include/clang/Analysis/PathSensitive/BugReporter.h b/include/clang/Analysis/PathSensitive/BugReporter.h
index f2f2e03166..325e1a750f 100644
--- a/include/clang/Analysis/PathSensitive/BugReporter.h
+++ b/include/clang/Analysis/PathSensitive/BugReporter.h
@@ -32,6 +32,7 @@ class BugReporter;
class GRExprEngine;
class ValueState;
class Stmt;
+class BugReport;
class BugType {
public:
@@ -43,17 +44,29 @@ public:
virtual void EmitWarnings(BugReporter& BR) {}
virtual void GetErrorNodes(std::vector<ExplodedNode<ValueState>*>& Nodes) {}
+
+ virtual bool isCached(BugReport& R) = 0;
+};
+
+class BugTypeCacheLocation : public BugType {
+ llvm::SmallPtrSet<void*,10> CachedErrors;
+public:
+ BugTypeCacheLocation() {}
+ virtual ~BugTypeCacheLocation() {}
+ virtual bool isCached(BugReport& R);
};
+
class BugReport {
- const BugType& Desc;
+ BugType& Desc;
ExplodedNode<ValueState> *N;
public:
- BugReport(const BugType& D, ExplodedNode<ValueState> *n) : Desc(D), N(n) {}
+ BugReport(BugType& D, ExplodedNode<ValueState> *n) : Desc(D), N(n) {}
virtual ~BugReport();
const BugType& getBugType() const { return Desc; }
+ BugType& getBugType() { return Desc; }
ExplodedNode<ValueState>* getEndNode() const { return N; }
@@ -82,7 +95,7 @@ public:
class RangedBugReport : public BugReport {
std::vector<SourceRange> Ranges;
public:
- RangedBugReport(const BugType& D, ExplodedNode<ValueState> *n)
+ RangedBugReport(BugType& D, ExplodedNode<ValueState> *n)
: BugReport(D, n) {}
virtual ~RangedBugReport();
@@ -104,7 +117,6 @@ public:
};
class BugReporter {
- llvm::SmallPtrSet<void*,10> CachedErrors;
Diagnostic& Diag;
PathDiagnosticClient* PD;
ASTContext& Ctx;
@@ -130,10 +142,6 @@ public:
CFG& getCFG() { return getGraph().getCFG(); }
void EmitWarning(BugReport& R);
-
- void clearCache() { CachedErrors.clear(); }
-
- bool IsCached(ExplodedNode<ValueState>* N);
void GeneratePathDiagnostic(PathDiagnostic& PD, BugReport& R);
};
diff --git a/lib/Analysis/BasicObjCFoundationChecks.cpp b/lib/Analysis/BasicObjCFoundationChecks.cpp
index 958f85dff9..7e51aee17b 100644
--- a/lib/Analysis/BasicObjCFoundationChecks.cpp
+++ b/lib/Analysis/BasicObjCFoundationChecks.cpp
@@ -54,7 +54,7 @@ static const char* GetReceiverNameType(ObjCMessageExpr* ME) {
namespace {
-class VISIBILITY_HIDDEN NilArg : public BugType {
+class VISIBILITY_HIDDEN NilArg : public BugTypeCacheLocation {
public:
virtual ~NilArg() {}
diff --git a/lib/Analysis/BugReporter.cpp b/lib/Analysis/BugReporter.cpp
index e74295c311..e69c5a6d3f 100644
--- a/lib/Analysis/BugReporter.cpp
+++ b/lib/Analysis/BugReporter.cpp
@@ -357,12 +357,14 @@ void BugReporter::GeneratePathDiagnostic(PathDiagnostic& PD,
}
}
-bool BugReporter::IsCached(ExplodedNode<ValueState>* N) {
+bool BugTypeCacheLocation::isCached(BugReport& R) {
+
+ ExplodedNode<ValueState>* N = R.getEndNode();
if (!N)
return false;
-
- // HACK: Cache the location of the error. Don't emit the same
+
+ // Cache the location of the error. Don't emit the same
// warning for the same error type that occurs at the same program
// location but along a different path.
@@ -371,14 +373,13 @@ bool BugReporter::IsCached(ExplodedNode<ValueState>* N) {
if (CachedErrors.count(p))
return true;
- CachedErrors.insert(p);
-
+ CachedErrors.insert(p);
return false;
}
void BugReporter::EmitWarning(BugReport& R) {
- if (IsCached(R.getEndNode()))
+ if (R.getBugType().isCached(R))
return;
PathDiagnostic D(R.getName());
diff --git a/lib/Analysis/CFRefCount.cpp b/lib/Analysis/CFRefCount.cpp
index 3eb037978a..253e00589e 100644
--- a/lib/Analysis/CFRefCount.cpp
+++ b/lib/Analysis/CFRefCount.cpp
@@ -1268,7 +1268,7 @@ namespace {
// Bug Descriptions. //
//===-------------===//
- class VISIBILITY_HIDDEN CFRefBug : public BugType {
+ class VISIBILITY_HIDDEN CFRefBug : public BugTypeCacheLocation {
protected:
CFRefCount& TF;
@@ -1331,7 +1331,7 @@ namespace {
class VISIBILITY_HIDDEN CFRefReport : public RangedBugReport {
SymbolID Sym;
public:
- CFRefReport(const BugType& D, ExplodedNode<ValueState> *n, SymbolID sym)
+ CFRefReport(BugType& D, ExplodedNode<ValueState> *n, SymbolID sym)
: RangedBugReport(D, n), Sym(sym) {}
virtual ~CFRefReport() {}
diff --git a/lib/Analysis/DeadStores.cpp b/lib/Analysis/DeadStores.cpp
index 719b5eb6c0..6858e3ab37 100644
--- a/lib/Analysis/DeadStores.cpp
+++ b/lib/Analysis/DeadStores.cpp
@@ -109,7 +109,7 @@ class VISIBILITY_HIDDEN DiagBugReport : public RangedBugReport {
std::list<std::string> Strs;
FullSourceLoc L;
public:
- DiagBugReport(const BugType& D, FullSourceLoc l) :
+ DiagBugReport(BugType& D, FullSourceLoc l) :
RangedBugReport(D, NULL), L(l) {}
virtual ~DiagBugReport() {}
@@ -124,7 +124,7 @@ public:
class VISIBILITY_HIDDEN DiagCollector : public DiagnosticClient {
std::list<DiagBugReport> Reports;
- const BugType& D;
+ BugType& D;
public:
DiagCollector(BugType& d) : D(d) {}
@@ -159,7 +159,7 @@ public:
iterator end() { return Reports.end(); }
};
-class VISIBILITY_HIDDEN DeadStoresChecker : public BugType {
+class VISIBILITY_HIDDEN DeadStoresChecker : public BugTypeCacheLocation {
public:
virtual const char* getName() const {
return "dead store";
diff --git a/lib/Analysis/GRSimpleVals.cpp b/lib/Analysis/GRSimpleVals.cpp
index ea8762aa0c..2c14dde08b 100644
--- a/lib/Analysis/GRSimpleVals.cpp
+++ b/lib/Analysis/GRSimpleVals.cpp
@@ -40,8 +40,7 @@ ExplodedNode<ValueState>* GetNode(GRExprEngine::undef_arg_iterator I) {
}
template <typename ITER>
-void GenericEmitWarnings(BugReporter& BR, const BugType& D,
- ITER I, ITER E) {
+void GenericEmitWarnings(BugReporter& BR, BugType& D, ITER I, ITER E) {
for (; I != E; ++I) {
BugReport R(D, GetNode(I));
@@ -55,7 +54,7 @@ void GenericEmitWarnings(BugReporter& BR, const BugType& D,
namespace {
-class VISIBILITY_HIDDEN NullDeref : public BugType {
+class VISIBILITY_HIDDEN NullDeref : public BugTypeCacheLocation {
public:
virtual const char* getName() const {
return "null dereference";
@@ -72,7 +71,7 @@ public:
}
};
-class VISIBILITY_HIDDEN UndefDeref : public BugType {
+class VISIBILITY_HIDDEN UndefDeref : public BugTypeCacheLocation {
public:
virtual const char* getName() const {
return "bad dereference";
@@ -89,7 +88,7 @@ public:
}
};
-class VISIBILITY_HIDDEN UndefBranch : public BugType {
+class VISIBILITY_HIDDEN UndefBranch : public BugTypeCacheLocation {
public:
virtual const char* getName() const {
return "uninitialized value";
@@ -106,7 +105,7 @@ public:
}
};
-class VISIBILITY_HIDDEN DivZero : public BugType {
+class VISIBILITY_HIDDEN DivZero : public BugTypeCacheLocation {
public:
virtual const char* getName() const {
return "divide-by-zero";
@@ -123,7 +122,7 @@ public:
}
};
-class VISIBILITY_HIDDEN UndefResult : public BugType {
+class VISIBILITY_HIDDEN UndefResult : public BugTypeCacheLocation {
public:
virtual const char* getName() const {
return "undefined result";
@@ -140,7 +139,7 @@ public:
}
};
-class VISIBILITY_HIDDEN BadCall : public BugType {
+class VISIBILITY_HIDDEN BadCall : public BugTypeCacheLocation {
public:
virtual const char* getName() const {
return "invalid function call";
@@ -158,7 +157,7 @@ public:
};
-class VISIBILITY_HIDDEN BadArg : public BugType {
+class VISIBILITY_HIDDEN BadArg : public BugTypeCacheLocation {
public:
virtual ~BadArg() {}
@@ -214,7 +213,7 @@ public:
}
};
-class VISIBILITY_HIDDEN BadReceiver : public BugType {
+class VISIBILITY_HIDDEN BadReceiver : public BugTypeCacheLocation {
public:
virtual const char* getName() const {
return "bad receiver";
@@ -245,7 +244,7 @@ public:
}
};
-class VISIBILITY_HIDDEN RetStack : public BugType {
+class VISIBILITY_HIDDEN RetStack : public BugTypeCacheLocation {
public:
virtual const char* getName() const {
return "return of stack address";