clang: include/clang/StaticAnalyzer/Core/CheckerManager.h Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13#ifndef LLVM_CLANG_STATICANALYZER_CORE_CHECKERMANAGER_H

14#define LLVM_CLANG_STATICANALYZER_CORE_CHECKERMANAGER_H

15

21#include "llvm/ADT/ArrayRef.h"

22#include "llvm/ADT/DenseMap.h"

23#include "llvm/ADT/SmallVector.h"

24#include "llvm/ADT/StringRef.h"

25#include

26

28

29class AnalyzerOptions;

30class CallExpr;

32class LocationContext;

33class Stmt;

34class TranslationUnitDecl;

35

36namespace ento {

37

38class AnalysisManager;

39class CXXAllocatorCall;

40class BugReporter;

41class CallEvent;

42class CheckerBase;

43class CheckerContext;

44class CheckerRegistry;

45struct CheckerRegistryData;

46class ExplodedGraph;

47class ExplodedNode;

48class ExplodedNodeSet;

49class ExprEngine;

50struct EvalCallOptions;

51class MemRegion;

52class NodeBuilderContext;

53class ObjCMethodCall;

54class RegionAndSymbolInvalidationTraits;

55class SVal;

56class SymbolReaper;

57

59

60template <typename RET, typename... Ps>

62 using Func = RET (*)(void *, Ps...);

63

64 Func Fn;

65

66public:

68

70

72 return Fn(Checker, ps...);

73 }

74};

75

76

77

79

80

82

83

85

86

87

88

90

91

92

93

95

96

97

100

101

102

103

104

105

107 friend class ::clang::ento::CheckerRegistry;

108

109 StringRef Name;

110

111 explicit CheckerNameRef(StringRef Name) : Name(Name) {}

112

113public:

115

116 StringRef getName() const { return Name; }

117 operator StringRef() const { return Name; }

118};

119

124};

125

133 std::unique_ptr RegistryData;

134

135public:

136

137

138

139

140

141

146

147

148

149

153

154

155

156

157 CheckerManager(AnalyzerOptions &AOptions, const LangOptions &LangOpts,

158 DiagnosticsEngine &Diags, ArrayRefstd::string plugins);

159

161

164

166

170 assert(PP);

171 return *PP;

172 }

174 return *RegistryData;

175 }

178 assert(Context);

179 return *Context;

180 }

181

182

183

185 StringRef OptionName,

186 StringRef ExpectedValueDesc) const;

187

191

192

193

194

195

196

197

198

199

200

201 template <typename CHECKER, typename... AT>

205 assert(!ref && "Checker already registered, use getChecker!");

206

207 CHECKER *checker = new CHECKER(std::forward(Args)...);

208 checker->Name = CurrentCheckerName;

209 CheckerDtors.push_back(CheckerDtor(checker, destruct));

210 CHECKER::_register(checker, *this);

211 ref = checker;

212 return checker;

213 }

214

215 template

218 assert(CheckerTags.count(tag) != 0 &&

219 "Requested checker is not registered! Maybe you should add it as a "

220 "dependency in Checkers.td?");

221 return static_cast<CHECKER *>(CheckerTags[tag]);

222 }

223

225 return CheckerTags.contains(getTag());

226 }

227

228

229

230

231

232

235

236

239

240

241

242

243

244

245

246

247

248

249

252 const Stmt *S,

255 }

256

257

258

259

260

261

262

265 const Stmt *S,

267 bool wasInlined = false) {

268 runCheckersForStmt(false, Dst, Src, S, Eng, wasInlined);

269 }

270

271

275 bool wasInlined = false);

276

277

283 }

284

285

290 bool wasInlined = false) {

292 wasInlined);

293 }

294

295

301 Eng);

302 }

303

304

309 bool wasInlined = false);

310

311

315 }

316

317

320 bool wasInlined = false) {

322 wasInlined);

323 }

324

325

329 bool wasInlined = false);

330

331

334 SVal location,

335 bool isLoad,

336 const Stmt *NodeEx,

337 const Stmt *BoundEx,

339

340

346

347

350

351

356

357

363

364

368

369

372 ExprEngine &Eng, bool wasInlined = false);

373

374

375

376

377

378

381

382

383

384

385

386

392

393

394

395

396

397

398

399

400

401

402

403

411

412

413

414

415

416

417

418

419

420

421

422

423

424

425

426

433

434

436 SVal Cond, bool Assumption);

437

438

439

440

444

445

449

450

451

452

453

454

455

456

457

458

459

461 const char *NL = "\n",

462 unsigned int Space = 0,

463 bool IsDot = false) const;

464

465

466

467

468

469

470

471

474

476

478

480

481

482

483

484

486

489

492

495

498

501

503

506

509

512

515

517

525

531

534

536

540

542

547

550

552

555

557

559

561

564

566

568

570

572

574

576

578

580

582

584

585

586

587

588

591

592 template

594 EventInfo &info = Events[&EVENT::Tag];

595 info.Checkers.push_back(checkfn);

596 }

597

598 template

600 EventInfo &info = Events[&EVENT::Tag];

601 info.HasDispatcher = true;

602 }

603

604 template

606 EventsTy::const_iterator I = Events.find(&EVENT::Tag);

607 if (I == Events.end())

608 return;

609 const EventInfo &info = I->second;

610 for (const auto &Checker : info.Checkers)

612 }

613

614

615

616

617

618private:

619 template

620 static void destruct(void *obj) { delete static_cast<CHECKER *>(obj); }

621

622 template

623 static void *getTag() { static int tag; return &tag; }

624

625 llvm::DenseMap<CheckerTag, CheckerRef> CheckerTags;

626

627 std::vector CheckerDtors;

628

629 struct DeclCheckerInfo {

632 };

633 std::vector DeclCheckers;

634

635 std::vector BodyCheckers;

636

637 using CachedDeclCheckers = SmallVector<CheckDeclFunc, 4>;

638 using CachedDeclCheckersMapTy = llvm::DenseMap<unsigned, CachedDeclCheckers>;

639 CachedDeclCheckersMapTy CachedDeclCheckersMap;

640

641 struct StmtCheckerInfo {

644 bool IsPreVisit;

645 };

646 std::vector StmtCheckers;

647

648 using CachedStmtCheckers = SmallVector<CheckStmtFunc, 4>;

649 using CachedStmtCheckersMapTy = llvm::DenseMap<unsigned, CachedStmtCheckers>;

650 CachedStmtCheckersMapTy CachedStmtCheckersMap;

651

652 const CachedStmtCheckers &getCachedStmtCheckersFor(const Stmt *S,

653 bool isPreVisit);

654

655

656

657 const std::vector &

659

660 std::vector PreObjCMessageCheckers;

661 std::vector PostObjCMessageCheckers;

662 std::vector ObjCMessageNilCheckers;

663

664 std::vector PreCallCheckers;

665 std::vector PostCallCheckers;

666

667 std::vector LocationCheckers;

668

669 std::vector BindCheckers;

670

671 std::vector EndAnalysisCheckers;

672

673 std::vector BeginFunctionCheckers;

674 std::vector EndFunctionCheckers;

675

676 std::vector BranchConditionCheckers;

677

678 std::vector NewAllocatorCheckers;

679

680 std::vector LiveSymbolsCheckers;

681

682 std::vector DeadSymbolsCheckers;

683

684 std::vector RegionChangesCheckers;

685

686 std::vector PointerEscapeCheckers;

687

688 std::vector EvalAssumeCheckers;

689

690 std::vector EvalCallCheckers;

691

692 std::vector EndOfTranslationUnitCheckers;

693

694 struct EventInfo {

695 SmallVector<CheckEventFunc, 4> Checkers;

696 bool HasDispatcher = false;

697

698 EventInfo() = default;

699 };

700

701 using EventsTy = llvm::DenseMap<EventTag, EventInfo>;

702 EventsTy Events;

703};

704

705}

706

707}

708

709#endif

Defines the Diagnostic-related interfaces.

#define CHECKER(FULLNAME, CLASS, HELPTEXT, DOC_URI, IS_HIDDEN)

enum clang::sema::@1727::IndirectLocalPathEntry::EntryKind Kind

Defines the clang::LangOptions interface.

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.

Decl - This represents one declaration (or definition), e.g.

Concrete class used by the front-end to report problems and issues.

Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...

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.

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.

CheckerFn(CheckerBase *checker, Func fn)

RET operator()(Ps... ps) const

void _registerForLiveSymbols(CheckLiveSymbolsFunc checkfn)

void _registerForEndOfTranslationUnit(CheckEndOfTranslationUnit checkfn)

const AnalyzerOptions & getAnalyzerOptions() const

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 runCheckersForPreObjCMessage(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const ObjCMethodCall &msg, ExprEngine &Eng)

Run checkers for pre-visiting obj-c messages.

void _registerForPreCall(CheckCallFunc checkfn)

void _registerForObjCMessageNil(CheckObjCMessageFunc checkfn)

CHECKER * registerChecker(AT &&... Args)

Used to register checkers.

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.

ASTContext & getASTContext() const

void _registerListenerForEvent(CheckEventFunc checkfn)

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.

const CheckerRegistryData & getCheckerRegistryData() const

CheckerFn< void(const Stmt *, CheckerContext &)> CheckStmtFunc

void runCheckersForEndAnalysis(ExplodedGraph &G, BugReporter &BR, ExprEngine &Eng)

Run checkers for end of analysis.

CheckerManager(ASTContext &Context, AnalyzerOptions &AOptions, const Preprocessor &PP)

Constructs a CheckerManager that ignores all non TblGen-generated checkers.

void runCheckersForPreCall(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const CallEvent &Call, ExprEngine &Eng)

Run checkers for pre-visiting obj-c messages.

CheckerFn< void(const Decl *, AnalysisManager &, BugReporter &)> CheckDeclFunc

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 runCheckersForPostObjCMessage(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const ObjCMethodCall &msg, ExprEngine &Eng, bool wasInlined=false)

Run checkers for post-visiting obj-c messages.

void runCheckersForBeginFunction(ExplodedNodeSet &Dst, const BlockEdge &L, ExplodedNode *Pred, ExprEngine &Eng)

Run checkers on beginning of function.

void runCheckersForPostStmt(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const Stmt *S, ExprEngine &Eng, bool wasInlined=false)

Run checkers for post-visiting Stmts.

void runCheckersForNewAllocator(const CXXAllocatorCall &Call, ExplodedNodeSet &Dst, ExplodedNode *Pred, ExprEngine &Eng, bool wasInlined=false)

Run checkers between C++ operator new and constructor calls.

void runCheckersForPreStmt(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const Stmt *S, ExprEngine &Eng)

Run checkers for pre-visiting Stmts.

void _registerForBranchCondition(CheckBranchConditionFunc checkfn)

void runCheckersForObjCMessageNil(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const ObjCMethodCall &msg, ExprEngine &Eng)

Run checkers for visiting an obj-c message to nil.

void _dispatchEvent(const EVENT &event) const

void runCheckersForStmt(bool isPreVisit, ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const Stmt *S, ExprEngine &Eng, bool wasInlined=false)

Run checkers for visiting Stmts.

const LangOptions & getLangOpts() const

void _registerForEvalCall(EvalCallFunc checkfn)

void _registerForEndFunction(CheckEndFunctionFunc checkfn)

void _registerDispatcherForEvent()

void runCheckersForBranchCondition(const Stmt *condition, ExplodedNodeSet &Dst, ExplodedNode *Pred, ExprEngine &Eng)

Run checkers for branch condition.

CheckerNameRef getCurrentCheckerName() const

CheckerFn< void()> CheckerDtor

bool isRegisteredChecker()

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.

void runCheckersForPostCall(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const CallEvent &Call, ExprEngine &Eng, bool wasInlined=false)

Run checkers for post-visiting obj-c messages.

void setCurrentCheckerName(CheckerNameRef name)

ProgramStateRef runCheckersForEvalAssume(ProgramStateRef state, SVal Cond, bool Assumption)

Run checkers for handling assumptions on symbolic values.

const Preprocessor & getPreprocessor() const

This wrapper is used to ensure that only StringRefs originating from the CheckerRegistry are used as ...

StringRef getName() const

Manages a set of available checkers for running a static analysis.

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.

@ Decl

The l-value was an access to a declared entity or something equivalently strong, like the address of ...

PointerEscapeKind

Describes the different reasons a pointer escapes during analysis.

@ PSK_DirectEscapeOnCall

The pointer has been passed to a function call directly.

@ PSK_EscapeOnBind

A pointer escapes due to binding its value to a location that the analyzer cannot track.

@ PSK_IndirectEscapeOnCall

The pointer has been passed to a function indirectly.

@ PSK_EscapeOther

The reason for pointer escape is unknown.

@ PSK_EscapeOutParameters

Escape for a new symbol that was generated into a region that the analyzer cannot follow during a con...

IntrusiveRefCntPtr< const ProgramState > ProgramStateRef

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