From: Ted Kremenek Date: Fri, 18 Sep 2009 07:31:15 +0000 (+0000) Subject: Revert most of r82198, which was causing a large number of crashes X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7f473c546602de69b35f0c657619c2ffe8e4136a;p=clang Revert most of r82198, which was causing a large number of crashes when running the analyzer on real projects. We'll keep the change to AnalysisManager.cpp in r82198 so that -fobjc-gc analyzes code correctly in both GC and non-GC modes, although this may emit two diagnostics for each bug in some cases (a better solution will come later). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@82201 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Analysis/PathDiagnostic.h b/include/clang/Analysis/PathDiagnostic.h index 0635a01d7b..809c83161f 100644 --- a/include/clang/Analysis/PathDiagnostic.h +++ b/include/clang/Analysis/PathDiagnostic.h @@ -17,7 +17,6 @@ #include "clang/Basic/SourceManager.h" #include "clang/Basic/Diagnostic.h" #include "llvm/ADT/OwningPtr.h" -#include "llvm/ADT/FoldingSet.h" #include #include @@ -25,17 +24,12 @@ #include namespace clang { - -class Stmt; -class Decl; -class Preprocessor; - + //===----------------------------------------------------------------------===// // High-level interface for handlers of path-sensitive diagnostics. //===----------------------------------------------------------------------===// class PathDiagnostic; - class Stmt; class Decl; class Preprocessor; @@ -44,9 +38,12 @@ class PathDiagnosticClient : public DiagnosticClient { public: PathDiagnosticClient() {} virtual ~PathDiagnosticClient() {} + virtual void SetPreprocessor(Preprocessor *PP) {} + virtual void HandleDiagnostic(Diagnostic::Level DiagLevel, const DiagnosticInfo &Info); + virtual void HandlePathDiagnostic(const PathDiagnostic* D) = 0; enum PathGenerationScheme { Minimal, Extensive }; @@ -128,8 +125,6 @@ public: void flatten(); const SourceManager& getManager() const { assert(isValid()); return *SM; } - - void Profile(llvm::FoldingSetNodeID &ID) const; }; class PathDiagnosticLocationPair { @@ -147,11 +142,6 @@ public: Start.flatten(); End.flatten(); } - - void Profile(llvm::FoldingSetNodeID &ID) const { - Start.Profile(ID); - End.Profile(ID); - } }; //===----------------------------------------------------------------------===// @@ -230,8 +220,6 @@ public: static inline bool classof(const PathDiagnosticPiece* P) { return true; } - - virtual void Profile(llvm::FoldingSetNodeID &ID) const; }; class PathDiagnosticSpotPiece : public PathDiagnosticPiece { @@ -250,8 +238,6 @@ public: PathDiagnosticLocation getLocation() const { return Pos; } virtual void flattenLocations() { Pos.flatten(); } - - virtual void Profile(llvm::FoldingSetNodeID &ID) const; }; class PathDiagnosticEventPiece : public PathDiagnosticSpotPiece { @@ -331,8 +317,6 @@ public: static inline bool classof(const PathDiagnosticPiece* P) { return P->getKind() == ControlFlow; } - - virtual void Profile(llvm::FoldingSetNodeID &ID) const; }; class PathDiagnosticMacroPiece : public PathDiagnosticSpotPiece { @@ -363,14 +347,12 @@ public: static inline bool classof(const PathDiagnosticPiece* P) { return P->getKind() == Macro; } - - virtual void Profile(llvm::FoldingSetNodeID &ID) const; }; /// PathDiagnostic - PathDiagnostic objects represent a single path-sensitive /// diagnostic. It represents an ordered-collection of PathDiagnosticPieces, /// each which represent the pieces of the path. -class PathDiagnostic : public llvm::FoldingSetNode { +class PathDiagnostic { std::deque path; unsigned Size; std::string BugType; @@ -404,13 +386,11 @@ public: } void push_front(PathDiagnosticPiece* piece) { - assert(piece); path.push_front(piece); ++Size; } void push_back(PathDiagnosticPiece* piece) { - assert(piece); path.push_back(piece); ++Size; } @@ -473,7 +453,7 @@ public: bool operator==(const const_iterator& X) const { return I == X.I; } bool operator!=(const const_iterator& X) const { return I != X.I; } - reference operator*() const { assert(*I); return **I; } + reference operator*() const { return **I; } pointer operator->() const { return *I; } const_iterator& operator++() { ++I; return *this; } @@ -500,8 +480,8 @@ public: void flattenLocations() { for (iterator I = begin(), E = end(); I != E; ++I) I->flattenLocations(); } - - void Profile(llvm::FoldingSetNodeID &ID) const; -}; +}; + + } //end clang namespace #endif diff --git a/lib/Analysis/BugReporter.cpp b/lib/Analysis/BugReporter.cpp index 064fff47f4..38e982888e 100644 --- a/lib/Analysis/BugReporter.cpp +++ b/lib/Analysis/BugReporter.cpp @@ -1732,50 +1732,6 @@ static BugReport *FindReportInEquivalenceClass(BugReportEquivClass& EQ) { return NULL; } - -//===----------------------------------------------------------------------===// -// DiagnosticCache. This is a hack to cache analyzer diagnostics. It -// uses global state, which eventually should go elsewhere. -//===----------------------------------------------------------------------===// -namespace { -class VISIBILITY_HIDDEN DiagCacheItem : public llvm::FoldingSetNode { - llvm::FoldingSetNodeID ID; -public: - DiagCacheItem(BugReport *R, PathDiagnostic *PD) { - ID.AddString(R->getBugType().getName()); - ID.AddString(R->getBugType().getCategory()); - ID.AddString(R->getDescription()); - ID.AddInteger(R->getLocation().getRawEncoding()); - PD->Profile(ID); - } - - void Profile(llvm::FoldingSetNodeID &id) { - id = ID; - } - - llvm::FoldingSetNodeID &getID() { return ID; } -}; -} - -static bool IsCachedDiagnostic(BugReport *R, PathDiagnostic *PD) { - // FIXME: Eventually this diagnostic cache should reside in something - // like AnalysisManager instead of being a static variable. This is - // really unsafe in the long term. - typedef llvm::FoldingSet DiagnosticCache; - static DiagnosticCache DC; - - void *InsertPos; - DiagCacheItem *Item = new DiagCacheItem(R, PD); - - if (DC.FindNodeOrInsertPos(Item->getID(), InsertPos)) { - delete Item; - return true; - } - - DC.InsertNode(Item, InsertPos); - return false; -} - void BugReporter::FlushReport(BugReportEquivClass& EQ) { BugReport *R = FindReportInEquivalenceClass(EQ); @@ -1796,9 +1752,6 @@ void BugReporter::FlushReport(BugReportEquivClass& EQ) { GeneratePathDiagnostic(*D.get(), EQ); - if (IsCachedDiagnostic(R, D.get())) - return; - // Get the meta data. std::pair Meta = R->getExtraDescriptiveText(); for (const char** s = Meta.first; s != Meta.second; ++s) diff --git a/lib/Analysis/PathDiagnostic.cpp b/lib/Analysis/PathDiagnostic.cpp index 800496a161..ceead6a3ac 100644 --- a/lib/Analysis/PathDiagnostic.cpp +++ b/lib/Analysis/PathDiagnostic.cpp @@ -239,66 +239,4 @@ void PathDiagnosticLocation::flatten() { } } -//===----------------------------------------------------------------------===// -// FoldingSet profiling methods. -//===----------------------------------------------------------------------===// - -void PathDiagnosticLocation::Profile(llvm::FoldingSetNodeID &ID) const { - ID.AddInteger((unsigned) K); - switch (K) { - case RangeK: - ID.AddInteger(R.getBegin().getRawEncoding()); - ID.AddInteger(R.getEnd().getRawEncoding()); - break; - case SingleLocK: - ID.AddInteger(R.getBegin().getRawEncoding()); - break; - case StmtK: - ID.Add(S); - break; - case DeclK: - ID.Add(D); - break; - } - return; -} - -void PathDiagnosticPiece::Profile(llvm::FoldingSetNodeID &ID) const { - ID.AddInteger((unsigned) getKind()); - ID.AddString(str); - // FIXME: Add profiling support for code hints. - ID.AddInteger((unsigned) getDisplayHint()); - for (range_iterator I = ranges_begin(), E = ranges_end(); I != E; ++I) { - ID.AddInteger(I->getBegin().getRawEncoding()); - ID.AddInteger(I->getEnd().getRawEncoding()); - } -} - -void PathDiagnosticSpotPiece::Profile(llvm::FoldingSetNodeID &ID) const { - PathDiagnosticPiece::Profile(ID); - ID.Add(Pos); -} -void PathDiagnosticControlFlowPiece::Profile(llvm::FoldingSetNodeID &ID) const { - PathDiagnosticPiece::Profile(ID); - for (const_iterator I = begin(), E = end(); I != E; ++I) - ID.Add(*I); -} - -void PathDiagnosticMacroPiece::Profile(llvm::FoldingSetNodeID &ID) const { - PathDiagnosticSpotPiece::Profile(ID); - for (const_iterator I = begin(), E = end(); I != E; ++I) - ID.Add(**I); -} - -void PathDiagnostic::Profile(llvm::FoldingSetNodeID &ID) const { - ID.AddInteger(Size); - ID.AddString(BugType); - ID.AddString(Desc); - ID.AddString(Category); - for (const_iterator I = begin(), E = end(); I != E; ++I) - ID.Add(*I); - - for (meta_iterator I = meta_begin(), E = meta_end(); I != E; ++I) - ID.AddString(*I); -} diff --git a/test/Analysis/misc-ps.m b/test/Analysis/misc-ps.m index d7c3db7439..189fc44878 100644 --- a/test/Analysis/misc-ps.m +++ b/test/Analysis/misc-ps.m @@ -1,5 +1,4 @@ -// NOTE: Use '-fobjc-gc' to test the analysis being run twice, and multiple reports are not issued. -// RUN: clang-cc -analyze -checker-cfref --analyzer-store=basic -fobjc-gc -analyzer-constraints=basic --verify -fblocks %s && +// RUN: clang-cc -analyze -checker-cfref --analyzer-store=basic -analyzer-constraints=basic --verify -fblocks %s && // RUN: clang-cc -analyze -checker-cfref --analyzer-store=basic -analyzer-constraints=range --verify -fblocks %s && // RUN: clang-cc -analyze -checker-cfref --analyzer-store=region -analyzer-constraints=basic --verify -fblocks %s && // RUN: clang-cc -analyze -checker-cfref --analyzer-store=region -analyzer-constraints=range --verify -fblocks %s