diff options
Diffstat (limited to 'contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h')
-rw-r--r-- | contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h | 89 |
1 files changed, 80 insertions, 9 deletions
diff --git a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h index 48393a3..b5a88ba 100644 --- a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h +++ b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h @@ -24,6 +24,7 @@ #include "llvm/ADT/ilist_node.h" #include "llvm/ADT/ImmutableSet.h" #include "llvm/ADT/DenseSet.h" +#include "llvm/ADT/SmallSet.h" namespace clang { @@ -95,6 +96,10 @@ protected: /// for multiple PathDiagnosticConsumers. llvm::SmallVector<Regions *, 2> interestingRegions; + /// A set of location contexts that correspoind to call sites which should be + /// considered "interesting". + llvm::SmallSet<const LocationContext *, 2> InterestingLocationContexts; + /// A set of custom visitors which generate "event" diagnostics at /// interesting points in the path. VisitorList Callbacks; @@ -111,6 +116,19 @@ protected: /// when reporting an issue. bool DoNotPrunePath; + /// Used to track unique reasons why a bug report might be invalid. + /// + /// \sa markInvalid + /// \sa removeInvalidation + typedef std::pair<const void *, const void *> InvalidationRecord; + + /// If non-empty, this bug report is likely a false positive and should not be + /// shown to the user. + /// + /// \sa markInvalid + /// \sa removeInvalidation + llvm::SmallSet<InvalidationRecord, 4> Invalidations; + private: // Used internally by BugReporter. Symbols &getInterestingSymbols(); @@ -147,7 +165,8 @@ public: PathDiagnosticLocation LocationToUnique) : BT(bt), DeclWithIssue(0), Description(desc), UniqueingLocation(LocationToUnique), - ErrorNode(errornode), ConfigurationChangeToken(0) {} + ErrorNode(errornode), ConfigurationChangeToken(0), + DoNotPrunePath(false) {} virtual ~BugReport(); @@ -158,8 +177,10 @@ public: const StringRef getDescription() const { return Description; } - const StringRef getShortDescription() const { - return ShortDescription.empty() ? Description : ShortDescription; + const StringRef getShortDescription(bool UseFallback = true) const { + if (ShortDescription.empty() && UseFallback) + return Description; + return ShortDescription; } /// Indicates whether or not any path pruning should take place @@ -172,14 +193,44 @@ public: void markInteresting(SymbolRef sym); void markInteresting(const MemRegion *R); void markInteresting(SVal V); + void markInteresting(const LocationContext *LC); bool isInteresting(SymbolRef sym); bool isInteresting(const MemRegion *R); bool isInteresting(SVal V); + bool isInteresting(const LocationContext *LC); unsigned getConfigurationChangeToken() const { return ConfigurationChangeToken; } + + /// Returns whether or not this report should be considered valid. + /// + /// Invalid reports are those that have been classified as likely false + /// positives after the fact. + bool isValid() const { + return Invalidations.empty(); + } + + /// Marks the current report as invalid, meaning that it is probably a false + /// positive and should not be reported to the user. + /// + /// The \p Tag and \p Data arguments are intended to be opaque identifiers for + /// this particular invalidation, where \p Tag represents the visitor + /// responsible for invalidation, and \p Data represents the reason this + /// visitor decided to invalidate the bug report. + /// + /// \sa removeInvalidation + void markInvalid(const void *Tag, const void *Data) { + Invalidations.insert(std::make_pair(Tag, Data)); + } + + /// Reverses the effects of a previous invalidation. + /// + /// \sa markInvalid + void removeInvalidation(const void *Tag, const void *Data) { + Invalidations.erase(std::make_pair(Tag, Data)); + } /// Return the canonical declaration, be it a method or class, where /// this issue semantically occurred. @@ -342,6 +393,11 @@ private: /// A vector of BugReports for tracking the allocated pointers and cleanup. std::vector<BugReportEquivClass *> EQClassesVector; + /// A map from PathDiagnosticPiece to the LocationContext of the inlined + /// function call it represents. + llvm::DenseMap<const PathDiagnosticCallPiece*, + const LocationContext*> LocationContextMap; + protected: BugReporter(BugReporterData& d, Kind k) : BugTypes(F.getEmptySet()), kind(k), D(d) {} @@ -378,9 +434,14 @@ public: SourceManager& getSourceManager() { return D.getSourceManager(); } - virtual void GeneratePathDiagnostic(PathDiagnostic& pathDiagnostic, + virtual bool generatePathDiagnostic(PathDiagnostic& pathDiagnostic, PathDiagnosticConsumer &PC, - ArrayRef<BugReport *> &bugReports) {} + ArrayRef<BugReport *> &bugReports) { + return true; + } + + bool RemoveUneededCalls(PathPieces &pieces, BugReport *R, + PathDiagnosticCallPiece *CallWithLoc = 0); void Register(BugType *BT); @@ -389,7 +450,7 @@ public: /// The reports are usually generated by the checkers. Further, they are /// folded based on the profile value, which is done to coalesce similar /// reports. - void EmitReport(BugReport *R); + void emitReport(BugReport *R); void EmitBasicReport(const Decl *DeclWithIssue, StringRef BugName, StringRef BugCategory, @@ -409,8 +470,10 @@ public: EmitBasicReport(DeclWithIssue, BugName, Category, BugStr, Loc, &R, 1); } - static bool classof(const BugReporter* R) { return true; } - + void addCallPieceLocationContextPair(const PathDiagnosticCallPiece *C, + const LocationContext *LC) { + LocationContextMap[C] = LC; + } private: llvm::StringMap<BugType *> StrBugTypes; @@ -440,7 +503,15 @@ public: /// engine. ProgramStateManager &getStateManager(); - virtual void GeneratePathDiagnostic(PathDiagnostic &pathDiagnostic, + /// Generates a path corresponding to one of the given bug reports. + /// + /// Which report is used for path generation is not specified. The + /// bug reporter will try to pick the shortest path, but this is not + /// guaranteed. + /// + /// \return True if the report was valid and a path was generated, + /// false if the reports should be considered invalid. + virtual bool generatePathDiagnostic(PathDiagnostic &PD, PathDiagnosticConsumer &PC, ArrayRef<BugReport*> &bugReports); |