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

371 checkFn(Loc, Val, S, C);

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().