diff options
-rw-r--r-- | include/clang/Analysis/PathSensitive/BugReporter.h | 24 | ||||
-rw-r--r-- | lib/Analysis/BasicObjCFoundationChecks.cpp | 2 | ||||
-rw-r--r-- | lib/Analysis/BugReporter.cpp | 13 | ||||
-rw-r--r-- | lib/Analysis/CFRefCount.cpp | 4 | ||||
-rw-r--r-- | lib/Analysis/DeadStores.cpp | 6 | ||||
-rw-r--r-- | lib/Analysis/GRSimpleVals.cpp | 21 |
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"; |