Go to the documentation of this file.
14 #ifndef LLVM_CLANG_STATICANALYZER_CORE_BUGREPORTER_BUGREPORTER_H
15 #define LLVM_CLANG_STATICANALYZER_CORE_BUGREPORTER_BUGREPORTER_H
28 #include "llvm/ADT/ArrayRef.h"
29 #include "llvm/ADT/DenseSet.h"
30 #include "llvm/ADT/FoldingSet.h"
31 #include "llvm/ADT/ImmutableSet.h"
32 #include "llvm/ADT/None.h"
33 #include "llvm/ADT/SmallSet.h"
34 #include "llvm/ADT/SmallVector.h"
35 #include "llvm/ADT/StringMap.h"
36 #include "llvm/ADT/StringRef.h"
37 #include "llvm/ADT/ilist.h"
38 #include "llvm/ADT/ilist_node.h"
39 #include "llvm/ADT/iterator_range.h"
48 class AnalyzerOptions;
51 class LocationContext;
71 llvm::DenseMap<PathDiagnosticConsumer *, std::unique_ptr<PathDiagnostic>>;
203 auto P = std::make_shared<PathDiagnosticNotePiece>(Pos, Msg);
205 for (
const auto &R :
Ranges)
208 Notes.push_back(std::move(
P));
223 assert((R.
isValid() ||
Ranges.empty()) &&
"Invalid range can only be used "
224 "to specify that the report does not have a range.");
248 virtual void Profile(llvm::FoldingSetNodeID& hash)
const = 0;
253 const Decl *DeclWithIssue =
nullptr;
269 return DeclWithIssue;
283 DeclWithIssue = declWithIssue;
286 void Profile(llvm::FoldingSetNodeID& hash)
const override;
318 llvm::DenseMap<const MemRegion *, bugreporter::TrackingKind>
365 std::map<PathDiagnosticPieceRef, std::unique_ptr<StackHintGenerator>>
389 const Decl *DeclToUnique)
396 const Decl *DeclToUnique);
488 void Profile(llvm::FoldingSetNodeID &hash)
const override;
495 void addVisitor(std::unique_ptr<BugReporterVisitor> visitor);
497 template <
class VisitorType,
class... Args>
500 std::make_unique<VisitorType>(std::forward<Args>(ConstructorArgs)...));
520 std::unique_ptr<StackHintGenerator> StackHint) {
535 return I->second->getMessage(N);
550 void AddReport(std::unique_ptr<BugReport> &&R) {
551 Reports.push_back(std::move(R));
560 assert(!Reports.empty());
561 Reports.front()->Profile(
ID);
593 llvm::FoldingSet<BugReportEquivClass> EQClasses;
596 std::vector<BugReportEquivClass *> EQClassesVector;
627 virtual void emitReport(std::unique_ptr<BugReport> R);
630 StringRef BugName, StringRef BugCategory,
636 StringRef BugName, StringRef BugCategory,
642 llvm::StringMap<std::unique_ptr<BugType>> StrBugTypes;
657 virtual std::unique_ptr<DiagnosticForConsumerMapTy>
672 std::unique_ptr<DiagnosticForConsumerMapTy>
673 generateDiagnosticForConsumerMap(
BugReport *exampleReport,
697 void emitReport(std::unique_ptr<BugReport> R)
override;
704 virtual void anchor();
744 std::vector<std::unique_ptr<DataTag>> Tags;
747 template <
class DataTagType,
class... Args>
748 const DataTagType *
make(Args &&... ConstructorArgs) {
752 new DataTagType(std::forward<Args>(ConstructorArgs)...));
753 return static_cast<DataTagType *
>(Tags.back().get());
772 const bool IsPrunable;
775 :
DataTag(&Kind), Cb(
std::move(Cb)), IsPrunable(IsPrunable) {}
788 return std::move(Msg);
808 #endif // LLVM_CLANG_STATICANALYZER_CORE_BUGREPORTER_BUGREPORTER_H
virtual void Profile(llvm::FoldingSetNodeID &hash) const =0
Reports are uniqued to ensure that we do not emit multiple diagnostics for each bug.
bool isValid() const
Returns whether or not this report should be considered valid.
std::map< PathDiagnosticPieceRef, std::unique_ptr< StackHintGenerator > > StackHints
If an event occurs in a different frame than the final diagnostic, supply a message that will be used...
virtual ~BugReporterData()=default
llvm::SmallSet< const LocationContext *, 2 > InterestingLocationContexts
A set of location contexts that correspoind to call sites which should be considered "interesting".
void addVisitor(std::unique_ptr< BugReporterVisitor > visitor)
Add custom or predefined bug report visitors to this report.
PathDiagnosticLocation UniqueingLocation
Reports with different uniqueing locations are considered to be different for the purposes of dedupli...
void addCallStackHint(PathDiagnosticPieceRef Piece, std::unique_ptr< StackHintGenerator > StackHint)
It wraps the AnalysisDeclContext to represent both the call stack with the help of StackFrameContext ...
llvm::ArrayRef< FixItHint > getFixits() const
A trivial tuple used to represent a source range.
llvm::FoldingSet< BugReportEquivClass >::iterator EQClasses_iterator
Iterator over the set of BugReports tracked by the BugReporter.
void Profile(llvm::FoldingSetNodeID &hash) const override
Reports are uniqued to ensure that we do not emit multiple diagnostics for each bug.
std::shared_ptr< PathDiagnosticPiece > PathDiagnosticPieceRef
virtual std::string getMessageForSymbolNotFound()
ProgramPoints can be "tagged" as representing points specific to a given analysis entity.
void Profile(llvm::FoldingSetNodeID &ID) const
const ExplodedNode * ErrorNode
The ExplodedGraph node against which the report was thrown.
Constructs a Stack hint for the given symbol.
virtual std::string getMessageForReturn(const CallExpr *CallExpr)
virtual Preprocessor & getPreprocessor()=0
BugReportEquivClass(std::unique_ptr< BugReport > R)
std::string getMessage(const ExplodedNode *N) override
Search the call expression for the symbol Sym and dispatch the 'getMessageForX()' methods to construc...
StackHintGeneratorForSymbol(SymbolRef S, StringRef M)
SmallVector< std::shared_ptr< PathDiagnosticNotePiece >, 4 > Notes
TrackingKind
Specifies the type of tracking for an expression.
bool shouldPrunePath() const
Indicates whether or not any path pruning should take place when generating a PathDiagnostic from thi...
const Stmt * getStmt() const
std::string getCallStackMessage(PathDiagnosticPieceRef Piece, const ExplodedNode *N) const
Produce the hint for the given node.
const Decl * getDeclWithIssue() const override
The smallest declaration that contains the bug location.
llvm::DenseMap< SymbolRef, bugreporter::TrackingKind > InterestingSymbols
Profile to identify equivalent bug reports for error report coalescing.
PathDiagnosticLocation getUniqueingLocation() const override
Get the location on which the report should be uniqued.
bool EQ(InterpState &S, CodePtr OpPC)
std::pair< const void *, const void * > InvalidationRecord
Used to track unique reasons why a bug report might be invalid.
virtual AnalyzerOptions & getAnalyzerOptions()=0
void FlushReports()
Generate and flush diagnostics for all bug reports.
PathDiagnosticLocation getUniqueingLocation() const override
Get the location on which the report should be uniqued.
This class handles loading and caching of source files into memory.
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...
MemRegion - The root abstract class for all memory regions.
Annotates a diagnostic with some code that should be inserted, removed, or replaced to fix the proble...
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
BugReporterContext(PathSensitiveBugReporter &br)
virtual SourceManager & getSourceManager()=0
Optional< std::string > generateMessage(BugReporterContext &BRC, PathSensitiveBugReport &R) const
BasicBugReport(const BugType &bt, StringRef desc, PathDiagnosticLocation l)
The tag that carries some information with it.
SmallVector< SourceRange, 4 > Ranges
The visitor detects NoteTags and displays the event notes they contain.
llvm::DenseMap< PathDiagnosticConsumer *, std::unique_ptr< PathDiagnostic > > DiagnosticForConsumerMapTy
A mapping from diagnostic consumers to the diagnostics they should consume.
EQClasses_iterator EQClasses_begin()
llvm::SmallSet< const ExplodedNode *, 4 > TrackedConditions
Conditions we're already tracking.
const Decl * getUniqueingDecl() const override
Get the declaration containing the uniqueing location.
virtual ~StackHintGenerator()=0
virtual void emitReport(std::unique_ptr< BugReport > R)
Add the given report to the set of reports tracked by BugReporter.
Preprocessor & getPreprocessor()
const DataTagType * make(Args &&... ConstructorArgs)
const SourceManager & getSourceManager() const
ArrayRef< PathDiagnosticConsumer * > getPathDiagnosticConsumers()
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
static bool classof(const BugReport *R)
const ExplodedNode * getErrorNode() const
PathDiagnosticLocation getLocation() const override
The primary location of the bug report that points at the undesirable behavior in the code.
const AnalyzerOptions & getAnalyzerOptions() const
StringRef getTagDescription() const override
const AnalyzerOptions & getAnalyzerOptions()
This wrapper is used to ensure that only StringRefs originating from the CheckerRegistry are used as ...
visitor_iterator visitor_end()
PathSensitiveBugReport(const BugType &bt, StringRef desc, const ExplodedNode *errorNode)
bool hasCallStackHint(PathDiagnosticPieceRef Piece) const
virtual std::unique_ptr< DiagnosticForConsumerMapTy > generateDiagnosticForConsumerMap(BugReport *exampleReport, ArrayRef< PathDiagnosticConsumer * > consumers, ArrayRef< BugReport * > bugReports)
Generate the diagnostics for the given bug report.
virtual ASTContext & getASTContext()=0
@ Thorough
Default tracking kind – specifies that as much information should be gathered about the tracked expre...
virtual ArrayRef< PathDiagnosticConsumer * > getPathDiagnosticConsumers()=0
PathSensitiveBugReporter(BugReporterData &d, ExprEngine &eng)
BugReporter is a utility class for generating PathDiagnostics for analysis.
static bool classof(const ProgramPointTag *T)
llvm::FoldingSet< BugReporterVisitor > CallbacksSet
Used for ensuring the visitors are only added once.
visitor_iterator visitor_begin()
Iterators through the custom diagnostic visitors.
EQClasses_iterator EQClasses_end()
virtual std::string getMessage(const ExplodedNode *N)=0
Construct the Diagnostic message for the given ExplodedNode.
virtual ArrayRef< SourceRange > getRanges() const
Get the SourceRanges associated with the report.
ArrayRef< std::unique_ptr< BugReport > > getReports() const
bool addTrackedCondition(const ExplodedNode *Cond)
Notes that the condition of the CFGBlock associated with Cond is being tracked.
const Decl * getDeclWithIssue() const override
The smallest declaration that contains the bug location.
void emitReport(std::unique_ptr< BugReport > R) override
Add the given report to the set of reports tracked by BugReporter.
const ExplodedGraph & getGraph() const
getGraph - Get the exploded graph created by the analysis engine for the analyzed method or function.
ArrayRef< SourceRange > getRanges() const override
Get the SourceRanges associated with the report.
const SourceManager & getSourceManager()
virtual const Decl * getDeclWithIssue() const =0
The smallest declaration that contains the bug location.
void EmitBasicReport(const Decl *DeclWithIssue, const CheckerBase *Checker, StringRef BugName, StringRef BugCategory, StringRef BugStr, PathDiagnosticLocation Loc, ArrayRef< SourceRange > Ranges=None, ArrayRef< FixItHint > Fixits=None)
llvm::DenseMap< const MemRegion *, bugreporter::TrackingKind > InterestingRegions
A (stack of) set of regions that are registered with this report as being "interesting",...
Interface for classes constructing Stack hints.
virtual ~BugReport()=default
Decl - This represents one declaration (or definition), e.g.
VisitorList Callbacks
A set of custom visitors which generate "event" diagnostics at interesting points in the path.
ProgramStateManager & getStateManager() const
getStateManager - Return the state manager used by the analysis engine.
void addRange(SourceRange R)
Add a range to a bug report.
virtual PathDiagnosticLocation getUniqueingLocation() const =0
Get the location on which the report should be uniqued.
Stores options for the analyzer from the command line.
StringRef getTagDescription() const override
BugReporter(BugReporterData &d)
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 report.
PathSensitiveBugReport(const BugType &bt, StringRef shortDesc, StringRef desc, const ExplodedNode *errorNode)
PathSensitiveBugReport(const BugType &bt, StringRef desc, const ExplodedNode *errorNode, PathDiagnosticLocation LocationToUnique, const Decl *DeclToUnique)
Create a PathSensitiveBugReport with a custom uniqueing location.
GRBugReporter is used for generating path-sensitive reports.
virtual const Decl * getUniqueingDecl() const =0
Get the declaration that corresponds to (usually contains) the uniqueing location.
StringRef getDescription() const
A verbose warning message that is appropriate for displaying next to the source code that introduces ...
PathSensitiveBugReporter & getBugReporter()
const void * getTagKind() const
Used to implement 'isKind' in subclasses.
void markNotInteresting(SymbolRef sym)
This class provides an interface through which checkers can create individual bug reports.
BugReport(Kind kind, const BugType &bt, StringRef desc)
llvm::iterator_range< visitor_iterator > visitor_range
Optional< bugreporter::TrackingKind > getInterestingnessKind(SymbolRef sym) const
const Decl * UniqueingDecl
Stmt - This represents one statement.
const SourceRange ErrorNodeRange
The range that corresponds to ErrorNode's program point.
VisitorList::iterator visitor_iterator
ArrayRef< std::shared_ptr< PathDiagnosticNotePiece > > getNotes()
void markInteresting(SymbolRef sym, bugreporter::TrackingKind TKind=bugreporter::TrackingKind::Thorough)
Marks a symbol as interesting.
virtual PathDiagnosticLocation getLocation() const =0
The primary location of the bug report that points at the undesirable behavior in the code.
void Profile(llvm::FoldingSetNodeID &hash) const override
Profile to identify equivalent bug reports for error report coalescing.
StringRef getShortDescription(bool UseFallback=true) const
A short general warning message that is appropriate for displaying in the list of all reported bugs.
std::unique_ptr< DiagnosticForConsumerMapTy > generatePathDiagnostics(ArrayRef< PathDiagnosticConsumer * > consumers, ArrayRef< PathSensitiveBugReport * > &bugReports)
bugReports A set of bug reports within a single equivalence class
void clearVisitors()
Remove all visitors attached to this bug report.
static bool classof(const BugReport *R)
bool isInteresting(SymbolRef sym) const
BugReport(Kind K, const BugType &BT, StringRef ShortDescription, StringRef Description)
SVal - This represents a symbolic expression, which can be either an L-value or an R-value.
void addFixItHint(const FixItHint &F)
Add a fix-it hint to the bug report.
llvm::SmallSet< InvalidationRecord, 4 > Invalidations
If non-empty, this bug report is likely a false positive and should not be shown to the user.
std::string ShortDescription
bool DoNotPrunePath
When set, this flag disables all callstack pruning from a diagnostic path.
void setDeclWithIssue(const Decl *declWithIssue)
Specifically set the Decl where an issue occurred.
~StackHintGeneratorForSymbol() override=default
This represents one expression.
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
ASTContext & getASTContext() const
virtual ~BugReporterContext()=default
void disablePathPruning()
Disable all path pruning when generating a PathDiagnostic.
The tag upon which the TagVisitor reacts.
SmallVector< FixItHint, 4 > Fixits
PathDiagnosticLocation getLocation() const override
The primary location of the bug report that points at the undesirable behavior in the code.
virtual std::string getMessageForArg(const Expr *ArgE, unsigned ArgIndex)
Produces the message of the following form: 'Msg via Nth parameter'.
std::function< std::string(BugReporterContext &, PathSensitiveBugReport &)> Callback
ProgramStateManager & getStateManager() const
const BugType & getBugType() const
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
const Decl * getUniqueingDecl() const override
Get the declaration that corresponds to (usually contains) the uniqueing location.
unsigned kind
All of the diagnostics that can be emitted by the frontend.
void addVisitor(Args &&... ConstructorArgs)
ASTContext & getContext()