clang: include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14#ifndef LLVM_CLANG_STATICANALYZER_CORE_BUGREPORTER_BUGREPORTER_H
15#define LLVM_CLANG_STATICANALYZER_CORE_BUGREPORTER_BUGREPORTER_H
16
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"
39#include
40#include
41#include
42#include
43#include
44#include
45
47
54
55namespace ento {
56
63
64
65
66
67
68
69
71 llvm::DenseMap<PathDiagnosticConsumer *, std::unique_ptr>;
72
73
74
75
76
84
85
86
87
88
89
90
92private:
94 std::string Msg;
95
96public:
99
100
101
103
104
105
107
111
115};
116
117
118
120public:
122
123protected:
126
131
135
138
143
144public:
146
148
150
151
152
153
154
155
156
158
159
160
161
162
168
169
170
171
172
174
175
176
177
179
180
181
182
183
184
185
186
187
188
190
191
192
193
194
196
197
198
199
200
203 auto P = std::make_shared(Pos, Msg);
204
205 for (const auto &R : Ranges)
206 P->addRange(R);
207
208 Notes.push_back(std::move(P));
209 }
210
214
215
216
217
218
219
220
221
223 assert((R.isValid() || Ranges.empty()) && "Invalid range can only be used "
224 "to specify that the report does not have a range.");
226 }
227
228
232
233
234
235
236
237
238
239
243
245
246
247
248 virtual void Profile(llvm::FoldingSetNodeID& hash) const = 0;
249};
250
253 const Decl *DeclWithIssue = nullptr;
254
255public:
258
262
264 assert(Location.isValid());
265 return Location;
266 }
267
269 return DeclWithIssue;
270 }
271
275
279
280
281
283 DeclWithIssue = declWithIssue;
284 }
285
286 void Profile(llvm::FoldingSetNodeID& hash) const override;
287};
288
290public:
293 using visitor_range = llvm::iterator_range<visitor_iterator>;
294
295protected:
296
297
299
300
301
303
304
305
306
307
308
309
310
312
313
314
315
316
317
318 llvm::DenseMap<const MemRegion *, bugreporter::TrackingKind>
320
321
322
324
325
326
328
329
331
332
333
334
336
337
338
339
340
342
343
344
345
346
347
349
350
352
353
354
357
359
360
361
362
363
364
365 std::map<PathDiagnosticPieceRef, std::unique_ptr>
367
368public:
372
378
379
380
381
382
383
384
385
389 const Decl *DeclToUnique)
391 DeclToUnique) {}
392
396 const Decl *DeclToUnique);
397
401
403
404
405
407
408
410
411
415
416
420
422
424
426
427
428
429
432
434
435
436
437
441
443
444
445
446
450
455
456 std::optionalbugreporter::TrackingKind
458
459 std::optionalbugreporter::TrackingKind
461
463
464
465
466
467
471
472
473
474
475
476
477
478
479
480
484
485
486
487
488 void Profile(llvm::FoldingSetNodeID &hash) const override;
489
490
491
492
493
494
495 void addVisitor(std::unique_ptr visitor);
496
497 template <class VisitorType, class... Args>
500 std::make_unique(std::forward(ConstructorArgs)...));
501 }
502
503
504
506
507
511
512
513
514
518
520 std::unique_ptr StackHint) {
521 StackHints[Piece] = std::move(StackHint);
522 }
523
527
528
529
530 std::string
535 return I->second->getMessage(N);
536 return "";
537 }
538};
539
540
541
542
543
546
547
549
550 void AddReport(std::unique_ptr &&R) {
551 Reports.push_back(std::move(R));
552 }
553
554public:
556
558
559 void Profile(llvm::FoldingSetNodeID& ID) const {
560 assert(!Reports.empty());
561 Reports.front()->Profile(ID);
562 }
563};
564
565
566
567
568
580
581
582
583
584
585
587private:
589
590
591 const Decl *AnalysisEntryPoint = nullptr;
592
593
595
596
597 llvm::FoldingSet EQClasses;
598
599
600 std::vector<BugReportEquivClass *> EQClassesVector;
601
602
604
605public:
608
609
611
614 return D.getPathDiagnosticConsumers();
615 }
616
617
620 return EQClasses;
621 }
622
624
627
629
632
633
635
637 assert(EntryPoint);
638 AnalysisEntryPoint = EntryPoint;
639 }
640
641
642
643
644
645
646 virtual void emitReport(std::unique_ptr R);
647
650 StringRef BugCategory, StringRef BugStr,
654
655 void EmitBasicReport(const Decl *DeclWithIssue, CheckerNameRef CheckerName,
656 StringRef BugName, StringRef BugCategory,
657 StringRef BugStr, PathDiagnosticLocation Loc,
659 ArrayRef Fixits = {});
660
661private:
662 llvm::StringMap<std::unique_ptr> StrBugTypes;
663
664
665
666 BugType *getBugTypeForName(CheckerNameRef CheckerName, StringRef name,
667 StringRef category);
668
669 virtual BugReport *
670 findReportInEquivalenceClass(BugReportEquivClass &eqClass,
671 SmallVectorImpl<BugReport *> &bugReports) {
672 return eqClass.getReports()[0].get();
673 }
674
675protected:
676
677 virtual std::unique_ptr
679 BugReport *exampleReport,
680 ArrayRef<std::unique_ptr> consumers,
681 ArrayRef<BugReport *> bugReports);
682};
683
684
687
688 BugReport *findReportInEquivalenceClass(
691
692
693 std::unique_ptr generateDiagnosticForConsumerMap(
695 ArrayRef<std::unique_ptr> consumers,
697
698public:
701
702
703
705
706
707
709
710
711
712
713
714
716 ArrayRef<std::unique_ptr> consumers,
718
719 void emitReport(std::unique_ptr R) override;
720};
721
722
725
726 virtual void anchor();
727
728public:
730
732
735
737 return BR.getStateManager();
738 }
739
741 return BR.getContext();
742 }
743
745 return BR.getSourceManager();
746 }
747
749 return BR.getAnalyzerOptions();
750 }
751};
752
753
754
755
756
757
758
759
760
762public:
763 StringRef getDebugTag() const override { return "Data Tag"; }
764
765
767 std::vector<std::unique_ptr> Tags;
768
769 public:
770 template <class DataTagType, class... Args>
771 const DataTagType *make(Args &&... ConstructorArgs) {
772
773
774 Tags.emplace_back(
775 new DataTagType(std::forward(ConstructorArgs)...));
776 return static_cast<DataTagType *>(Tags.back().get());
777 }
778 };
779
780protected:
782};
783
784
785
787public:
790
791private:
792 static int Kind;
793
795 const bool IsPrunable;
796
797 NoteTag(Callback &&Cb, bool IsPrunable)
798 : DataTag(&Kind), Cb(std::move(Cb)), IsPrunable(IsPrunable) {}
799
800public:
802 return T->getTagKind() == &Kind;
803 }
804
807 std::string Msg = Cb(BRC, R);
808 if (Msg.empty())
809 return std::nullopt;
810
811 return std::move(Msg);
812 }
813
815
816
817
818 return "Note Tag";
819 }
820
822
825};
826
827}
828
829}
830
831#endif
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.
ProgramPointTag(void *tagKind=nullptr)
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)
Definition BugReporter.h:256
PathDiagnosticLocation getLocation() const override
The primary location of the bug report that points at the undesirable behavior in the code.
Definition BugReporter.h:263
const Decl * getDeclWithIssue() const override
The smallest declaration that contains the bug location.
Definition BugReporter.h:268
PathDiagnosticLocation getUniqueingLocation() const override
Get the location on which the report should be uniqued.
Definition BugReporter.h:272
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)
Definition BugReporter.h:259
const Decl * getUniqueingDecl() const override
Get the declaration that corresponds to (usually contains) the uniqueing location.
Definition BugReporter.h:276
void setDeclWithIssue(const Decl *declWithIssue)
Specifically set the Decl where an issue occurred.
Definition BugReporter.h:282
Definition BugReporter.h:544
ArrayRef< std::unique_ptr< BugReport > > getReports() const
Definition BugReporter.h:557
BugReportEquivClass(std::unique_ptr< BugReport > R)
Definition BugReporter.h:555
void Profile(llvm::FoldingSetNodeID &ID) const
Definition BugReporter.h:559
friend class BugReporter
Definition BugReporter.h:545
This class provides an interface through which checkers can create individual bug reports.
Definition BugReporter.h:119
llvm::ArrayRef< FixItHint > getFixits() const
Definition BugReporter.h:244
void addRange(SourceRange R)
Add a range to a bug report.
Definition BugReporter.h:222
SmallVector< SourceRange, 4 > Ranges
Definition BugReporter.h:132
std::string ShortDescription
Definition BugReporter.h:129
std::string Description
Definition BugReporter.h:130
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.
Definition BugReporter.h:201
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.
friend class BugReportEquivClass
Definition BugReporter.h:124
virtual const Decl * getUniqueingDecl() const =0
Get the declaration that corresponds to (usually contains) the uniqueing location.
SmallVector< std::shared_ptr< PathDiagnosticNotePiece >, 4 > Notes
Definition BugReporter.h:133
SmallVector< FixItHint, 4 > Fixits
Definition BugReporter.h:134
ArrayRef< std::shared_ptr< PathDiagnosticNotePiece > > getNotes()
Definition BugReporter.h:211
Kind
Definition BugReporter.h:121
@ PathSensitive
Definition BugReporter.h:121
@ Basic
Definition BugReporter.h:121
BugReport(Kind kind, const BugType &bt, StringRef desc)
Definition BugReporter.h:136
Kind K
Definition BugReporter.h:127
void addFixItHint(const FixItHint &F)
Add a fix-it hint to the bug report.
Definition BugReporter.h:240
StringRef getDescription() const
A verbose warning message that is appropriate for displaying next to the source code that introduces ...
Definition BugReporter.h:157
const BugType & BT
Definition BugReporter.h:128
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
Definition BugReporter.h:149
StringRef getShortDescription(bool UseFallback=true) const
A short general warning message that is appropriate for displaying in the list of all reported bugs.
Definition BugReporter.h:163
friend class BugReporter
Definition BugReporter.h:125
Kind getKind() const
Definition BugReporter.h:147
virtual ArrayRef< SourceRange > getRanges() const
Get the SourceRanges associated with the report.
Definition BugReporter.h:229
virtual const Decl * getDeclWithIssue() const =0
The smallest declaration that contains the bug location.
BugReport(Kind K, const BugType &BT, StringRef ShortDescription, StringRef Description)
Definition BugReporter.h:139
Definition BugReporter.h:723
ASTContext & getASTContext() const
Definition BugReporter.h:740
BugReporterContext(PathSensitiveBugReporter &br)
Definition BugReporter.h:729
ProgramStateManager & getStateManager() const
Definition BugReporter.h:736
const SourceManager & getSourceManager() const
Definition BugReporter.h:744
PathSensitiveBugReporter & getBugReporter()
Definition BugReporter.h:733
virtual ~BugReporterContext()=default
const PathSensitiveBugReporter & getBugReporter() const
Definition BugReporter.h:734
const AnalyzerOptions & getAnalyzerOptions() const
Definition BugReporter.h:748
Definition BugReporter.h:569
virtual ASTContext & getASTContext()=0
virtual ~BugReporterData()=default
virtual ArrayRef< std::unique_ptr< PathDiagnosticConsumer > > getPathDiagnosticConsumers()=0
virtual AnalyzerOptions & getAnalyzerOptions()=0
virtual SourceManager & getSourceManager()=0
virtual Preprocessor & getPreprocessor()=0
Preprocessor & getPreprocessor()
Definition BugReporter.h:630
void FlushReports()
Generate and flush diagnostics for all bug reports.
BugReporter(BugReporterData &d)
const SourceManager & getSourceManager()
Definition BugReporter.h:625
const Decl * getAnalysisEntryPoint() const
Get the top-level entry point for the issue to be reported.
Definition BugReporter.h:634
ArrayRef< std::unique_ptr< PathDiagnosticConsumer > > getPathDiagnosticConsumers()
Definition BugReporter.h:613
const SourceManager & getSourceManager() const
Definition BugReporter.h:626
const Preprocessor & getPreprocessor() const
Definition BugReporter.h:631
llvm::iterator_range< EQClasses_iterator > equivalenceClasses()
Definition BugReporter.h:619
ASTContext & getContext()
Definition BugReporter.h:623
void EmitBasicReport(const Decl *DeclWithIssue, const CheckerFrontend *Checker, StringRef BugName, StringRef BugCategory, StringRef BugStr, PathDiagnosticLocation Loc, ArrayRef< SourceRange > Ranges={}, ArrayRef< FixItHint > Fixits={})
virtual std::unique_ptr< DiagnosticForConsumerMapTy > generateDiagnosticForConsumerMap(BugReport *exampleReport, ArrayRef< std::unique_ptr< PathDiagnosticConsumer > > consumers, ArrayRef< BugReport * > bugReports)
Generate the diagnostics for the given bug report.
const AnalyzerOptions & getAnalyzerOptions()
Definition BugReporter.h:628
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.
Definition BugReporter.h:618
void setAnalysisEntryPoint(const Decl *EntryPoint)
Definition BugReporter.h:636
The non-templated common ancestor of all the simple Checker<...> classes.
A CheckerFrontend instance is what the user recognizes as "one checker": it has a public canonical na...
Simple checker classes that implement one frontend (i.e.
Definition BugReporter.h:766
const DataTagType * make(Args &&... ConstructorArgs)
Definition BugReporter.h:771
DataTag(void *TagKind)
Definition BugReporter.h:781
StringRef getDebugTag() const override
The description of this program point which will be dumped for debugging purposes.
Definition BugReporter.h:763
MemRegion - The root abstract class for all memory regions.
StringRef getDebugTag() const override
The description of this program point which will be dumped for debugging purposes.
Definition BugReporter.h:814
friend class TagVisitor
Definition BugReporter.h:824
static bool classof(const ProgramPointTag *T)
Definition BugReporter.h:801
friend class Factory
Definition BugReporter.h:823
bool isPrunable() const
Definition BugReporter.h:821
std::function< std::string(BugReporterContext &, PathSensitiveBugReport &)> Callback
Definition BugReporter.h:788
std::optional< std::string > generateMessage(BugReporterContext &BRC, PathSensitiveBugReport &R) const
Definition BugReporter.h:805
Definition BugReporter.h:289
void markInteresting(SymbolRef sym, bugreporter::TrackingKind TKind=bugreporter::TrackingKind::Thorough)
Marks a symbol as interesting.
void addVisitor(Args &&... ConstructorArgs)
Definition BugReporter.h:498
SmallVector< std::unique_ptr< BugReporterVisitor >, 8 > VisitorList
Definition BugReporter.h:291
PathDiagnosticLocation getUniqueingLocation() const override
Get the location on which the report should be uniqued.
Definition BugReporter.h:412
VisitorList Callbacks
A set of custom visitors which generate "event" diagnostics at interesting points in the path.
Definition BugReporter.h:327
const Stmt * getStmt() const
std::string getCallStackMessage(PathDiagnosticPieceRef Piece, const ExplodedNode *N) const
Produce the hint for the given node.
Definition BugReporter.h:531
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.
llvm::SmallPtrSet< const ExplodedNode *, 4 > TrackedConditions
Conditions we're already tracking.
Definition BugReporter.h:351
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...
Definition BugReporter.h:366
std::pair< const void *, const void * > InvalidationRecord
Used to track unique reasons why a bug report might be invalid.
Definition BugReporter.h:341
bool shouldPrunePath() const
Indicates whether or not any path pruning should take place when generating a PathDiagnostic from thi...
Definition BugReporter.h:406
visitor_range visitors()
Definition BugReporter.h:510
PathDiagnosticLocation UniqueingLocation
Reports with different uniqueing locations are considered to be different for the purposes of dedupli...
Definition BugReporter.h:355
ArrayRef< SourceRange > getRanges() const override
Get the SourceRanges associated with the report.
visitor_iterator visitor_end()
Definition BugReporter.h:509
llvm::DenseMap< SymbolRef, bugreporter::TrackingKind > InterestingSymbols
Profile to identify equivalent bug reports for error report coalescing.
Definition BugReporter.h:311
const Decl * getUniqueingDecl() const override
Get the declaration containing the uniqueing location.
Definition BugReporter.h:417
llvm::SmallSet< InvalidationRecord, 4 > Invalidations
If non-empty, this bug report is likely a false positive and should not be shown to the user.
Definition BugReporter.h:348
const ExplodedNode * getErrorNode() const
Definition BugReporter.h:402
PathSensitiveBugReport(const BugType &bt, StringRef desc, const ExplodedNode *errorNode)
Definition BugReporter.h:369
static bool classof(const BugReport *R)
Definition BugReporter.h:398
const ExplodedNode * ErrorNode
The ExplodedGraph node against which the report was thrown.
Definition BugReporter.h:298
PathSensitiveBugReport(const BugType &bt, StringRef shortDesc, StringRef desc, const ExplodedNode *errorNode)
Definition BugReporter.h:373
bool addTrackedCondition(const ExplodedNode *Cond)
Notes that the condition of the CFGBlock associated with Cond is being tracked.
Definition BugReporter.h:515
visitor_iterator visitor_begin()
Iterators through the custom diagnostic visitors.
Definition BugReporter.h:508
void addCallStackHint(PathDiagnosticPieceRef Piece, std::unique_ptr< StackHintGenerator > StackHint)
Definition BugReporter.h:519
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...
Definition BugReporter.h:481
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
Definition BugReporter.h:524
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.
Definition BugReporter.h:468
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.
Definition BugReporter.h:335
PathSensitiveBugReport(const BugType &bt, StringRef desc, const ExplodedNode *errorNode, PathDiagnosticLocation LocationToUnique, const Decl *DeclToUnique)
Create a PathSensitiveBugReport with a custom uniqueing location.
Definition BugReporter.h:386
llvm::DenseMap< const MemRegion *, bugreporter::TrackingKind > InterestingRegions
A (stack of) set of regions that are registered with this report as being "interesting",...
Definition BugReporter.h:319
llvm::iterator_range< visitor_iterator > visitor_range
Definition BugReporter.h:293
bool isInteresting(SymbolRef sym) const
const SourceRange ErrorNodeRange
The range that corresponds to ErrorNode's program point.
Definition BugReporter.h:302
VisitorList::iterator visitor_iterator
Definition BugReporter.h:292
llvm::FoldingSet< BugReporterVisitor > CallbacksSet
Used for ensuring the visitors are only added once.
Definition BugReporter.h:330
void disablePathPruning()
Disable all path pruning when generating a PathDiagnostic.
Definition BugReporter.h:409
llvm::SmallPtrSet< const LocationContext *, 2 > InterestingLocationContexts
A set of location contexts that correspoind to call sites which should be considered "interesting".
Definition BugReporter.h:323
const Decl * UniqueingDecl
Definition BugReporter.h:356
GRBugReporter is used for generating path-sensitive reports.
Definition BugReporter.h:685
const ExplodedGraph & getGraph() const
getGraph - Get the exploded graph created by the analysis engine for the analyzed method or function.
void emitReport(std::unique_ptr< BugReport > R) override
Add the given report to the set of reports tracked by BugReporter.
std::unique_ptr< DiagnosticForConsumerMapTy > generatePathDiagnostics(ArrayRef< std::unique_ptr< PathDiagnosticConsumer > > consumers, ArrayRef< PathSensitiveBugReport * > &bugReports)
bugReports A set of bug reports within a single equivalence class
ProgramStateManager & getStateManager() const
getStateManager - Return the state manager used by the analysis engine.
PathSensitiveBugReporter(BugReporterData &d, ExprEngine &eng)
Definition BugReporter.h:699
SVal - This represents a symbolic expression, which can be either an L-value or an R-value.
StackHintGeneratorForSymbol(SymbolRef S, StringRef M)
Definition BugReporter.h:97
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()
Definition BugReporter.h:112
virtual std::string getMessageForReturn(const CallExpr *CallExpr)
Definition BugReporter.h:108
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.
Definition BugReporter.h:77
virtual ~StackHintGenerator()=0
virtual std::string getMessage(const ExplodedNode *N)=0
Construct the Diagnostic message for the given ExplodedNode.
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...
const SymExpr * SymbolRef
llvm::DenseMap< PathDiagnosticConsumer *, std::unique_ptr< PathDiagnostic > > DiagnosticForConsumerMapTy
A mapping from diagnostic consumers to the diagnostics they should consume.
Definition BugReporter.h:70
std::shared_ptr< PathDiagnosticPiece > PathDiagnosticPieceRef
The JSON file list parser is used to communicate input to InstallAPI.
const FunctionProtoType * T
int const char * function