summaryrefslogtreecommitdiffstats
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
commit31484b24773f7c020884268faaa770143bc216c6 (patch)
tree900d0226033dcecfe56bb1115b64a31184ab9b2f
parentc072b820cf3148bbddb1baaedbac713075171886 (diff)
downloadbcm5719-llvm-31484b24773f7c020884268faaa770143bc216c6.tar.gz
bcm5719-llvm-31484b24773f7c020884268faaa770143bc216c6.zip
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). llvm-svn: 49918
-rw-r--r--clang/include/clang/Analysis/PathSensitive/BugReporter.h24
-rw-r--r--clang/lib/Analysis/BasicObjCFoundationChecks.cpp2
-rw-r--r--clang/lib/Analysis/BugReporter.cpp13
-rw-r--r--clang/lib/Analysis/CFRefCount.cpp4
-rw-r--r--clang/lib/Analysis/DeadStores.cpp6
-rw-r--r--clang/lib/Analysis/GRSimpleVals.cpp21
6 files changed, 39 insertions, 31 deletions
diff --git a/clang/include/clang/Analysis/PathSensitive/BugReporter.h b/clang/include/clang/Analysis/PathSensitive/BugReporter.h
index f2f2e031661..325e1a750f1 100644
--- a/clang/include/clang/Analysis/PathSensitive/BugReporter.h
+++ b/clang/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/clang/lib/Analysis/BasicObjCFoundationChecks.cpp b/clang/lib/Analysis/BasicObjCFoundationChecks.cpp
index 958f85dff9a..7e51aee17b7 100644
--- a/clang/lib/Analysis/BasicObjCFoundationChecks.cpp
+++ b/clang/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/clang/lib/Analysis/BugReporter.cpp b/clang/lib/Analysis/BugReporter.cpp
index e74295c3113..e69c5a6d3ff 100644
--- a/clang/lib/Analysis/BugReporter.cpp
+++ b/clang/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/clang/lib/Analysis/CFRefCount.cpp b/clang/lib/Analysis/CFRefCount.cpp
index 3eb037978a1..253e00589e0 100644
--- a/clang/lib/Analysis/CFRefCount.cpp
+++ b/clang/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/clang/lib/Analysis/DeadStores.cpp b/clang/lib/Analysis/DeadStores.cpp
index 719b5eb6c0d..6858e3ab370 100644
--- a/clang/lib/Analysis/DeadStores.cpp
+++ b/clang/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/clang/lib/Analysis/GRSimpleVals.cpp b/clang/lib/Analysis/GRSimpleVals.cpp
index ea8762aa0c9..2c14dde08bd 100644
--- a/clang/lib/Analysis/GRSimpleVals.cpp
+++ b/clang/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";
OpenPOWER on IntegriCloud