;
38 const autoIfAnyAreNonEmpty = [](
const auto&... Callbacks) ->
bool{
39 return(!Callbacks.empty() || ...);
41 returnIfAnyAreNonEmpty(
42StmtCheckers, PreObjCMessageCheckers, ObjCMessageNilCheckers,
43PostObjCMessageCheckers, PreCallCheckers, PostCallCheckers,
44LocationCheckers, BindCheckers, EndAnalysisCheckers,
45BeginFunctionCheckers, EndFunctionCheckers, BranchConditionCheckers,
46NewAllocatorCheckers, LiveSymbolsCheckers, DeadSymbolsCheckers,
47RegionChangesCheckers, PointerEscapeCheckers, EvalAssumeCheckers,
48EvalCallCheckers, EndOfTranslationUnitCheckers);
53StringRef ExpectedValueDesc)
const{
56<< (llvm::Twine() +
C->getTagDescription() +
":"+ OptionName).str()
69 auto[CCI, Inserted] = CachedDeclCheckersMap.try_emplace(DeclKind);
73 for(
const auto&info : DeclCheckers)
74 if(info.IsForDeclFn(
D))
75checkers->push_back(info.CheckFn);
79 for(
const auto&checker : *checkers)
80checker(
D, mgr, BR);
87 for(
const auto&BodyChecker : BodyCheckers)
88BodyChecker(
D, mgr, BR);
95template<
typenameCHECK_CTX>
103 typenameCHECK_CTX::CheckersTy::const_iterator
104I = checkCtx.checkers_begin(),
E= checkCtx.checkers_end();
113 for(; I !=
E; ++I) {
118CurrSet = (PrevSet == &Tmp1) ? &Tmp2 : &Tmp1;
123 for(
const auto&NI : *PrevSet)
124checkCtx.runChecker(*I, B, NI);
127 if(CurrSet->
empty())
137 structCheckStmtContext {
141 constCheckersTy &Checkers;
146CheckStmtContext(
boolisPreVisit,
constCheckersTy &checkers,
148: IsPreVisit(isPreVisit), Checkers(checkers), S(
s), Eng(eng),
149WasInlined(wasInlined) {}
151CheckersTy::const_iterator checkers_begin() {
returnCheckers.begin(); }
152CheckersTy::const_iterator checkers_end() {
returnCheckers.end(); }
175CheckStmtContext
C(isPreVisit, getCachedStmtCheckersFor(S, isPreVisit),
182 structCheckObjCMessageContext {
183 usingCheckersTy = std::vector<CheckerManager::CheckObjCMessageFunc>;
187 constCheckersTy &Checkers;
192 constCheckersTy &checkers,
195:
Kind(visitKind), WasInlined(wasInlined), Checkers(checkers), Msg(msg),
198CheckersTy::const_iterator checkers_begin() {
returnCheckers.begin(); }
199CheckersTy::const_iterator checkers_end() {
returnCheckers.end(); }
206 caseObjCMessageVisitKind::Pre:
209 caseObjCMessageVisitKind::MessageNil:
210 caseObjCMessageVisitKind::Post:
231 const auto&checkers = getObjCMessageCheckers(visitKind);
232CheckObjCMessageContext
C(visitKind, checkers, msg, Eng, WasInlined);
236conststd::vector<CheckerManager::CheckObjCMessageFunc> &
240 returnPreObjCMessageCheckers;
243 returnPostObjCMessageCheckers;
245 returnObjCMessageNilCheckers;
247llvm_unreachable(
"Unknown Kind");
254 structCheckCallContext {
255 usingCheckersTy = std::vector<CheckerManager::CheckCallFunc>;
257 boolIsPreVisit, WasInlined;
258 constCheckersTy &Checkers;
262CheckCallContext(
boolisPreVisit,
constCheckersTy &checkers,
265: IsPreVisit(isPreVisit), WasInlined(wasInlined), Checkers(checkers),
266 Call(call), Eng(eng) {}
268CheckersTy::const_iterator checkers_begin() {
returnCheckers.begin(); }
269CheckersTy::const_iterator checkers_end() {
returnCheckers.end(); }
289CheckCallContext
C(isPreVisit,
290isPreVisit ? PreCallCheckers
292 Call, Eng, WasInlined);
298 structCheckLocationContext {
299 usingCheckersTy = std::vector<CheckerManager::CheckLocationFunc>;
301 constCheckersTy &Checkers;
308CheckLocationContext(
constCheckersTy &checkers,
309 SValloc,
boolisLoad,
const Stmt*NodeEx,
312: Checkers(checkers),
Loc(loc), IsLoad(isLoad), NodeEx(NodeEx),
313BoundEx(BoundEx), Eng(eng) {}
315CheckersTy::const_iterator checkers_begin() {
returnCheckers.begin(); }
316CheckersTy::const_iterator checkers_end() {
returnCheckers.end(); }
327checkFn(
Loc, IsLoad, BoundEx,
C);
337 SVallocation,
boolisLoad,
341CheckLocationContext
C(LocationCheckers, location, isLoad, NodeEx,
348 structCheckBindContext {
349 usingCheckersTy = std::vector<CheckerManager::CheckBindFunc>;
351 constCheckersTy &Checkers;
358CheckBindContext(
constCheckersTy &checkers,
361: Checkers(checkers),
Loc(loc), Val(val), S(
s), Eng(eng), PP(pp) {}
363CheckersTy::const_iterator checkers_begin() {
returnCheckers.begin(); }
364CheckersTy::const_iterator checkers_end() {
returnCheckers.end(); }
371checkFn(
Loc, Val, S,
C);
383CheckBindContext
C(BindCheckers, location, val, S, Eng, PP);
390 for(
const auto&EndAnalysisChecker : EndAnalysisCheckers)
391EndAnalysisChecker(G, BR, Eng);
396structCheckBeginFunctionContext {
397 usingCheckersTy = std::vector<CheckerManager::CheckBeginFunctionFunc>;
399 constCheckersTy &Checkers;
403CheckBeginFunctionContext(
constCheckersTy &Checkers,
ExprEngine&Eng,
405: Checkers(Checkers), Eng(Eng), PP(PP) {}
407CheckersTy::const_iterator checkers_begin() {
returnCheckers.begin(); }
408CheckersTy::const_iterator checkers_end() {
returnCheckers.end(); }
427CheckBeginFunctionContext
C(BeginFunctionCheckers, Eng, L);
443 for(
const auto&checkFn : EndFunctionCheckers) {
453 structCheckBranchConditionContext {
454 usingCheckersTy = std::vector<CheckerManager::CheckBranchConditionFunc>;
456 constCheckersTy &Checkers;
460CheckBranchConditionContext(
constCheckersTy &checkers,
462: Checkers(checkers),
Condition(Cond), Eng(eng) {}
464CheckersTy::const_iterator checkers_begin() {
returnCheckers.begin(); }
465CheckersTy::const_iterator checkers_end() {
returnCheckers.end(); }
485CheckBranchConditionContext
C(BranchConditionCheckers,
Condition, Eng);
491 structCheckNewAllocatorContext {
492 usingCheckersTy = std::vector<CheckerManager::CheckNewAllocatorFunc>;
494 constCheckersTy &Checkers;
499CheckNewAllocatorContext(
constCheckersTy &Checkers,
502: Checkers(Checkers),
Call(
Call), WasInlined(WasInlined), Eng(Eng) {}
504CheckersTy::const_iterator checkers_begin() {
returnCheckers.begin(); }
505CheckersTy::const_iterator checkers_end() {
returnCheckers.end(); }
512checkFn(cast<CXXAllocatorCall>(*
Call.cloneWithState(Pred->
getState())),
526CheckNewAllocatorContext
C(NewAllocatorCheckers,
Call, WasInlined, Eng);
533 for(
const auto&LiveSymbolsChecker : LiveSymbolsCheckers)
534LiveSymbolsChecker(state, SymReaper);
539 structCheckDeadSymbolsContext {
540 usingCheckersTy = std::vector<CheckerManager::CheckDeadSymbolsFunc>;
542 constCheckersTy &Checkers;
548CheckDeadSymbolsContext(
constCheckersTy &checkers,
SymbolReaper&sr,
551: Checkers(checkers), SR(sr), S(
s), Eng(eng), ProgarmPointKind(K) {}
553CheckersTy::const_iterator checkers_begin() {
returnCheckers.begin(); }
554CheckersTy::const_iterator checkers_end() {
returnCheckers.end(); }
578CheckDeadSymbolsContext
C(DeadSymbolsCheckers, SymReaper, S, Eng, K);
590 for(
const auto&RegionChangesChecker : RegionChangesCheckers) {
595state = RegionChangesChecker(state, invalidated, ExplicitRegions, Regions,
608assert((
Call!=
nullptr||
611 "Call must not be NULL when escaping on call");
612 for(
const auto&PointerEscapeChecker : PointerEscapeCheckers) {
617State = PointerEscapeChecker(State, Escaped,
Call, Kind, ETraits);
625 SValCond,
boolAssumption) {
626 for(
const auto&EvalAssumeChecker : EvalAssumeCheckers) {
631state = EvalAssumeChecker(state, Cond, Assumption);
643 for(
auto*
constPred : Src) {
644std::optional<CheckerNameRef> evaluatorChecker;
650 for(
const auto&EvalCallChecker : EvalCallCheckers) {
655Pred->getLocationContext(), EvalCallChecker.Checker);
656 boolevaluated =
false;
661evaluated = EvalCallChecker(
Call,
C);
664 if(evaluated && evaluatorChecker) {
667llvm::raw_string_ostream
OS(Buf);
671std::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.",
676EvalCallChecker.Checker->getCheckerName());
677llvm_unreachable(AssertionMessage.c_str());
681evaluatorChecker = EvalCallChecker.Checker->getCheckerName();
690 if(!evaluatorChecker) {
702 for(
const auto&EndOfTranslationUnitChecker : EndOfTranslationUnitCheckers)
703EndOfTranslationUnitChecker(TU, mgr, BR);
711Indent(Out, Space, IsDot) <<
"\"checker_messages\": ";
715llvm::raw_svector_ostream TempOut(TempBuf);
716 unsigned intInnerSpace = Space + 2;
720llvm::raw_svector_ostream NLOut(
NewLine);
721NLOut <<
"\", "<< NL;
722Indent(NLOut, InnerSpace, IsDot) <<
"\"";
725 boolHasMessage =
false;
728 const void*LastCT =
nullptr;
729 for(
const auto&CT : CheckerTags) {
731CT.second->printState(TempOut, State,
NewLine.c_str(),
"");
745 for(
const auto&CT : CheckerTags) {
747CT.second->printState(TempOut, State,
NewLine.c_str(),
"");
752Indent(Out, Space, IsDot)
753<<
"{ \"checker\": \""<< CT.second->getCheckerName().getName()
754<<
"\", \"messages\": ["<< NL;
755Indent(Out, InnerSpace, IsDot)
756<<
'\"'<< TempBuf.str().trim() <<
'\"'<< NL;
757Indent(Out, Space, IsDot) <<
"]}";
768Indent(Out, --Space, IsDot) <<
"]";
781DeclCheckerInfo info = { checkfn, isForDeclFn };
782DeclCheckers.push_back(info);
786BodyCheckers.push_back(checkfn);
795StmtCheckerInfo info = { checkfn, isForStmtFn,
true};
796StmtCheckers.push_back(info);
801StmtCheckerInfo info = { checkfn, isForStmtFn,
false};
802StmtCheckers.push_back(info);
806PreObjCMessageCheckers.push_back(checkfn);
810ObjCMessageNilCheckers.push_back(checkfn);
814PostObjCMessageCheckers.push_back(checkfn);
818PreCallCheckers.push_back(checkfn);
821PostCallCheckers.push_back(checkfn);
825LocationCheckers.push_back(checkfn);
829BindCheckers.push_back(checkfn);
833EndAnalysisCheckers.push_back(checkfn);
837BeginFunctionCheckers.push_back(checkfn);
841EndFunctionCheckers.push_back(checkfn);
846BranchConditionCheckers.push_back(checkfn);
850NewAllocatorCheckers.push_back(checkfn);
854LiveSymbolsCheckers.push_back(checkfn);
858DeadSymbolsCheckers.push_back(checkfn);
862RegionChangesCheckers.push_back(checkfn);
866PointerEscapeCheckers.push_back(checkfn);
871PointerEscapeCheckers.push_back(checkfn);
875EvalAssumeCheckers.push_back(checkfn);
879EvalCallCheckers.push_back(checkfn);
884EndOfTranslationUnitCheckers.push_back(checkfn);
892CheckerManager::getCachedStmtCheckersFor(
const Stmt*S,
boolisPreVisit) {
895 unsignedKey = (S->getStmtClass() << 1) |
unsigned(isPreVisit);
896 auto[CCI, Inserted] = CachedStmtCheckersMap.try_emplace(Key);
897CachedStmtCheckers &Checkers = CCI->second;
900 for(
const auto&Info : StmtCheckers)
901 if(Info.IsPreVisit == isPreVisit && Info.IsForStmtFn(S))
902Checkers.push_back(Info.CheckFn);
enum clang::sema::@1704::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().
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4