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.