clang: lib/StaticAnalyzer/Core/CheckerManager.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
26#include "llvm/ADT/SmallVector.h"
27#include "llvm/Support/Casting.h"
28#include "llvm/Support/ErrorHandling.h"
29#include "llvm/Support/FormatVariadic.h"
30#include
31#include
32#include
33
34using namespace clang;
35using namespace ento;
36
38 const auto IfAnyAreNonEmpty = [](const auto &... Callbacks) -> bool {
39 return (!Callbacks.empty() || ...);
40 };
41 return IfAnyAreNonEmpty(
42 StmtCheckers, PreObjCMessageCheckers, ObjCMessageNilCheckers,
43 PostObjCMessageCheckers, PreCallCheckers, PostCallCheckers,
44 LocationCheckers, BindCheckers, EndAnalysisCheckers,
45 BeginFunctionCheckers, EndFunctionCheckers, BranchConditionCheckers,
46 NewAllocatorCheckers, LiveSymbolsCheckers, DeadSymbolsCheckers,
47 RegionChangesCheckers, PointerEscapeCheckers, EvalAssumeCheckers,
48 EvalCallCheckers, EndOfTranslationUnitCheckers);
49}
50
53 StringRef ExpectedValueDesc) const {
54
56 << (llvm::Twine() + C->getTagDescription() + ":" + OptionName).str()
57 << ExpectedValueDesc;
58}
59
60
61
62
63
66 assert(D);
67
68 unsigned DeclKind = D->getKind();
69 auto [CCI, Inserted] = CachedDeclCheckersMap.try_emplace(DeclKind);
71 if (Inserted) {
72
73 for (const auto &info : DeclCheckers)
74 if (info.IsForDeclFn(D))
75 checkers->push_back(info.CheckFn);
76 }
77
78 assert(checkers);
79 for (const auto &checker : *checkers)
80 checker(D, mgr, BR);
81}
82
86
87 for (const auto &BodyChecker : BodyCheckers)
88 BodyChecker(D, mgr, BR);
89}
90
91
92
93
94
95template <typename CHECK_CTX>
101 return;
102
103 typename CHECK_CTX::CheckersTy::const_iterator
104 I = checkCtx.checkers_begin(), E = checkCtx.checkers_end();
105 if (I == E) {
107 return;
108 }
109
112
113 for (; I != E; ++I) {
115 if (I+1 == E)
116 CurrSet = &Dst;
117 else {
118 CurrSet = (PrevSet == &Tmp1) ? &Tmp2 : &Tmp1;
119 CurrSet->clear();
120 }
121
122 NodeBuilder B(*PrevSet, *CurrSet, BldrCtx);
123 for (const auto &NI : *PrevSet)
124 checkCtx.runChecker(*I, B, NI);
125
126
127 if (CurrSet->empty())
128 return;
129
130
131 PrevSet = CurrSet;
132 }
133}
134
135namespace {
136
137 struct CheckStmtContext {
139
140 bool IsPreVisit;
141 const CheckersTy &Checkers;
142 const Stmt *S;
144 bool WasInlined;
145
146 CheckStmtContext(bool isPreVisit, const CheckersTy &checkers,
148 : IsPreVisit(isPreVisit), Checkers(checkers), S(s), Eng(eng),
149 WasInlined(wasInlined) {}
150
151 CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); }
152 CheckersTy::const_iterator checkers_end() { return Checkers.end(); }
153
156
162 checkFn(S, C);
163 }
164 };
165
166}
167
168
172 const Stmt *S,
174 bool WasInlined) {
175 CheckStmtContext C(isPreVisit, getCachedStmtCheckersFor(S, isPreVisit),
176 S, Eng, WasInlined);
178}
179
180namespace {
181
182 struct CheckObjCMessageContext {
183 using CheckersTy = std::vectorCheckerManager::CheckObjCMessageFunc;
184
186 bool WasInlined;
187 const CheckersTy &Checkers;
190
192 const CheckersTy &checkers,
194 bool wasInlined)
195 : Kind(visitKind), WasInlined(wasInlined), Checkers(checkers), Msg(msg),
196 Eng(eng) {}
197
198 CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); }
199 CheckersTy::const_iterator checkers_end() { return Checkers.end(); }
200
203 bool IsPreVisit;
204
205 switch (Kind) {
206 case ObjCMessageVisitKind::Pre:
207 IsPreVisit = true;
208 break;
209 case ObjCMessageVisitKind::MessageNil:
210 case ObjCMessageVisitKind::Post:
211 IsPreVisit = false;
212 break;
213 }
214
217
219 }
220 };
221
222}
223
224
230 bool WasInlined) {
231 const auto &checkers = getObjCMessageCheckers(visitKind);
232 CheckObjCMessageContext C(visitKind, checkers, msg, Eng, WasInlined);
234}
235
236const std::vectorCheckerManager::CheckObjCMessageFunc &
238 switch (Kind) {
240 return PreObjCMessageCheckers;
241 break;
243 return PostObjCMessageCheckers;
245 return ObjCMessageNilCheckers;
246 }
247 llvm_unreachable("Unknown Kind");
248}
249
250namespace {
251
252
253
254 struct CheckCallContext {
255 using CheckersTy = std::vectorCheckerManager::CheckCallFunc;
256
257 bool IsPreVisit, WasInlined;
258 const CheckersTy &Checkers;
261
262 CheckCallContext(bool isPreVisit, const CheckersTy &checkers,
264 bool wasInlined)
265 : IsPreVisit(isPreVisit), WasInlined(wasInlined), Checkers(checkers),
266 Call(call), Eng(eng) {}
267
268 CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); }
269 CheckersTy::const_iterator checkers_end() { return Checkers.end(); }
270
273 const ProgramPoint &L = Call.getProgramPoint(IsPreVisit,checkFn.Checker);
275
276 checkFn(*Call.cloneWithState(Pred->getState()), C);
277 }
278 };
279
280}
281
282
288 bool WasInlined) {
289 CheckCallContext C(isPreVisit,
290 isPreVisit ? PreCallCheckers
291 : PostCallCheckers,
292 Call, Eng, WasInlined);
294}
295
296namespace {
297
298 struct CheckLocationContext {
299 using CheckersTy = std::vectorCheckerManager::CheckLocationFunc;
300
301 const CheckersTy &Checkers;
303 bool IsLoad;
304 const Stmt *NodeEx;
305 const Stmt *BoundEx;
307
308 CheckLocationContext(const CheckersTy &checkers,
309 SVal loc, bool isLoad, const Stmt *NodeEx,
310 const Stmt *BoundEx,
312 : Checkers(checkers), Loc(loc), IsLoad(isLoad), NodeEx(NodeEx),
313 BoundEx(BoundEx), Eng(eng) {}
314
315 CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); }
316 CheckersTy::const_iterator checkers_end() { return Checkers.end(); }
317
325 checkFn.Checker);
327 checkFn(Loc, IsLoad, BoundEx, C);
328 }
329 };
330
331}
332
333
334
337 SVal location, bool isLoad,
338 const Stmt *NodeEx,
339 const Stmt *BoundEx,
341 CheckLocationContext C(LocationCheckers, location, isLoad, NodeEx,
342 BoundEx, Eng);
344}
345
346namespace {
347
348 struct CheckBindContext {
349 using CheckersTy = std::vectorCheckerManager::CheckBindFunc;
350
351 const CheckersTy &Checkers;
354 const Stmt *S;
357
358 CheckBindContext(const CheckersTy &checkers,
361 : Checkers(checkers), Loc(loc), Val(val), S(s), Eng(eng), PP(pp) {}
362
363 CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); }
364 CheckersTy::const_iterator checkers_end() { return Checkers.end(); }
365
370
372 }
373 };
374
375}
376
377
383 CheckBindContext C(BindCheckers, location, val, S, Eng, PP);
385}
386
390 for (const auto &EndAnalysisChecker : EndAnalysisCheckers)
391 EndAnalysisChecker(G, BR, Eng);
392}
393
394namespace {
395
396struct CheckBeginFunctionContext {
397 using CheckersTy = std::vectorCheckerManager::CheckBeginFunctionFunc;
398
399 const CheckersTy &Checkers;
402
403 CheckBeginFunctionContext(const CheckersTy &Checkers, ExprEngine &Eng,
405 : Checkers(Checkers), Eng(Eng), PP(PP) {}
406
407 CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); }
408 CheckersTy::const_iterator checkers_end() { return Checkers.end(); }
409
414
415 checkFn(C);
416 }
417};
418
419}
420
427 CheckBeginFunctionContext C(BeginFunctionCheckers, Eng, L);
429}
430
431
432
433
439
440
441
443 for (const auto &checkFn : EndFunctionCheckers) {
447 checkFn(RS, C);
448 }
449}
450
451namespace {
452
453 struct CheckBranchConditionContext {
454 using CheckersTy = std::vectorCheckerManager::CheckBranchConditionFunc;
455
456 const CheckersTy &Checkers;
459
460 CheckBranchConditionContext(const CheckersTy &checkers,
462 : Checkers(checkers), Condition(Cond), Eng(eng) {}
463
464 CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); }
465 CheckersTy::const_iterator checkers_end() { return Checkers.end(); }
466
470 checkFn.Checker);
473 }
474 };
475
476}
477
478
485 CheckBranchConditionContext C(BranchConditionCheckers, Condition, Eng);
487}
488
489namespace {
490
491 struct CheckNewAllocatorContext {
492 using CheckersTy = std::vectorCheckerManager::CheckNewAllocatorFunc;
493
494 const CheckersTy &Checkers;
496 bool WasInlined;
498
499 CheckNewAllocatorContext(const CheckersTy &Checkers,
502 : Checkers(Checkers), Call(Call), WasInlined(WasInlined), Eng(Eng) {}
503
504 CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); }
505 CheckersTy::const_iterator checkers_end() { return Checkers.end(); }
506
512 checkFn(cast(*Call.cloneWithState(Pred->getState())),
513 C);
514 }
515 };
516
517}
518
523 bool WasInlined) {
526 CheckNewAllocatorContext C(NewAllocatorCheckers, Call, WasInlined, Eng);
528}
529
530
533 for (const auto &LiveSymbolsChecker : LiveSymbolsCheckers)
534 LiveSymbolsChecker(state, SymReaper);
535}
536
537namespace {
538
539 struct CheckDeadSymbolsContext {
540 using CheckersTy = std::vectorCheckerManager::CheckDeadSymbolsFunc;
541
542 const CheckersTy &Checkers;
544 const Stmt *S;
547
548 CheckDeadSymbolsContext(const CheckersTy &checkers, SymbolReaper &sr,
551 : Checkers(checkers), SR(sr), S(s), Eng(eng), ProgarmPointKind(K) {}
552
553 CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); }
554 CheckersTy::const_iterator checkers_end() { return Checkers.end(); }
555
561
562
563
564
565 checkFn(SR, C);
566 }
567 };
568
569}
570
571
575 const Stmt *S,
578 CheckDeadSymbolsContext C(DeadSymbolsCheckers, SymReaper, S, Eng, K);
580}
581
582
590 for (const auto &RegionChangesChecker : RegionChangesCheckers) {
591
592
593 if (!state)
594 return nullptr;
595 state = RegionChangesChecker(state, invalidated, ExplicitRegions, Regions,
597 }
598 return state;
599}
600
601
608 assert((Call != nullptr ||
611 "Call must not be NULL when escaping on call");
612 for (const auto &PointerEscapeChecker : PointerEscapeCheckers) {
613
614
615 if (!State)
616 return nullptr;
617 State = PointerEscapeChecker(State, Escaped, Call, Kind, ETraits);
618 }
619 return State;
620}
621
622
625 SVal Cond, bool Assumption) {
626 for (const auto &EvalAssumeChecker : EvalAssumeCheckers) {
627
628
629 if (!state)
630 return nullptr;
631 state = EvalAssumeChecker(state, Cond, Assumption);
632 }
633 return state;
634}
635
636
637
643 for (auto *const Pred : Src) {
644 std::optional evaluatorChecker;
645
648
649
650 for (const auto &EvalCallChecker : EvalCallCheckers) {
651
652
655 Pred->getLocationContext(), EvalCallChecker.Checker);
656 bool evaluated = false;
657 {
658
659
661 evaluated = EvalCallChecker(Call, C);
662 }
663#ifndef NDEBUG
664 if (evaluated && evaluatorChecker) {
666 std::string Buf;
667 llvm::raw_string_ostream OS(Buf);
669 return Buf;
670 };
671 std::string AssertionMessage = llvm::formatv(
672 "The '{0}' call has been already evaluated by the {1} checker, "
673 "while the {2} checker also tried to evaluate the same call. At "
674 "most one checker supposed to evaluate a call.",
676 EvalCallChecker.Checker->getCheckerName());
677 llvm_unreachable(AssertionMessage.c_str());
678 }
679#endif
680 if (evaluated) {
681 evaluatorChecker = EvalCallChecker.Checker->getCheckerName();
682 Dst.insert(checkDst);
683#ifdef NDEBUG
684 break;
685#endif
686 }
687 }
688
689
690 if (!evaluatorChecker) {
693 }
694 }
695}
696
697
702 for (const auto &EndOfTranslationUnitChecker : EndOfTranslationUnitCheckers)
703 EndOfTranslationUnitChecker(TU, mgr, BR);
704}
705
708 const char *NL,
709 unsigned int Space,
710 bool IsDot) const {
711 Indent(Out, Space, IsDot) << "\"checker_messages\": ";
712
713
715 llvm::raw_svector_ostream TempOut(TempBuf);
716 unsigned int InnerSpace = Space + 2;
717
718
720 llvm::raw_svector_ostream NLOut(NewLine);
721 NLOut << "\", " << NL;
722 Indent(NLOut, InnerSpace, IsDot) << "\"";
723
724 ++Space;
725 bool HasMessage = false;
726
727
728 const void *LastCT = nullptr;
729 for (const auto &CT : CheckerTags) {
730
731 CT.second->printState(TempOut, State, NewLine.c_str(), "");
732
733 if (TempBuf.empty())
734 continue;
735
736 if (!HasMessage) {
737 Out << '[' << NL;
738 HasMessage = true;
739 }
740
741 LastCT = &CT;
742 TempBuf.clear();
743 }
744
745 for (const auto &CT : CheckerTags) {
746
747 CT.second->printState(TempOut, State, NewLine.c_str(), "");
748
749 if (TempBuf.empty())
750 continue;
751
752 Indent(Out, Space, IsDot)
753 << "{ \"checker\": \"" << CT.second->getCheckerName().getName()
754 << "\", \"messages\": [" << NL;
755 Indent(Out, InnerSpace, IsDot)
756 << '\"' << TempBuf.str().trim() << '\"' << NL;
757 Indent(Out, Space, IsDot) << "]}";
758
759 if (&CT != LastCT)
760 Out << ',';
761 Out << NL;
762
763 TempBuf.clear();
764 }
765
766
767 if (HasMessage)
768 Indent(Out, --Space, IsDot) << "]";
769 else
770 Out << "null";
771
772 Out << NL;
773}
774
775
776
777
778
781 DeclCheckerInfo info = { checkfn, isForDeclFn };
782 DeclCheckers.push_back(info);
783}
784
786 BodyCheckers.push_back(checkfn);
787}
788
789
790
791
792
795 StmtCheckerInfo info = { checkfn, isForStmtFn, true };
796 StmtCheckers.push_back(info);
797}
798
801 StmtCheckerInfo info = { checkfn, isForStmtFn, false };
802 StmtCheckers.push_back(info);
803}
804
806 PreObjCMessageCheckers.push_back(checkfn);
807}
808
810 ObjCMessageNilCheckers.push_back(checkfn);
811}
812
814 PostObjCMessageCheckers.push_back(checkfn);
815}
816
818 PreCallCheckers.push_back(checkfn);
819}
821 PostCallCheckers.push_back(checkfn);
822}
823
825 LocationCheckers.push_back(checkfn);
826}
827
829 BindCheckers.push_back(checkfn);
830}
831
833 EndAnalysisCheckers.push_back(checkfn);
834}
835
837 BeginFunctionCheckers.push_back(checkfn);
838}
839
841 EndFunctionCheckers.push_back(checkfn);
842}
843
846 BranchConditionCheckers.push_back(checkfn);
847}
848
850 NewAllocatorCheckers.push_back(checkfn);
851}
852
854 LiveSymbolsCheckers.push_back(checkfn);
855}
856
858 DeadSymbolsCheckers.push_back(checkfn);
859}
860
862 RegionChangesCheckers.push_back(checkfn);
863}
864
866 PointerEscapeCheckers.push_back(checkfn);
867}
868
871 PointerEscapeCheckers.push_back(checkfn);
872}
873
875 EvalAssumeCheckers.push_back(checkfn);
876}
877
879 EvalCallCheckers.push_back(checkfn);
880}
881
884 EndOfTranslationUnitCheckers.push_back(checkfn);
885}
886
887
888
889
890
892CheckerManager::getCachedStmtCheckersFor(const Stmt *S, bool isPreVisit) {
893 assert(S);
894
895 unsigned Key = (S->getStmtClass() << 1) | unsigned(isPreVisit);
896 auto [CCI, Inserted] = CachedStmtCheckersMap.try_emplace(Key);
897 CachedStmtCheckers &Checkers = CCI->second;
898 if (Inserted) {
899
900 for (const auto &Info : StmtCheckers)
901 if (Info.IsPreVisit == isPreVisit && Info.IsForStmtFn(S))
902 Checkers.push_back(Info.CheckFn);
903 }
904 return Checkers;
905}
enum clang::sema::@1727::IndirectLocalPathEntry::EntryKind Kind
static void expandGraphWithCheckers(CHECK_CTX checkCtx, ExplodedNodeSet &Dst, const ExplodedNodeSet &Src)
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
__device__ __2f16 float __ockl_bool s
Decl - This represents one declaration (or definition), e.g.
virtual bool hasBody() const
Returns true if this Decl represents a declaration for a body of code, such as a function or method d...
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
It wraps the AnalysisDeclContext to represent both the call stack with the help of StackFrameContext ...
static ProgramPoint getProgramPoint(const Stmt *S, ProgramPoint::Kind K, const LocationContext *LC, const ProgramPointTag *tag)
ProgramPoint withTag(const ProgramPointTag *tag) const
Create a new ProgramPoint object that is the same as the original except for using the specified tag ...
ReturnStmt - This represents a return, optionally of an expression: return; return 4;.
Stmt - This represents one statement.
The top declaration context.
BugReporter is a utility class for generating PathDiagnostics for analysis.
Represents the memory allocation call in a C++ new-expression.
Represents an abstract call to a function or method along a particular path.
CallEventRef< T > cloneWithState(ProgramStateRef NewState) const
Returns a copy of this CallEvent, but using the given state.
ProgramPoint getProgramPoint(bool IsPreVisit=false, const ProgramPointTag *Tag=nullptr) const
Returns an appropriate ProgramPoint for this call.
void _registerForLiveSymbols(CheckLiveSymbolsFunc checkfn)
void _registerForEndOfTranslationUnit(CheckEndOfTranslationUnit checkfn)
void _registerForBeginFunction(CheckBeginFunctionFunc checkfn)
void runCheckersForBind(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, SVal location, SVal val, const Stmt *S, ExprEngine &Eng, const ProgramPoint &PP)
Run checkers for binding of a value to a location.
void _registerForNewAllocator(CheckNewAllocatorFunc checkfn)
void _registerForPreCall(CheckCallFunc checkfn)
void _registerForObjCMessageNil(CheckObjCMessageFunc checkfn)
bool(*)(const Decl *D) HandlesDeclFunc
void runCheckersForObjCMessage(ObjCMessageVisitKind visitKind, ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const ObjCMethodCall &msg, ExprEngine &Eng, bool wasInlined=false)
Run checkers for visiting obj-c messages.
void runCheckersOnASTDecl(const Decl *D, AnalysisManager &mgr, BugReporter &BR)
Run checkers handling Decls.
void reportInvalidCheckerOptionValue(const CheckerBase *C, StringRef OptionName, StringRef ExpectedValueDesc) const
Emits an error through a DiagnosticsEngine about an invalid user supplied checker option value.
void _registerForDecl(CheckDeclFunc checkfn, HandlesDeclFunc isForDeclFn)
void _registerForPreObjCMessage(CheckObjCMessageFunc checkfn)
void runCheckersOnEndOfTranslationUnit(const TranslationUnitDecl *TU, AnalysisManager &mgr, BugReporter &BR)
Run checkers for the entire Translation Unit.
void runCheckersForEndFunction(NodeBuilderContext &BC, ExplodedNodeSet &Dst, ExplodedNode *Pred, ExprEngine &Eng, const ReturnStmt *RS)
Run checkers on end of function.
void _registerForEvalAssume(EvalAssumeFunc checkfn)
void _registerForEndAnalysis(CheckEndAnalysisFunc checkfn)
void _registerForBody(CheckDeclFunc checkfn)
DiagnosticsEngine & getDiagnostics() const
void runCheckersForLocation(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, SVal location, bool isLoad, const Stmt *NodeEx, const Stmt *BoundEx, ExprEngine &Eng)
Run checkers for load/store of a location.
void runCheckersForEndAnalysis(ExplodedGraph &G, BugReporter &BR, ExprEngine &Eng)
Run checkers for end of analysis.
void runCheckersForPrintStateJson(raw_ostream &Out, ProgramStateRef State, const char *NL="\n", unsigned int Space=0, bool IsDot=false) const
Run checkers for debug-printing a ProgramState.
void _registerForDeadSymbols(CheckDeadSymbolsFunc checkfn)
void runCheckersForDeadSymbols(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, SymbolReaper &SymReaper, const Stmt *S, ExprEngine &Eng, ProgramPoint::Kind K)
Run checkers for dead symbols.
ProgramStateRef runCheckersForRegionChanges(ProgramStateRef state, const InvalidatedSymbols *invalidated, ArrayRef< const MemRegion * > ExplicitRegions, ArrayRef< const MemRegion * > Regions, const LocationContext *LCtx, const CallEvent *Call)
Run checkers for region changes.
void _registerForPostObjCMessage(CheckObjCMessageFunc checkfn)
void _registerForRegionChanges(CheckRegionChangesFunc checkfn)
bool hasPathSensitiveCheckers() const
void _registerForBind(CheckBindFunc checkfn)
void runCheckersForLiveSymbols(ProgramStateRef state, SymbolReaper &SymReaper)
Run checkers for live symbols.
void _registerForPointerEscape(CheckPointerEscapeFunc checkfn)
void _registerForPreStmt(CheckStmtFunc checkfn, HandlesStmtFunc isForStmtFn)
void runCheckersForEvalCall(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const CallEvent &CE, ExprEngine &Eng, const EvalCallOptions &CallOpts)
Run checkers for evaluating a call.
void _registerForPostStmt(CheckStmtFunc checkfn, HandlesStmtFunc isForStmtFn)
void runCheckersForBeginFunction(ExplodedNodeSet &Dst, const BlockEdge &L, ExplodedNode *Pred, ExprEngine &Eng)
Run checkers on beginning of function.
void runCheckersForNewAllocator(const CXXAllocatorCall &Call, ExplodedNodeSet &Dst, ExplodedNode *Pred, ExprEngine &Eng, bool wasInlined=false)
Run checkers between C++ operator new and constructor calls.
void _registerForBranchCondition(CheckBranchConditionFunc checkfn)
void runCheckersForStmt(bool isPreVisit, ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const Stmt *S, ExprEngine &Eng, bool wasInlined=false)
Run checkers for visiting Stmts.
void _registerForEvalCall(EvalCallFunc checkfn)
void _registerForEndFunction(CheckEndFunctionFunc checkfn)
void runCheckersForBranchCondition(const Stmt *condition, ExplodedNodeSet &Dst, ExplodedNode *Pred, ExprEngine &Eng)
Run checkers for branch condition.
void _registerForLocation(CheckLocationFunc checkfn)
ProgramStateRef runCheckersForPointerEscape(ProgramStateRef State, const InvalidatedSymbols &Escaped, const CallEvent *Call, PointerEscapeKind Kind, RegionAndSymbolInvalidationTraits *ITraits)
Run checkers when pointers escape.
void _registerForConstPointerEscape(CheckPointerEscapeFunc checkfn)
void runCheckersForCallEvent(bool isPreVisit, ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const CallEvent &Call, ExprEngine &Eng, bool wasInlined=false)
Run checkers for visiting obj-c messages.
bool(*)(const Stmt *D) HandlesStmtFunc
void _registerForPostCall(CheckCallFunc checkfn)
void runCheckersOnASTBody(const Decl *D, AnalysisManager &mgr, BugReporter &BR)
Run checkers handling Decls containing a Stmt body.
ProgramStateRef runCheckersForEvalAssume(ProgramStateRef state, SVal Cond, bool Assumption)
Run checkers for handling assumptions on symbolic values.
void insert(const ExplodedNodeSet &S)
const ProgramStateRef & getState() const
const LocationContext * getLocationContext() const
void defaultEvalCall(NodeBuilder &B, ExplodedNode *Pred, const CallEvent &Call, const EvalCallOptions &CallOpts={})
Default implementation of call evaluation.
const NodeBuilderContext & getBuilderContext()
This is the simplest builder which generates nodes in the ExplodedGraph.
Represents any expression that calls an Objective-C method.
Information about invalidation for a particular region/symbol.
SVal - This represents a symbolic expression, which can be either an L-value or an R-value.
A class responsible for cleaning up unused symbols.
PointerEscapeKind
Describes the different reasons a pointer escapes during analysis.
@ PSK_DirectEscapeOnCall
The pointer has been passed to a function call directly.
@ PSK_IndirectEscapeOnCall
The pointer has been passed to a function indirectly.
@ OS
Indicates that the tracking object is a descendant of a referenced-counted OSObject,...
llvm::DenseSet< SymbolRef > InvalidatedSymbols
The JSON file list parser is used to communicate input to InstallAPI.
Hints for figuring out of a call should be inlined during evalCall().