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