14 #ifndef LLVM_CLANG_STATICANALYZER_CORE_BUGREPORTER_BUGREPORTER_H 15 #define LLVM_CLANG_STATICANALYZER_CORE_BUGREPORTER_BUGREPORTER_H 26 #include "llvm/ADT/ArrayRef.h" 27 #include "llvm/ADT/DenseSet.h" 28 #include "llvm/ADT/FoldingSet.h" 29 #include "llvm/ADT/ImmutableSet.h" 30 #include "llvm/ADT/None.h" 31 #include "llvm/ADT/SmallSet.h" 32 #include "llvm/ADT/SmallVector.h" 33 #include "llvm/ADT/StringMap.h" 34 #include "llvm/ADT/StringRef.h" 35 #include "llvm/ADT/ilist.h" 36 #include "llvm/ADT/ilist_node.h" 37 #include "llvm/ADT/iterator_range.h" 46 class AnalyzerOptions;
49 class DiagnosticsEngine;
50 class LocationContext;
71 llvm::DenseMap<PathDiagnosticConsumer *, std::unique_ptr<PathDiagnostic>>;
75 class BugReport :
public llvm::ilist_node<BugReport> {
78 virtual void anchor();
161 Symbols &getInterestingSymbols();
162 Regions &getInterestingRegions();
164 void lazyInitializeInterestingSets();
165 void pushInterestingSymbolsAndRegions();
166 void popInterestingSymbolsAndRegions();
170 : BT(bt), Description(desc), ErrorNode(errornode) {}
174 : BT(bt), ShortDescription(shortDesc), Description(desc),
175 ErrorNode(errornode) {}
178 : BT(bt), Description(desc), Location(l) {}
189 : BT(bt), Description(desc), UniqueingLocation(LocationToUnique),
190 UniqueingDecl(DeclToUnique), ErrorNode(errornode) {}
214 if (ShortDescription.empty() && UseFallback)
241 return Invalidations.empty();
254 Invalidations.insert(std::make_pair(Tag, Data));
264 DeclWithIssue = declWithIssue;
274 auto P = std::make_shared<PathDiagnosticNotePiece>(Pos, Msg);
276 for (
const auto &R : Ranges)
279 Notes.push_back(std::move(
P));
285 std::vector<SourceRange>
Ranges;
297 ExtraText.push_back(S);
331 assert((R.
isValid() || Ranges.empty()) &&
"Invalid range can only be used " 332 "to specify that the report does not have a range.");
337 virtual llvm::iterator_range<ranges_iterator>
getRanges();
346 void addVisitor(std::unique_ptr<BugReporterVisitor> visitor);
359 return TrackedConditions.insert(Cond).second;
365 virtual void Profile(llvm::FoldingSetNodeID& hash)
const;
376 llvm::ilist<BugReport> Reports;
378 void AddReport(std::unique_ptr<BugReport> R) {
379 Reports.push_back(R.release());
387 assert(!Reports.empty());
388 Reports.front().Profile(ID);
423 enum Kind { BaseBRKind, GRBugReporterKind };
426 using BugTypesTy = llvm::ImmutableSet<BugType *>;
428 BugTypesTy::Factory F;
438 std::unique_ptr<DiagnosticForConsumerMapTy>
439 generateDiagnosticForConsumerMap(
BugReport *exampleReport,
444 llvm::FoldingSet<BugReportEquivClass> EQClasses;
447 std::vector<BugReportEquivClass *> EQClassesVector;
451 : BugTypes(F.getEmptySet()), kind(k), D(d) {}
455 : BugTypes(F.getEmptySet()), kind(BaseBRKind), D(d) {}
487 virtual std::unique_ptr<DiagnosticForConsumerMapTy>
500 void emitReport(std::unique_ptr<BugReport> R);
503 StringRef BugName, StringRef BugCategory,
508 StringRef BugName, StringRef BugCategory,
513 llvm::StringMap<BugType *> StrBugTypes;
517 BugType *getBugTypeForName(CheckName CheckName, StringRef
name,
544 std::unique_ptr<DiagnosticForConsumerMapTy>
550 return R->
getKind() == GRBugReporterKind;
570 virtual void anchor();
574 : BR(br), NMC(Backmap) {}
587 return getStateManager().getSValBuilder();
611 std::function<std::string(BugReporterContext &, BugReport &)>;
617 const bool IsPrunable;
629 std::string Msg = Cb(BRC, R);
633 return std::move(Msg);
647 std::vector<std::unique_ptr<NoteTag>> Tags;
653 std::unique_ptr<NoteTag> T(
new NoteTag(std::move(Cb), IsPrunable));
654 Tags.push_back(std::move(T));
655 return Tags.back().get();
659 friend class TagVisitor;
666 #endif // LLVM_CLANG_STATICANALYZER_CORE_BUGREPORTER_BUGREPORTER_H const ExplodedNode * getOriginalNode(const ExplodedNode *N) override
BugReporter(BugReporterData &d)
bool shouldPrunePath() const
Indicates whether or not any path pruning should take place when generating a PathDiagnostic from thi...
MemRegion - The root abstract class for all memory regions.
PathDiagnosticLocation getUniqueingLocation() const
Get the location on which the report should be uniqued.
ASTContext & getASTContext()
bool isInteresting(SymbolRef sym)
AnalyzerOptions & getAnalyzerOptions()
Stmt - This represents one statement.
const NoteTag * makeNoteTag(Callback &&Cb, bool IsPrunable=false)
Decl - This represents one declaration (or definition), e.g.
StringRef getDescription() const
ArrayRef< PathDiagnosticConsumer * > getPathDiagnosticConsumers()
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
virtual PathDiagnosticLocation getLocation(const SourceManager &SM) const
Return the "definitive" location of the reported bug.
virtual std::unique_ptr< DiagnosticForConsumerMapTy > generatePathDiagnostics(ArrayRef< PathDiagnosticConsumer *> consumers, ArrayRef< BugReport *> &bugReports)
NodeMapClosure(InterExplodedGraphMap &m)
void addNote(StringRef Msg, const PathDiagnosticLocation &Pos)
void disablePathPruning()
Disable all path pruning when generating a PathDiagnostic.
SmallVector< SourceRange, 4 > Ranges
virtual AnalyzerOptions & getAnalyzerOptions()=0
llvm::DenseMap< PathDiagnosticConsumer *, std::unique_ptr< PathDiagnostic > > DiagnosticForConsumerMapTy
A mapping from diagnostic consumers to the diagnostics they should consume.
void clearVisitors()
Remove all visitors attached to this bug report.
void addRange(SourceRange R)
Add a range to a bug report.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
BugReport(BugType &bt, StringRef desc, const ExplodedNode *errornode, PathDiagnosticLocation LocationToUnique, const Decl *DeclToUnique)
Create a BugReport with a custom uniqueing location.
bool isValid() const
Returns whether or not this report should be considered valid.
std::function< std::string(BugReporterContext &, BugReport &)> Callback
llvm::SmallSet< const ExplodedNode *, 4 > TrackedConditions
Conditions we're already tracking.
std::string ShortDescription
virtual DiagnosticsEngine & getDiagnostic()=0
llvm::SmallSet< InvalidationRecord, 4 > Invalidations
If non-empty, this bug report is likely a false positive and should not be shown to the user...
SmallVector< Regions *, 2 > interestingRegions
A (stack of) set of regions that are registered with this report as being "interesting", and thus used to help decide which diagnostics to include when constructing the final path diagnostic.
virtual llvm::iterator_range< ranges_iterator > getRanges()
Get the SourceRanges associated with the report.
llvm::FoldingSet< BugReporterVisitor > CallbacksSet
Used for ensuring the visitors are only added once.
const Stmt * getStmt() const
llvm::SmallSet< const LocationContext *, 2 > InterestingLocationContexts
A set of location contexts that correspoind to call sites which should be considered "interesting"...
const BugType & getBugType() const
BugReporter(BugReporterData &d, Kind k)
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified...
ASTContext & getContext()
Concrete class used by the front-end to report problems and issues.
ExplodedGraph & getGraph()
void Profile(llvm::FoldingSetNodeID &ID) const
GRBugReporter(BugReporterData &d, ExprEngine &eng)
const Decl * getDeclWithIssue() const
Return the canonical declaration, be it a method or class, where this issue semantically occurred...
static bool classof(const ProgramPointTag *T)
void addVisitor(std::unique_ptr< BugReporterVisitor > visitor)
Add custom or predefined bug report visitors to this report.
virtual const NoteList & getNotes()
const_iterator begin() const
NodeMapClosure & getNodeResolver()
const Decl * UniqueingDecl
VisitorList::iterator visitor_iterator
BugReportEquivClass(std::unique_ptr< BugReport > R)
bool DoNotPrunePath
When set, this flag disables all callstack pruning from a diagnostic path.
virtual const ExtraTextList & getExtraText()
BugTypesTy::iterator iterator
Iterator over the set of BugTypes tracked by the BugReporter.
visitor_iterator visitor_end()
visitor_iterator visitor_begin()
Iterators through the custom diagnostic visitors.
virtual SourceManager & getSourceManager()=0
const Decl * getUniqueingDecl() const
Get the declaration containing the uniqueing location.
void addNote(StringRef Msg, const PathDiagnosticLocation &Pos, ArrayRef< SourceRange > Ranges)
Add new item to the list of additional notes that need to be attached to this path-insensitive report...
SValBuilder & getSValBuilder()
BugReporterContext(GRBugReporter &br, InterExplodedGraphMap &Backmap)
void markInteresting(SymbolRef sym)
The tag upon which the TagVisitor reacts.
std::pair< const void *, const void * > InvalidationRecord
Used to track unique reasons why a bug report might be invalid.
AnalyzerOptions & getAnalyzerOptions()
virtual ArrayRef< PathDiagnosticConsumer * > getPathDiagnosticConsumers()=0
BugReporter is a utility class for generating PathDiagnostics for analysis.
PathDiagnosticLocation UniqueingLocation
static bool classof(const BugReporter *R)
classof - Used by isa<>, cast<>, and dyn_cast<>.
EQClasses_iterator EQClasses_begin()
const ExplodedNode * ErrorNode
ProgramPoints can be "tagged" as representing points specific to a given analysis entity...
ExplodedGraph & getGraph()
getGraph - Get the exploded graph created by the analysis engine for the analyzed method or function...
SVal - This represents a symbolic expression, which can be either an L-value or an R-value...
PathDiagnosticLocation Location
const Decl * DeclWithIssue
VisitorList Callbacks
A set of custom visitors which generate "event" diagnostics at interesting points in the path...
SmallVector< Symbols *, 2 > interestingSymbols
A (stack of) a set of symbols that are registered with this report as being "interesting", and thus used to help decide which diagnostics to include when constructing the final path diagnostic.
Dataflow Directional Tag Classes.
bool addTrackedCondition(const ExplodedNode *Cond)
Notes that the condition of the CFGBlock associated with Cond is being tracked.
BugReport(const BugType &bt, StringRef desc, const ExplodedNode *errornode)
Optional< std::string > generateMessage(BugReporterContext &BRC, BugReport &R) const
BugReport(const BugType &bt, StringRef desc, PathDiagnosticLocation l)
GRBugReporter & getBugReporter()
BugReport(const BugType &bt, StringRef shortDesc, StringRef desc, const ExplodedNode *errornode)
llvm::DenseMap< const ExplodedNode *, const ExplodedNode * > InterExplodedGraphMap
StringRef getTagDescription() const override
DiagnosticsEngine & getDiagnostic()
const_iterator end() const
ProgramStateManager & getStateManager()
virtual ~NodeResolver()=default
const ExplodedNode * getErrorNode() const
virtual void Profile(llvm::FoldingSetNodeID &hash) const
Profile to identify equivalent bug reports for error report coalescing.
EQClasses_iterator EQClasses_end()
StringRef getShortDescription(bool UseFallback=true) const
llvm::FoldingSet< BugReportEquivClass >::iterator EQClasses_iterator
Iterator over the set of BugReports tracked by the BugReporter.
Stores options for the analyzer from the command line.
llvm::ilist< BugReport >::iterator iterator
SourceManager & getSourceManager()
ProgramStateManager & getStateManager()
getStateManager - Return the state manager used by the analysis engine.
Defines the clang::SourceLocation class and associated facilities.
void addExtraText(StringRef S)
This allows for addition of meta data to the diagnostic.
GRBugReporter is used for generating path-sensitive reports.
void markInvalid(const void *Tag, const void *Data)
Marks the current report as invalid, meaning that it is probably a false positive and should not be r...
unsigned kind
All of the diagnostics that can be emitted by the frontend.
virtual const ExplodedNode * getOriginalNode(const ExplodedNode *N)=0
A trivial tuple used to represent a source range.
This class provides an interface through which checkers can create individual bug reports...
llvm::ilist< BugReport >::const_iterator const_iterator
This class handles loading and caching of source files into memory.
const void * getTagKind() const
Used to implement 'isKind' in subclasses.
virtual ASTContext & getASTContext()=0
SourceManager & getSourceManager()
void setDeclWithIssue(const Decl *declWithIssue)
Specifically set the Decl where an issue occurred.
bool isPathSensitive() const
True when the report has an execution path associated with it.