clang: include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.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_BUGREPORTER_H

15#define LLVM_CLANG_STATICANALYZER_CORE_BUGREPORTER_BUGREPORTER_H

16

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

30#include "llvm/ADT/FoldingSet.h"

31#include "llvm/ADT/ImmutableSet.h"

32#include "llvm/ADT/SmallSet.h"

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

34#include "llvm/ADT/StringMap.h"

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

36#include "llvm/ADT/ilist.h"

37#include "llvm/ADT/ilist_node.h"

38#include "llvm/ADT/iterator_range.h"

39#include

40#include

41#include

42#include

43#include

44#include

45

47

54

55namespace ento {

56

63

64

65

66

67

68

69

71 llvm::DenseMap<PathDiagnosticConsumer *, std::unique_ptr>;

72

73

74

75

76

84

85

86

87

88

89

90

92private:

94 std::string Msg;

95

96public:

99

100

101

103

104

105

107

111

115};

116

117

118

120public:

122

123protected:

126

131

135

138

143

144public:

146

148

150

151

152

153

154

155

156

158

159

160

161

162

168

169

170

171

172

174

175

176

177

179

180

181

182

183

184

185

186

187

188

190

191

192

193

194

196

197

198

199

200

203 auto P = std::make_shared(Pos, Msg);

204

205 for (const auto &R : Ranges)

206 P->addRange(R);

207

208 Notes.push_back(std::move(P));

209 }

210

214

215

216

217

218

219

220

221

223 assert((R.isValid() || Ranges.empty()) && "Invalid range can only be used "

224 "to specify that the report does not have a range.");

226 }

227

228

232

233

234

235

236

237

238

239

243

245

246

247

248 virtual void Profile(llvm::FoldingSetNodeID& hash) const = 0;

249};

250

253 const Decl *DeclWithIssue = nullptr;

254

255public:

258

262

264 assert(Location.isValid());

265 return Location;

266 }

267

269 return DeclWithIssue;

270 }

271

275

279

280

281

283 DeclWithIssue = declWithIssue;

284 }

285

286 void Profile(llvm::FoldingSetNodeID& hash) const override;

287};

288

290public:

293 using visitor_range = llvm::iterator_range<visitor_iterator>;

294

295protected:

296

297

299

300

301

303

304

305

306

307

308

309

310

312

313

314

315

316

317

318 llvm::DenseMap<const MemRegion *, bugreporter::TrackingKind>

320

321

322

324

325

326

328

329

331

332

333

334

336

337

338

339

340

342

343

344

345

346

347

349

350

352

353

354

357

359

360

361

362

363

364

365 std::map<PathDiagnosticPieceRef, std::unique_ptr>

367

368public:

372

378

379

380

381

382

383

384

385

389 const Decl *DeclToUnique)

391 DeclToUnique) {}

392

396 const Decl *DeclToUnique);

397

401

403

404

405

407

408

410

411

415

416

420

422

424

426

427

428

429

432

434

435

436

437

441

443

444

445

446

450

455

456 std::optionalbugreporter::TrackingKind

458

459 std::optionalbugreporter::TrackingKind

461

463

464

465

466

467

471

472

473

474

475

476

477

478

479

480

484

485

486

487

488 void Profile(llvm::FoldingSetNodeID &hash) const override;

489

490

491

492

493

494

495 void addVisitor(std::unique_ptr visitor);

496

497 template <class VisitorType, class... Args>

500 std::make_unique(std::forward(ConstructorArgs)...));

501 }

502

503

504

506

507

511

512

513

514

518

520 std::unique_ptr StackHint) {

521 StackHints[Piece] = std::move(StackHint);

522 }

523

527

528

529

530 std::string

535 return I->second->getMessage(N);

536 return "";

537 }

538};

539

540

541

542

543

546

547

549

550 void AddReport(std::unique_ptr &&R) {

551 Reports.push_back(std::move(R));

552 }

553

554public:

556

558

559 void Profile(llvm::FoldingSetNodeID& ID) const {

560 assert(!Reports.empty());

561 Reports.front()->Profile(ID);

562 }

563};

564

565

566

567

568

580

581

582

583

584

585

587private:

589

590

591 const Decl *AnalysisEntryPoint = nullptr;

592

593

595

596

597 llvm::FoldingSet EQClasses;

598

599

600 std::vector<BugReportEquivClass *> EQClassesVector;

601

602

604

605public:

608

609

611

614 return D.getPathDiagnosticConsumers();

615 }

616

617

620 return EQClasses;

621 }

622

624

627

629

632

633

635

637 assert(EntryPoint);

638 AnalysisEntryPoint = EntryPoint;

639 }

640

641

642

643

644

645

646 virtual void emitReport(std::unique_ptr R);

647

650 StringRef BugCategory, StringRef BugStr,

654

655 void EmitBasicReport(const Decl *DeclWithIssue, CheckerNameRef CheckerName,

656 StringRef BugName, StringRef BugCategory,

657 StringRef BugStr, PathDiagnosticLocation Loc,

659 ArrayRef Fixits = {});

660

661private:

662 llvm::StringMap<std::unique_ptr> StrBugTypes;

663

664

665

666 BugType *getBugTypeForName(CheckerNameRef CheckerName, StringRef name,

667 StringRef category);

668

669 virtual BugReport *

670 findReportInEquivalenceClass(BugReportEquivClass &eqClass,

671 SmallVectorImpl<BugReport *> &bugReports) {

672 return eqClass.getReports()[0].get();

673 }

674

675protected:

676

677 virtual std::unique_ptr

679 BugReport *exampleReport,

680 ArrayRef<std::unique_ptr> consumers,

681 ArrayRef<BugReport *> bugReports);

682};

683

684

687

688 BugReport *findReportInEquivalenceClass(

691

692

693 std::unique_ptr generateDiagnosticForConsumerMap(

695 ArrayRef<std::unique_ptr> consumers,

697

698public:

701

702

703

705

706

707

709

710

711

712

713

714

716 ArrayRef<std::unique_ptr> consumers,

718

719 void emitReport(std::unique_ptr R) override;

720};

721

722

725

726 virtual void anchor();

727

728public:

730

732

735

737 return BR.getStateManager();

738 }

739

741 return BR.getContext();

742 }

743

745 return BR.getSourceManager();

746 }

747

749 return BR.getAnalyzerOptions();

750 }

751};

752

753

754

755

756

757

758

759

760

762public:

763 StringRef getDebugTag() const override { return "Data Tag"; }

764

765

767 std::vector<std::unique_ptr> Tags;

768

769 public:

770 template <class DataTagType, class... Args>

771 const DataTagType *make(Args &&... ConstructorArgs) {

772

773

774 Tags.emplace_back(

775 new DataTagType(std::forward(ConstructorArgs)...));

776 return static_cast<DataTagType *>(Tags.back().get());

777 }

778 };

779

780protected:

782};

783

784

785

787public:

790

791private:

792 static int Kind;

793

795 const bool IsPrunable;

796

797 NoteTag(Callback &&Cb, bool IsPrunable)

798 : DataTag(&Kind), Cb(std::move(Cb)), IsPrunable(IsPrunable) {}

799

800public:

802 return T->getTagKind() == &Kind;

803 }

804

807 std::string Msg = Cb(BRC, R);

808 if (Msg.empty())

809 return std::nullopt;

810

811 return std::move(Msg);

812 }

813

815

816

817

818 return "Note Tag";

819 }

820

822

825};

826

827}

828

829}

830

831#endif

Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.

Defines the clang::Preprocessor interface.

Defines the clang::SourceLocation class and associated facilities.

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.

CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).

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

This represents one expression.

Annotates a diagnostic with some code that should be inserted, removed, or replaced to fix the proble...

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.

ProgramPointTag(void *tagKind=nullptr)

This class handles loading and caching of source files into memory.

A trivial tuple used to represent a source range.

Stmt - This represents one statement.

BasicBugReport(const BugType &bt, StringRef desc, PathDiagnosticLocation l)

Definition BugReporter.h:256

PathDiagnosticLocation getLocation() const override

The primary location of the bug report that points at the undesirable behavior in the code.

Definition BugReporter.h:263

const Decl * getDeclWithIssue() const override

The smallest declaration that contains the bug location.

Definition BugReporter.h:268

PathDiagnosticLocation getUniqueingLocation() const override

Get the location on which the report should be uniqued.

Definition BugReporter.h:272

void Profile(llvm::FoldingSetNodeID &hash) const override

Reports are uniqued to ensure that we do not emit multiple diagnostics for each bug.

static bool classof(const BugReport *R)

Definition BugReporter.h:259

const Decl * getUniqueingDecl() const override

Get the declaration that corresponds to (usually contains) the uniqueing location.

Definition BugReporter.h:276

void setDeclWithIssue(const Decl *declWithIssue)

Specifically set the Decl where an issue occurred.

Definition BugReporter.h:282

Definition BugReporter.h:544

ArrayRef< std::unique_ptr< BugReport > > getReports() const

Definition BugReporter.h:557

BugReportEquivClass(std::unique_ptr< BugReport > R)

Definition BugReporter.h:555

void Profile(llvm::FoldingSetNodeID &ID) const

Definition BugReporter.h:559

friend class BugReporter

Definition BugReporter.h:545

This class provides an interface through which checkers can create individual bug reports.

Definition BugReporter.h:119

llvm::ArrayRef< FixItHint > getFixits() const

Definition BugReporter.h:244

void addRange(SourceRange R)

Add a range to a bug report.

Definition BugReporter.h:222

SmallVector< SourceRange, 4 > Ranges

Definition BugReporter.h:132

std::string ShortDescription

Definition BugReporter.h:129

std::string Description

Definition BugReporter.h:130

void addNote(StringRef Msg, const PathDiagnosticLocation &Pos, ArrayRef< SourceRange > Ranges={})

Add new item to the list of additional notes that need to be attached to this report.

Definition BugReporter.h:201

virtual PathDiagnosticLocation getUniqueingLocation() const =0

Get the location on which the report should be uniqued.

virtual ~BugReport()=default

virtual PathDiagnosticLocation getLocation() const =0

The primary location of the bug report that points at the undesirable behavior in the code.

friend class BugReportEquivClass

Definition BugReporter.h:124

virtual const Decl * getUniqueingDecl() const =0

Get the declaration that corresponds to (usually contains) the uniqueing location.

SmallVector< std::shared_ptr< PathDiagnosticNotePiece >, 4 > Notes

Definition BugReporter.h:133

SmallVector< FixItHint, 4 > Fixits

Definition BugReporter.h:134

ArrayRef< std::shared_ptr< PathDiagnosticNotePiece > > getNotes()

Definition BugReporter.h:211

Kind

Definition BugReporter.h:121

@ PathSensitive

Definition BugReporter.h:121

@ Basic

Definition BugReporter.h:121

BugReport(Kind kind, const BugType &bt, StringRef desc)

Definition BugReporter.h:136

Kind K

Definition BugReporter.h:127

void addFixItHint(const FixItHint &F)

Add a fix-it hint to the bug report.

Definition BugReporter.h:240

StringRef getDescription() const

A verbose warning message that is appropriate for displaying next to the source code that introduces ...

Definition BugReporter.h:157

const BugType & BT

Definition BugReporter.h:128

virtual void Profile(llvm::FoldingSetNodeID &hash) const =0

Reports are uniqued to ensure that we do not emit multiple diagnostics for each bug.

const BugType & getBugType() const

Definition BugReporter.h:149

StringRef getShortDescription(bool UseFallback=true) const

A short general warning message that is appropriate for displaying in the list of all reported bugs.

Definition BugReporter.h:163

friend class BugReporter

Definition BugReporter.h:125

Kind getKind() const

Definition BugReporter.h:147

virtual ArrayRef< SourceRange > getRanges() const

Get the SourceRanges associated with the report.

Definition BugReporter.h:229

virtual const Decl * getDeclWithIssue() const =0

The smallest declaration that contains the bug location.

BugReport(Kind K, const BugType &BT, StringRef ShortDescription, StringRef Description)

Definition BugReporter.h:139

Definition BugReporter.h:723

ASTContext & getASTContext() const

Definition BugReporter.h:740

BugReporterContext(PathSensitiveBugReporter &br)

Definition BugReporter.h:729

ProgramStateManager & getStateManager() const

Definition BugReporter.h:736

const SourceManager & getSourceManager() const

Definition BugReporter.h:744

PathSensitiveBugReporter & getBugReporter()

Definition BugReporter.h:733

virtual ~BugReporterContext()=default

const PathSensitiveBugReporter & getBugReporter() const

Definition BugReporter.h:734

const AnalyzerOptions & getAnalyzerOptions() const

Definition BugReporter.h:748

Definition BugReporter.h:569

virtual ASTContext & getASTContext()=0

virtual ~BugReporterData()=default

virtual ArrayRef< std::unique_ptr< PathDiagnosticConsumer > > getPathDiagnosticConsumers()=0

virtual AnalyzerOptions & getAnalyzerOptions()=0

virtual SourceManager & getSourceManager()=0

virtual Preprocessor & getPreprocessor()=0

Preprocessor & getPreprocessor()

Definition BugReporter.h:630

void FlushReports()

Generate and flush diagnostics for all bug reports.

BugReporter(BugReporterData &d)

const SourceManager & getSourceManager()

Definition BugReporter.h:625

const Decl * getAnalysisEntryPoint() const

Get the top-level entry point for the issue to be reported.

Definition BugReporter.h:634

ArrayRef< std::unique_ptr< PathDiagnosticConsumer > > getPathDiagnosticConsumers()

Definition BugReporter.h:613

const SourceManager & getSourceManager() const

Definition BugReporter.h:626

const Preprocessor & getPreprocessor() const

Definition BugReporter.h:631

llvm::iterator_range< EQClasses_iterator > equivalenceClasses()

Definition BugReporter.h:619

ASTContext & getContext()

Definition BugReporter.h:623

void EmitBasicReport(const Decl *DeclWithIssue, const CheckerFrontend *Checker, StringRef BugName, StringRef BugCategory, StringRef BugStr, PathDiagnosticLocation Loc, ArrayRef< SourceRange > Ranges={}, ArrayRef< FixItHint > Fixits={})

virtual std::unique_ptr< DiagnosticForConsumerMapTy > generateDiagnosticForConsumerMap(BugReport *exampleReport, ArrayRef< std::unique_ptr< PathDiagnosticConsumer > > consumers, ArrayRef< BugReport * > bugReports)

Generate the diagnostics for the given bug report.

const AnalyzerOptions & getAnalyzerOptions()

Definition BugReporter.h:628

virtual void emitReport(std::unique_ptr< BugReport > R)

Add the given report to the set of reports tracked by BugReporter.

llvm::FoldingSet< BugReportEquivClass >::iterator EQClasses_iterator

Iterator over the set of BugReports tracked by the BugReporter.

Definition BugReporter.h:618

void setAnalysisEntryPoint(const Decl *EntryPoint)

Definition BugReporter.h:636

The non-templated common ancestor of all the simple Checker<...> classes.

A CheckerFrontend instance is what the user recognizes as "one checker": it has a public canonical na...

Simple checker classes that implement one frontend (i.e.

Definition BugReporter.h:766

const DataTagType * make(Args &&... ConstructorArgs)

Definition BugReporter.h:771

DataTag(void *TagKind)

Definition BugReporter.h:781

StringRef getDebugTag() const override

The description of this program point which will be dumped for debugging purposes.

Definition BugReporter.h:763

MemRegion - The root abstract class for all memory regions.

StringRef getDebugTag() const override

The description of this program point which will be dumped for debugging purposes.

Definition BugReporter.h:814

friend class TagVisitor

Definition BugReporter.h:824

static bool classof(const ProgramPointTag *T)

Definition BugReporter.h:801

friend class Factory

Definition BugReporter.h:823

bool isPrunable() const

Definition BugReporter.h:821

std::function< std::string(BugReporterContext &, PathSensitiveBugReport &)> Callback

Definition BugReporter.h:788

std::optional< std::string > generateMessage(BugReporterContext &BRC, PathSensitiveBugReport &R) const

Definition BugReporter.h:805

Definition BugReporter.h:289

void markInteresting(SymbolRef sym, bugreporter::TrackingKind TKind=bugreporter::TrackingKind::Thorough)

Marks a symbol as interesting.

void addVisitor(Args &&... ConstructorArgs)

Definition BugReporter.h:498

SmallVector< std::unique_ptr< BugReporterVisitor >, 8 > VisitorList

Definition BugReporter.h:291

PathDiagnosticLocation getUniqueingLocation() const override

Get the location on which the report should be uniqued.

Definition BugReporter.h:412

VisitorList Callbacks

A set of custom visitors which generate "event" diagnostics at interesting points in the path.

Definition BugReporter.h:327

const Stmt * getStmt() const

std::string getCallStackMessage(PathDiagnosticPieceRef Piece, const ExplodedNode *N) const

Produce the hint for the given node.

Definition BugReporter.h:531

PathDiagnosticLocation getLocation() const override

The primary location of the bug report that points at the undesirable behavior in the code.

const Decl * getDeclWithIssue() const override

The smallest declaration that contains the bug location.

llvm::SmallPtrSet< const ExplodedNode *, 4 > TrackedConditions

Conditions we're already tracking.

Definition BugReporter.h:351

std::map< PathDiagnosticPieceRef, std::unique_ptr< StackHintGenerator > > StackHints

If an event occurs in a different frame than the final diagnostic, supply a message that will be used...

Definition BugReporter.h:366

std::pair< const void *, const void * > InvalidationRecord

Used to track unique reasons why a bug report might be invalid.

Definition BugReporter.h:341

bool shouldPrunePath() const

Indicates whether or not any path pruning should take place when generating a PathDiagnostic from thi...

Definition BugReporter.h:406

visitor_range visitors()

Definition BugReporter.h:510

PathDiagnosticLocation UniqueingLocation

Reports with different uniqueing locations are considered to be different for the purposes of dedupli...

Definition BugReporter.h:355

ArrayRef< SourceRange > getRanges() const override

Get the SourceRanges associated with the report.

visitor_iterator visitor_end()

Definition BugReporter.h:509

llvm::DenseMap< SymbolRef, bugreporter::TrackingKind > InterestingSymbols

Profile to identify equivalent bug reports for error report coalescing.

Definition BugReporter.h:311

const Decl * getUniqueingDecl() const override

Get the declaration containing the uniqueing location.

Definition BugReporter.h:417

llvm::SmallSet< InvalidationRecord, 4 > Invalidations

If non-empty, this bug report is likely a false positive and should not be shown to the user.

Definition BugReporter.h:348

const ExplodedNode * getErrorNode() const

Definition BugReporter.h:402

PathSensitiveBugReport(const BugType &bt, StringRef desc, const ExplodedNode *errorNode)

Definition BugReporter.h:369

static bool classof(const BugReport *R)

Definition BugReporter.h:398

const ExplodedNode * ErrorNode

The ExplodedGraph node against which the report was thrown.

Definition BugReporter.h:298

PathSensitiveBugReport(const BugType &bt, StringRef shortDesc, StringRef desc, const ExplodedNode *errorNode)

Definition BugReporter.h:373

bool addTrackedCondition(const ExplodedNode *Cond)

Notes that the condition of the CFGBlock associated with Cond is being tracked.

Definition BugReporter.h:515

visitor_iterator visitor_begin()

Iterators through the custom diagnostic visitors.

Definition BugReporter.h:508

void addCallStackHint(PathDiagnosticPieceRef Piece, std::unique_ptr< StackHintGenerator > StackHint)

Definition BugReporter.h:519

void markInvalid(const void *Tag, const void *Data)

Marks the current report as invalid, meaning that it is probably a false positive and should not be r...

Definition BugReporter.h:481

void Profile(llvm::FoldingSetNodeID &hash) const override

Profile to identify equivalent bug reports for error report coalescing.

void clearVisitors()

Remove all visitors attached to this bug report.

bool hasCallStackHint(PathDiagnosticPieceRef Piece) const

Definition BugReporter.h:524

void addVisitor(std::unique_ptr< BugReporterVisitor > visitor)

Add custom or predefined bug report visitors to this report.

bool isValid() const

Returns whether or not this report should be considered valid.

Definition BugReporter.h:468

std::optional< bugreporter::TrackingKind > getInterestingnessKind(SymbolRef sym) const

void markNotInteresting(SymbolRef sym)

bool DoNotPrunePath

When set, this flag disables all callstack pruning from a diagnostic path.

Definition BugReporter.h:335

PathSensitiveBugReport(const BugType &bt, StringRef desc, const ExplodedNode *errorNode, PathDiagnosticLocation LocationToUnique, const Decl *DeclToUnique)

Create a PathSensitiveBugReport with a custom uniqueing location.

Definition BugReporter.h:386

llvm::DenseMap< const MemRegion *, bugreporter::TrackingKind > InterestingRegions

A (stack of) set of regions that are registered with this report as being "interesting",...

Definition BugReporter.h:319

llvm::iterator_range< visitor_iterator > visitor_range

Definition BugReporter.h:293

bool isInteresting(SymbolRef sym) const

const SourceRange ErrorNodeRange

The range that corresponds to ErrorNode's program point.

Definition BugReporter.h:302

VisitorList::iterator visitor_iterator

Definition BugReporter.h:292

llvm::FoldingSet< BugReporterVisitor > CallbacksSet

Used for ensuring the visitors are only added once.

Definition BugReporter.h:330

void disablePathPruning()

Disable all path pruning when generating a PathDiagnostic.

Definition BugReporter.h:409

llvm::SmallPtrSet< const LocationContext *, 2 > InterestingLocationContexts

A set of location contexts that correspoind to call sites which should be considered "interesting".

Definition BugReporter.h:323

const Decl * UniqueingDecl

Definition BugReporter.h:356

GRBugReporter is used for generating path-sensitive reports.

Definition BugReporter.h:685

const ExplodedGraph & getGraph() const

getGraph - Get the exploded graph created by the analysis engine for the analyzed method or function.

void emitReport(std::unique_ptr< BugReport > R) override

Add the given report to the set of reports tracked by BugReporter.

std::unique_ptr< DiagnosticForConsumerMapTy > generatePathDiagnostics(ArrayRef< std::unique_ptr< PathDiagnosticConsumer > > consumers, ArrayRef< PathSensitiveBugReport * > &bugReports)

bugReports A set of bug reports within a single equivalence class

ProgramStateManager & getStateManager() const

getStateManager - Return the state manager used by the analysis engine.

PathSensitiveBugReporter(BugReporterData &d, ExprEngine &eng)

Definition BugReporter.h:699

SVal - This represents a symbolic expression, which can be either an L-value or an R-value.

StackHintGeneratorForSymbol(SymbolRef S, StringRef M)

Definition BugReporter.h:97

std::string getMessage(const ExplodedNode *N) override

Search the call expression for the symbol Sym and dispatch the 'getMessageForX()' methods to construc...

virtual std::string getMessageForSymbolNotFound()

Definition BugReporter.h:112

virtual std::string getMessageForReturn(const CallExpr *CallExpr)

Definition BugReporter.h:108

virtual std::string getMessageForArg(const Expr *ArgE, unsigned ArgIndex)

Produces the message of the following form: 'Msg via Nth parameter'.

~StackHintGeneratorForSymbol() override=default

Interface for classes constructing Stack hints.

Definition BugReporter.h:77

virtual ~StackHintGenerator()=0

virtual std::string getMessage(const ExplodedNode *N)=0

Construct the Diagnostic message for the given ExplodedNode.

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

const SymExpr * SymbolRef

llvm::DenseMap< PathDiagnosticConsumer *, std::unique_ptr< PathDiagnostic > > DiagnosticForConsumerMapTy

A mapping from diagnostic consumers to the diagnostics they should consume.

Definition BugReporter.h:70

std::shared_ptr< PathDiagnosticPiece > PathDiagnosticPieceRef

The JSON file list parser is used to communicate input to InstallAPI.

const FunctionProtoType * T

int const char * function