clang: include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.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_BUGREPORTERVISITORS_H
15#define LLVM_CLANG_STATICANALYZER_CORE_BUGREPORTER_BUGREPORTERVISITORS_H
16
21#include "llvm/ADT/FoldingSet.h"
22#include "llvm/ADT/IntrusiveRefCntPtr.h"
23#include "llvm/ADT/STLExtras.h"
24#include "llvm/ADT/SmallPtrSet.h"
25#include "llvm/ADT/StringRef.h"
26#include
27#include
28#include
29#include
30
32
33class BinaryOperator;
34class CFGBlock;
35class DeclRefExpr;
36class Expr;
37class Stmt;
38
39namespace ento {
40
41class PathSensitiveBugReport;
42class BugReporterContext;
43class ExplodedNode;
44class MemRegion;
45class PathDiagnosticPiece;
47
48
50public:
54
55
56
59
61
62
63
64
65
66
67
68
69
70
71
75
76
77
81
82
83
84
85
86
90
91 virtual void Profile(llvm::FoldingSetNodeID &ID) const = 0;
92
93
97};
98
99namespace bugreporter {
100
101
103
104
106
107
108
109
111};
112
113
115
117
118
120};
121
122
123
124
125
126
129
130
132
133
134
136
137
139
140
141
142
145
146
148
150
151
153
155
156
157
158
160};
161
164
167
168
169
170
171
172
174private:
175 using ExpressionHandlerPtr = std::unique_ptr;
176 using StoreHandlerPtr = std::unique_ptr;
177
179 std::list ExpressionHandlers;
180 std::list StoreHandlers;
181
182protected:
183
185
186public:
188
191 }
192
194
195
196
198
200
201
203
204
206
207
209
211 }
212 };
213
214
215
216
217
218
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235 virtual Result track(SVal V, const MemRegion *R, TrackingOptions Opts = {},
237
238
239
240
241
242
243
245 TrackingOptions Opts);
246
247
248
249
250
252 ExpressionHandlers.push_front(std::move(SH));
253 }
254
255
256
257
258
260 ExpressionHandlers.push_back(std::move(SH));
261 }
262
263
264
265
266
268 StoreHandlers.push_front(std::move(SH));
269 }
270
271
272
273
274
276 StoreHandlers.push_back(std::move(SH));
277 }
278
279
280
281
282 template <class HandlerType, class... Args>
285 *this, std::forward(ConstructorArgs)...));
286 }
287
288
289
290
291 template <class HandlerType, class... Args>
294 *this, std::forward(ConstructorArgs)...));
295 }
296};
297
298
300private:
302
303public:
306
307
308
309
310
311
312
316
317
319};
320
321
323private:
325
326public:
329
330
331
332
333
334
335
336
339
341
342protected:
344 StringRef NodeText);
345};
346
347
349private:
351
352public:
354 : ParentTracker(ParentTracker) {}
355
357};
358
359
360
361
362
363
364
365
366
367
368
369
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
388 PathSensitiveBugReport &Report, TrackingOptions Opts = {},
389 const StackFrameContext *Origin = nullptr);
390
392
393}
394
398 const bool Assumption;
399 bool IsSatisfied = false;
400
401
402
403 bool IsTrackingTurnedOn = false;
404
405public:
407 StringRef Message)
408 : Message(Message), Constraint(constraint), Assumption(assumption) {}
409
410 void Profile(llvm::FoldingSetNodeID &ID) const override;
411
412
413
414 static const char *getTag();
415
419
420private:
421
422 bool isZeroCheck() const;
423
424
425 bool isUnderconstrained(const ExplodedNode *N) const;
426};
427
428
429
431public:
432 void Profile(llvm::FoldingSetNodeID &ID) const override {
433 static int x = 0;
434 ID.AddPointer(&x);
435 }
436
440
441
442
444};
445
446
448
449 constexpr static llvm::StringLiteral GenericTrueMessage =
450 "Assuming the condition is true";
451 constexpr static llvm::StringLiteral GenericFalseMessage =
452 "Assuming the condition is false";
453
454public:
455 void Profile(llvm::FoldingSetNodeID &ID) const override {
456 static int x = 0;
457 ID.AddPointer(&x);
458 }
459
460
461
462 static const char *getTag();
463
467
471
476
481
486 bool IsAssuming);
487
491 const ExplodedNode *N, bool TookTrue, bool IsAssuming);
492
497 bool IsAssuming);
498
503
504
505
506
507
508
509
510
511
512
513 bool printValue(const Expr *CondVarExpr, raw_ostream &Out,
514 const ExplodedNode *N, bool TookTrue, bool IsAssuming);
515
518 const ExplodedNode *N, std::optional &prunable,
519 bool IsSameFieldName);
520
522};
523
524
525
526
529public:
531 static int Tag = 0;
532 return static_cast<void *>(&Tag);
533 }
534
535 void Profile(llvm::FoldingSetNodeID &ID) const override {
537 }
538
541 return nullptr;
542 }
543
546};
547
548
549
550
551
552
554
556
557public:
559
560 void Profile(llvm::FoldingSetNodeID &ID) const override {
561 static int Tag = 0;
562 ID.AddPointer(&Tag);
563 ID.AddPointer(R);
564 }
565
569};
570
572
573
575
576
577 bool IsSatisfied = false;
578
579
580
581
582
583
584 bool IsTrackingTurnedOn = false;
585
586public:
588
589 void Profile(llvm::FoldingSetNodeID &ID) const override;
590
591
592
593 static const char *getTag();
594
598};
599
600
602public:
603 void Profile(llvm::FoldingSetNodeID &ID) const override;
604
608};
609
612
613
614
615
616
617
618
619
620
621
622
624private:
625
626
627
628
629
630
631
632
633
634
637
638
639
640
641 bool isModifiedInFrame(const ExplodedNode *CallExitBeginN);
642
644
645
646
647 void findModifyingFrames(const ExplodedNode *const CallExitBeginN);
648
649protected:
651
652
653
654
655
656
657
658
659
660
663 return false;
664 }
665
666
667
668
669
670
671
672
673
674
675
676
677
678
681 return false;
682 }
683
684
685
686
687
688
693
694
695
696
697
698
703
704
705
706
707
708
712
713public:
715
719};
720
721
722
723
724
726 const SubRegion *RegionOfInterest;
730
731
732
733
734 static const unsigned DEREFERENCE_LIMIT = 2;
735
737
738public:
743 MmrMgr(R->getMemRegionManager()),
744 SM(MmrMgr.getContext().getSourceManager()),
745 PP(MmrMgr.getContext().getPrintingPolicy()) {}
746
747 void Profile(llvm::FoldingSetNodeID &ID) const override {
748 static int Tag = 0;
749 ID.AddPointer(&Tag);
750 ID.AddPointer(RegionOfInterest);
751 }
752
753private:
754
755
756 bool wasModifiedBeforeCallExit(const ExplodedNode *CurrN,
757 const ExplodedNode *CallExitBeginN) override;
758
759
760
761
762
763
764
765 const std::optional
767 const MemRegion *R, const RegionVector &Vec = {},
768 int depth = 0);
769
770
771
773 const ObjCMethodCall &Call,
774 const ExplodedNode *N) final;
775
777 const CXXConstructorCall &Call,
778 const ExplodedNode *N) final;
779
781 maybeEmitNoteForParameters(PathSensitiveBugReport &R, const CallEvent &Call,
782 const ExplodedNode *N) final;
783
784
785
786
787
789 maybeEmitNote(PathSensitiveBugReport &R, const CallEvent &Call,
790 const ExplodedNode *N, const RegionVector &FieldChain,
791 const MemRegion *MatchedRegion, StringRef FirstElement,
792 bool FirstIsReferenceType, unsigned IndirectionLevel);
793
794 bool prettyPrintRegionName(const RegionVector &FieldChain,
795 const MemRegion *MatchedRegion,
796 StringRef FirstElement, bool FirstIsReferenceType,
797 unsigned IndirectionLevel,
798 llvm::raw_svector_ostream &os);
799
800 StringRef prettyPrintFirstElement(StringRef FirstElement,
801 bool MoreItemsExpected,
802 int IndirectionLevel,
803 llvm::raw_svector_ostream &os);
804};
805
806}
807}
808
809#endif
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
A builtin binary operation expression such as "x + y" or "x <= y".
Represents a single basic block in a source-level CFG.
A reference to a declared variable, function, enum, etc.
This represents one expression.
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
Represents a struct/union/class.
This class handles loading and caching of source files into memory.
It represents a stack frame of the call stack (based on CallEvent).
Stmt - This represents one statement.
BugReporterVisitors are used to add custom diagnostics along a path.
virtual void Profile(llvm::FoldingSetNodeID &ID) const =0
BugReporterVisitor(BugReporterVisitor &&)
virtual PathDiagnosticPieceRef VisitNode(const ExplodedNode *Succ, BugReporterContext &BRC, PathSensitiveBugReport &BR)=0
Return a diagnostic piece which should be associated with the given node.
BugReporterVisitor & operator=(BugReporterVisitor &&)=delete
BugReporterVisitor(const BugReporterVisitor &)=default
BugReporterVisitor()=default
static PathDiagnosticPieceRef getDefaultEndPath(const BugReporterContext &BRC, const ExplodedNode *N, const PathSensitiveBugReport &BR)
Generates the default final diagnostic piece.
virtual ~BugReporterVisitor()
virtual PathDiagnosticPieceRef getEndPath(BugReporterContext &BRC, const ExplodedNode *N, PathSensitiveBugReport &BR)
Provide custom definition for the final diagnostic piece on the path - the piece, which is displayed ...
BugReporterVisitor & operator=(const BugReporterVisitor &)=delete
virtual void finalizeVisitor(BugReporterContext &BRC, const ExplodedNode *EndPathNode, PathSensitiveBugReport &BR)
Last function called on the visitor, no further calls to VisitNode would follow.
Represents a call to a C++ constructor.
Represents an abstract call to a function or method along a particular path.
Visitor that tries to report interesting diagnostics from conditions.
PathDiagnosticPieceRef VisitTerminator(const Stmt *Term, const ExplodedNode *N, const CFGBlock *SrcBlk, const CFGBlock *DstBlk, PathSensitiveBugReport &R, BugReporterContext &BRC)
bool printValue(const Expr *CondVarExpr, raw_ostream &Out, const ExplodedNode *N, bool TookTrue, bool IsAssuming)
Tries to print the value of the given expression.
PathDiagnosticPieceRef VisitNode(const ExplodedNode *N, BugReporterContext &BRC, PathSensitiveBugReport &BR) override
Return a diagnostic piece which should be associated with the given node.
bool patternMatch(const Expr *Ex, const Expr *ParentEx, raw_ostream &Out, BugReporterContext &BRC, PathSensitiveBugReport &R, const ExplodedNode *N, std::optional< bool > &prunable, bool IsSameFieldName)
static bool isPieceMessageGeneric(const PathDiagnosticPiece *Piece)
PathDiagnosticPieceRef VisitConditionVariable(StringRef LhsString, const Expr *CondVarExpr, BugReporterContext &BRC, PathSensitiveBugReport &R, const ExplodedNode *N, bool TookTrue)
PathDiagnosticPieceRef VisitTrueTest(const Expr *Cond, BugReporterContext &BRC, PathSensitiveBugReport &R, const ExplodedNode *N, bool TookTrue)
static const char * getTag()
Return the tag associated with this visitor.
PathDiagnosticPieceRef VisitNodeImpl(const ExplodedNode *N, BugReporterContext &BRC, PathSensitiveBugReport &BR)
void Profile(llvm::FoldingSetNodeID &ID) const override
Suppress reports that might lead to known false positives.
void finalizeVisitor(BugReporterContext &BRC, const ExplodedNode *N, PathSensitiveBugReport &BR) override
Last function called on the visitor, no further calls to VisitNode would follow.
void Profile(llvm::FoldingSetNodeID &ID) const override
PathDiagnosticPieceRef VisitNode(const ExplodedNode *, BugReporterContext &, PathSensitiveBugReport &) override
Return a diagnostic piece which should be associated with the given node.
MemRegion - The root abstract class for all memory regions.
Prints path notes when a message is sent to a nil receiver.
PathDiagnosticPieceRef VisitNode(const ExplodedNode *N, BugReporterContext &BRC, PathSensitiveBugReport &BR) override
Return a diagnostic piece which should be associated with the given node.
void Profile(llvm::FoldingSetNodeID &ID) const override
static const Expr * getNilReceiver(const Stmt *S, const ExplodedNode *N)
If the statement is a message send expression with nil receiver, returns the receiver expression.
Put a diagnostic on return statement (or on } in its absence) of all inlined functions for which some...
virtual bool wasModifiedBeforeCallExit(const ExplodedNode *CurrN, const ExplodedNode *CallExitBeginN)
virtual PathDiagnosticPieceRef maybeEmitNoteForObjCSelf(PathSensitiveBugReport &R, const ObjCMethodCall &Call, const ExplodedNode *N)=0
Consume the information on the non-modifying stack frame in order to either emit a note or not.
virtual PathDiagnosticPieceRef maybeEmitNoteForCXXThis(PathSensitiveBugReport &R, const CXXConstructorCall &Call, const ExplodedNode *N)=0
Consume the information on the non-modifying stack frame in order to either emit a note or not.
bugreporter::TrackingKind TKind
NoStateChangeFuncVisitor(bugreporter::TrackingKind TKind)
virtual bool wasModifiedInFunction(const ExplodedNode *CallEnterN, const ExplodedNode *CallExitEndN)
PathDiagnosticPieceRef VisitNode(const ExplodedNode *N, BugReporterContext &BR, PathSensitiveBugReport &R) final
Return a diagnostic piece which should be associated with the given node.
virtual PathDiagnosticPieceRef maybeEmitNoteForParameters(PathSensitiveBugReport &R, const CallEvent &Call, const ExplodedNode *N)=0
Consume the information on the non-modifying stack frame in order to either emit a note or not.
Put a diagnostic on return statement of all inlined functions for which the region of interest Region...
void Profile(llvm::FoldingSetNodeID &ID) const override
NoStoreFuncVisitor(const SubRegion *R, bugreporter::TrackingKind TKind=bugreporter::TrackingKind::Thorough)
Represents any expression that calls an Objective-C method.
SVal - This represents a symbolic expression, which can be either an L-value or an R-value.
SubRegion - A region that subsets another larger region.
PathDiagnosticPieceRef VisitNode(const ExplodedNode *Succ, BugReporterContext &BRC, PathSensitiveBugReport &BR) override
Return a diagnostic piece which should be associated with the given node.
static const char * getTag()
Return the tag associated with this visitor.
void Profile(llvm::FoldingSetNodeID &ID) const override
The visitor detects NoteTags and displays the event notes they contain.
void Profile(llvm::FoldingSetNodeID &ID) const override
PathDiagnosticPieceRef VisitNode(const ExplodedNode *N, BugReporterContext &BRC, PathSensitiveBugReport &R) override
Return a diagnostic piece which should be associated with the given node.
void Profile(llvm::FoldingSetNodeID &ID) const override
static const char * getTag()
Return the tag associated with this visitor.
TrackConstraintBRVisitor(DefinedSVal constraint, bool assumption, StringRef Message)
PathDiagnosticPieceRef VisitNode(const ExplodedNode *N, BugReporterContext &BRC, PathSensitiveBugReport &BR) override
Return a diagnostic piece which should be associated with the given node.
When a region containing undefined value or '0' value is passed as an argument in a call,...
PathDiagnosticPieceRef VisitNode(const ExplodedNode *N, BugReporterContext &BRC, PathSensitiveBugReport &BR) override
Return a diagnostic piece which should be associated with the given node.
void Profile(llvm::FoldingSetNodeID &ID) const override
UndefOrNullArgVisitor(const MemRegion *InR)
Handles expressions during the tracking.
virtual Tracker::Result handle(const Expr *E, const ExplodedNode *Original, const ExplodedNode *ExprNode, TrackingOptions Opts)=0
Handle the given expression from the given node.
virtual ~ExpressionHandler()
Tracker & getParentTracker()
\Return the tracker that initiated the process.
ExpressionHandler(Tracker &ParentTracker)
Handles stores during the tracking.
virtual PathDiagnosticPieceRef handle(StoreInfo SI, BugReporterContext &BRC, TrackingOptions Opts)=0
Handle the given store and produce the node.
Tracker & getParentTracker()
StoreHandler(Tracker &ParentTracker)
PathDiagnosticPieceRef constructNote(StoreInfo SI, BugReporterContext &BRC, StringRef NodeText)
A generalized component for tracking expressions, values, and stores.
void addLowPriorityHandler(ExpressionHandlerPtr SH)
Add custom expression handler with the lowest priority.
static TrackerRef create(PathSensitiveBugReport &Report)
PathSensitiveBugReport & getReport()
void addHighPriorityHandler(Args &&... ConstructorArgs)
Add custom expression/store handler with the highest priority.
virtual PathDiagnosticPieceRef handle(StoreInfo SI, BugReporterContext &BRC, TrackingOptions Opts)
Handle the store operation and produce the note.
void addHighPriorityHandler(StoreHandlerPtr SH)
Add custom store handler with the highest priority.
void addHighPriorityHandler(ExpressionHandlerPtr SH)
Add custom expression handler with the highest priority.
void addLowPriorityHandler(Args &&... ConstructorArgs)
Add custom expression/store handler with the lowest priority.
void addLowPriorityHandler(StoreHandlerPtr SH)
Add custom store handler with the lowest priority.
virtual ~Tracker()=default
virtual Result track(const Expr *E, const ExplodedNode *N, TrackingOptions Opts={})
Track expression value back to its point of origin.
Visitor that tracks expressions and values.
Tracker & getParentTracker()
TrackingBugReporterVisitor(TrackerRef ParentTracker)
const Expr * getDerefExpr(const Stmt *S)
Given that expression S represents a pointer that would be dereferenced, try to find a sub-expression...
bool trackExpressionValue(const ExplodedNode *N, const Expr *E, PathSensitiveBugReport &R, TrackingOptions Opts={})
Attempts to add visitors to track expression value back to its point of origin.
void trackStoredValue(SVal V, const MemRegion *R, PathSensitiveBugReport &Report, TrackingOptions Opts={}, const StackFrameContext *Origin=nullptr)
Track how the value got stored into the given region and where it came from.
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...
@ Condition
Specifies that a more moderate tracking should be used for the expression value.
std::shared_ptr< PathDiagnosticPiece > PathDiagnosticPieceRef
The JSON file list parser is used to communicate input to InstallAPI.
@ Other
Other implicit parameter.
Describes how types, statements, expressions, and declarations should be printed.
Describes an event when the value got stored into a memory region.
@ Assignment
The value got stored into the region during assignment: int x; x = 42;.
@ CallArgument
The value got stored into the parameter region as the result of a call.
@ BlockCapture
The value got stored into the region as block capture.
@ Initialization
The value got stored into the region during initialization: int x = 42;.
const Expr * SourceOfTheValue
The expression where the value comes from.
const ExplodedNode * StoreSite
The node where the store happened.
Kind StoreKind
The type of store operation.
SVal Value
Symbolic value that is being stored.
const MemRegion * Dest
Memory regions involved in the store operation.
Describes a tracking result with the most basic information of what was actually done (or not done).
bool FoundSomethingToTrack
Usually it means that the tracker added visitors.
void combineWith(const Result &Other)
Combines the current result with the given result.
bool WasInterrupted
Signifies that the tracking was interrupted at some point.
Defines a set of options altering tracking behavior.
bool EnableNullFPSuppression
Specifies whether we should employ false positive suppression (inlined defensive checks,...
TrackingKind Kind
Specifies the kind of tracking.