A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://clang.llvm.org/doxygen/TypeErasedDataflowAnalysis_8cpp_source.html below:

clang: lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp Source File

15#include <system_error> 34#include "llvm/ADT/ArrayRef.h" 35#include "llvm/ADT/STLExtras.h" 36#include "llvm/Support/Debug.h" 37#include "llvm/Support/Error.h" 39#define DEBUG_TYPE "clang-dataflow" 52template struct

CLANG_EXPORT_TEMPLATE Any::TypeId<clang::dataflow::NoopLattice>;

61 auto

BlockPos = llvm::find_if(

63

return Succ && Succ->getBlockID() == Block.getBlockID();

81class

TerminatorVisitor

84

TerminatorVisitor() =

default

;

85 const Expr

*VisitIfStmt(

const IfStmt

*S) {

return

S->getCond(); }

86 const

Expr *VisitWhileStmt(

const

WhileStmt *S) {

return

S->getCond(); }

87 const

Expr *VisitDoStmt(

const

DoStmt *S) {

return

S->getCond(); }

88 const

Expr *VisitForStmt(

const

ForStmt *S) {

return

S->getCond(); }

89 const

Expr *VisitCXXForRangeStmt(

const

CXXForRangeStmt *) {

94 const

Expr *VisitBinaryOperator(

const

BinaryOperator *S) {

95

assert(S->getOpcode() == BO_LAnd || S->getOpcode() == BO_LOr);

98 const

Expr *VisitConditionalOperator(

const

ConditionalOperator *S) {

104struct

AnalysisContext {

105

AnalysisContext(

const

AdornedCFG &

ACFG

, TypeErasedDataflowAnalysis &

Analysis

,

110 Log

(*

InitEnv

.getDataflowAnalysisContext().getOptions().

Log

),

114

~AnalysisContext() {

Log

.endAnalysis(); }

128class

PrettyStackTraceAnalysis :

public

llvm::PrettyStackTraceEntry {

130

PrettyStackTraceAnalysis(

const

AdornedCFG &ACFG,

const char

*Message)

131

: ACFG(ACFG), Message(Message) {}

133 void print

(raw_ostream &OS)

const override

{

134

OS << Message <<

"\n"

;

136

ACFG.getDecl().dump(OS);

138

ACFG.getCFG().print(OS, LangOptions(),

false

);

142 const

AdornedCFG &ACFG;

146class

PrettyStackTraceCFGElement :

public

llvm::PrettyStackTraceEntry {

148

PrettyStackTraceCFGElement(

const

CFGElement &Element,

int

BlockIdx,

149 int

ElementIdx,

const char

*Message)

150

: Element(Element), BlockIdx(BlockIdx), ElementIdx(ElementIdx),

153 void print

(raw_ostream &OS)

const override

{

154

OS << Message <<

": Element [B"

<< BlockIdx <<

"."

<< ElementIdx <<

"]\n"

;

155 if

(

auto

Stmt = Element.getAs<CFGStmt>()) {

157

ASTDumper Dumper(OS,

false

);

158

Dumper.Visit(Stmt->getStmt());

163 const

CFGElement &Element;

173class

JoinedStateBuilder {

175

Environment::ExprJoinBehavior JoinBehavior;

176

std::vector<const TypeErasedDataflowAnalysisState *>

All

;

177

std::deque<TypeErasedDataflowAnalysisState> Owned;

179

TypeErasedDataflowAnalysisState

180

join(

const

TypeErasedDataflowAnalysisState &L,

181 const

TypeErasedDataflowAnalysisState &R) {

182 return

{AC.Analysis.joinTypeErased(L.Lattice, R.Lattice),

183

Environment::join(L.Env, R.Env, AC.Analysis, JoinBehavior)};

187

JoinedStateBuilder(AnalysisContext &AC,

188

Environment::ExprJoinBehavior JoinBehavior)

189

: AC(AC), JoinBehavior(JoinBehavior) {}

191 void

addOwned(TypeErasedDataflowAnalysisState State) {

192

Owned.push_back(std::move(State));

193 All

.push_back(&Owned.back());

195 void

addUnowned(

const

TypeErasedDataflowAnalysisState &State) {

196 All

.push_back(&State);

198

TypeErasedDataflowAnalysisState take() && {

203 return

{AC.Analysis.typeErasedInitialElement(), AC.InitEnv.fork()};

204 if

(

All

.size() == 1)

209 return

{

All

[0]->Lattice, Environment::join(All[0]->

Env

, All[0]->

Env

,

210

AC.Analysis, JoinBehavior)};

212 auto

Result = join(*All[0], *All[1]);

213 for

(

unsigned

I = 2; I <

All

.size(); ++I)

214

Result = join(Result, *All[I]);

221 return

TerminatorStmt ==

nullptr

? nullptr

222

: TerminatorVisitor().Visit(TerminatorStmt);

233static

TypeErasedDataflowAnalysisState

235

std::vector<const CFGBlock *> Preds(

Block

.pred_begin(),

Block

.pred_end());

236 if

(

Block

.getTerminator().isTemporaryDtorsBranch()) {

259 if

(

Block

.succ_begin()->getReachableBlock() !=

nullptr

&&

260 Block

.succ_begin()->getReachableBlock()->hasNoReturnElement()) {

261 const CFGBlock

*StmtBlock =

nullptr

;

262 if

(

const Stmt

*Terminator =

Block

.getTerminatorStmt())

263

StmtBlock = AC.ACFG.blockForStmt(*Terminator);

264

assert(StmtBlock !=

nullptr

);

265

llvm::erase(Preds, StmtBlock);

277 for

(

const CFGBlock

*Pred : Preds) {

278 if

(Pred && AC.ACFG.containsExprConsumedInDifferentBlock(*Pred)) {

279

JoinBehavior = Environment::KeepExprState;

284

JoinedStateBuilder Builder(AC, JoinBehavior);

285 for

(

const CFGBlock

*Pred : Preds) {

287 if

(!Pred || Pred->hasNoReturnElement())

292 const

std::optional<TypeErasedDataflowAnalysisState> &MaybePredState =

293

AC.BlockStates[Pred->getBlockID()];

299 if

(Cond ==

nullptr

) {

300

Builder.addUnowned(PredState);

309 if

(AC.Analysis.builtinOptions()) {

315

assert(CondVal !=

nullptr

);

317

BranchVal ? CondVal : &

Copy

.Env.makeNot(*CondVal);

320

AC.Analysis.transferBranchTypeErased(BranchVal, Cond,

Copy

.Lattice,

322

Builder.addOwned(std::move(

Copy

));

324 return

std::move(Builder).take();

331

AnalysisContext &AC) {

333

assert(S !=

nullptr

);

335

InputState.

Env

, AC.Analysis);

343

assert(Init !=

nullptr

);

345 auto

&

Env

= InputState.

Env

;

346 auto

&ThisLoc = *

Env

.getThisPointeeStorageLocation();

348 if

(!Init->isAnyMemberInitializer())

352 auto

*InitExpr = Init->getInit();

353

assert(InitExpr !=

nullptr

);

358 if

(Init->isMemberInitializer()) {

359 Member

= Init->getMember();

360

MemberLoc = ThisLoc.getChild(*

Member

);

363

assert(IndirectField !=

nullptr

);

364

MemberLoc = &ThisLoc;

365 for

(

const auto

*I : IndirectField->

chain

()) {

366 Member

= cast<FieldDecl>(I);

367

ParentLoc = cast<RecordStorageLocation>(MemberLoc);

371

assert(

Member

!=

nullptr

);

380 if

(

Member

->getType()->isReferenceType()) {

381 auto

*InitExprLoc =

Env

.getStorageLocation(*InitExpr);

382 if

(InitExprLoc ==

nullptr

)

388

}

else if

(!

Member

->getType()->isRecordType()) {

389

assert(MemberLoc !=

nullptr

);

390 if

(

auto

*InitExprVal =

Env

.getValue(*InitExpr))

391 Env

.setValue(*MemberLoc, *InitExprVal);

397

AnalysisContext &AC) {

399 case

CFGElement::Statement:

402 case

CFGElement::Initializer:

405 case

CFGElement::LifetimeEnds:

412

State.Env.removeDecl(*VD);

428static

TypeErasedDataflowAnalysisState

431

AC.Log.enterBlock(

Block

, PostAnalysisCallbacks.Before !=

nullptr

||

432

PostAnalysisCallbacks.After !=

nullptr

);

433 auto

State = computeBlockInputState(

Block

, AC);

434

AC.Log.recordState(State);

436 for

(

const auto

&Element :

Block

) {

437

PrettyStackTraceCFGElement CrashInfo(Element,

Block

.getBlockID(),

438

ElementIdx++,

"transferCFGBlock"

);

440

AC.Log.enterElement(Element);

442 if

(PostAnalysisCallbacks.Before) {

443

PostAnalysisCallbacks.Before(Element, State);

447 if

(AC.Analysis.builtinOptions()) {

448

builtinTransfer(

Block

.getBlockID(), Element, State, AC);

452

AC.Analysis.transferTypeErased(Element, State.Lattice, State.Env);

454 if

(PostAnalysisCallbacks.After) {

455

PostAnalysisCallbacks.After(Element, State);

458

AC.Log.recordState(State);

466 if

(

const

Expr *TerminatorCond =

467

dyn_cast_or_null<Expr>(

Block

.getTerminatorCondition())) {

468 if

(State.Env.getValue(*TerminatorCond) ==

nullptr

)

474 transfer

(StmtToEnvMap(AC.ACFG, AC.BlockStates,

Block

.getBlockID(), State),

475

*TerminatorCond, State.Env, AC.Analysis);

480 if

(State.Env.getValue(*TerminatorCond) ==

nullptr

)

481

State.Env.setValue(*TerminatorCond, State.Env.makeAtomicBoolValue());

482

AC.Log.recordState(State);

493

std::int32_t MaxBlockVisits) {

494

PrettyStackTraceAnalysis CrashInfo(

ACFG

,

"runTypeErasedDataflowAnalysis"

);

496

std::optional<Environment> MaybeStartingEnv;

497 if

(

InitEnv

.callStackSize() == 0) {

498

MaybeStartingEnv =

InitEnv

.fork();

499

MaybeStartingEnv->initialize();

502

MaybeStartingEnv ? *MaybeStartingEnv :

InitEnv

;

508

std::vector<std::optional<TypeErasedDataflowAnalysisState>>

BlockStates

(

514

StartingEnv.

fork

()};

518

std::int32_t BlockVisits = 0;

520

LLVM_DEBUG(llvm::dbgs()

521

<<

"Processing Block "

<<

Block

->getBlockID() <<

"\n"

);

522 if

(++BlockVisits > MaxBlockVisits) {

523 return

llvm::createStringError(std::errc::timed_out,

524 "maximum number of blocks processed"

);

527 const

std::optional<TypeErasedDataflowAnalysisState> &OldBlockState =

532

llvm::errs() <<

"New Env:\n"

;

538

llvm::errs() <<

"Old Env:\n"

;

539

OldBlockState->Env.dump();

543

NewBlockState.

Lattice

, OldBlockState->Lattice);

546 if

(Effect1 == LatticeJoinEffect::Unchanged &&

547

Effect2 == LatticeJoinEffect::Unchanged) {

550

AC.Log.blockConverged();

553

}

else if

(

Analysis

.isEqualTypeErased(OldBlockState->Lattice,

555

OldBlockState->Env.equivalentTo(NewBlockState.

Env

,

Analysis

)) {

558

AC.Log.blockConverged();

566 if

(

Block

->hasNoReturnElement())

574 if

(PostAnalysisCallbacks.

Before

|| PostAnalysisCallbacks.

After

) {

static const Stmt * getTerminatorCondition(const CFGBlock *B)

A customized wrapper for CFGBlock::getTerminatorCondition() which returns the element for ObjCForColl...

Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....

static void print(llvm::raw_ostream &OS, const T &V, ASTContext &ASTCtx, QualType Ty)

llvm::ArrayRef< std::optional< TypeErasedDataflowAnalysisState > > BlockStates

Stores the state of a CFG block if it has been evaluated by the analysis.

const Environment & InitEnv

Initial state to start the analysis.

TypeErasedDataflowAnalysis & Analysis

The analysis to be run.

const AdornedCFG & ACFG

Contains the CFG being analyzed.

This class represents a potential adjacent block in the CFG.

Represents a single basic block in a source-level CFG.

succ_iterator succ_begin()

const Stmt * getLoopTarget() const

unsigned getBlockID() const

Represents a top-level expression in a basic block.

T castAs() const

Convert to the specified CFGElement type, asserting that this CFGElement is of the desired type.

Represents C++ base or member initializer from constructor's initialization list.

CXXCtorInitializer * getInitializer() const

Represents the point where the lifetime of an automatic object ends.

const VarDecl * getVarDecl() const

const Stmt * getStmt() const

Represents a source-level, intra-procedural CFG that represents the control-flow of a Stmt.

unsigned size() const

Return the total number of CFGBlocks within the CFG This is simply a renaming of the getNumBlockIDs()...

Represents a C++ base or member initializer.

ConstStmtVisitor - This class implements a simple visitor for Stmt subclasses.

const CFGBlock * dequeue()

This represents one expression.

Represents a member of a struct/union/class.

IfStmt - This represents an if/then/else.

Represents a field injected from an anonymous union/struct into the parent scope.

ArrayRef< NamedDecl * > chain() const

Stmt - This represents one statement.

Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...

Holds CFG with additional information derived from it that is needed to perform dataflow analysis.

const Formula & formula() const

Holds the state of the program (store and heap) at a given program point.

LatticeEffect widen(const Environment &PrevEnv, Environment::ValueModel &Model)

Widens the environment point-wise, using PrevEnv as needed to inform the approximation.

LLVM_DUMP_METHOD void dump() const

Environment fork() const

Returns a new environment that is a copy of this one.

ExprJoinBehavior

How to treat expression state (ExprToLoc and ExprToVal) in a join.

A storage location for a record (struct, class, or union).

StorageLocation * getChild(const ValueDecl &D) const

Returns the child storage location for D.

void setChild(const ValueDecl &D, StorageLocation *Loc)

Changes the child storage location for a field D of reference type.

Maps statements to the environments of basic blocks that contain them.

Base class for elements of the local variable store and of the heap.

Type-erased base class for dataflow analyses built on a single lattice type.

constexpr XRayInstrMask All

void transfer(const StmtToEnvMap &StmtToEnv, const Stmt &S, Environment &Env, Environment::ValueModel &Model)

Evaluates S and updates Env accordingly.

static TypeErasedDataflowAnalysisState computeBlockInputState(const CFGBlock &Block, AnalysisContext &AC)

Computes the input state for a given basic block by joining the output states of its predecessors.

static void builtinTransfer(unsigned CurBlockID, const CFGElement &Elt, TypeErasedDataflowAnalysisState &State, AnalysisContext &AC)

static void builtinTransferInitializer(const CFGInitializer &Elt, TypeErasedDataflowAnalysisState &InputState)

Built-in transfer function for CFGInitializer.

static TypeErasedDataflowAnalysisState transferCFGBlock(const CFGBlock &Block, AnalysisContext &AC, const CFGEltCallbacksTypeErased &PostAnalysisCallbacks={})

Transfers State by evaluating each element in the Block based on the AC.Analysis specified.

static int blockIndexInPredecessor(const CFGBlock &Pred, const CFGBlock &Block)

Returns the index of Block in the successors of Pred.

static bool isBackedgeNode(const CFGBlock &B)

llvm::Expected< std::vector< std::optional< TypeErasedDataflowAnalysisState > > > runTypeErasedDataflowAnalysis(const AdornedCFG &ACFG, TypeErasedDataflowAnalysis &Analysis, const Environment &InitEnv, const CFGEltCallbacksTypeErased &PostAnalysisCallbacks, std::int32_t MaxBlockVisits)

Performs dataflow analysis and returns a mapping from basic block IDs to dataflow analysis states tha...

static void builtinTransferStatement(unsigned CurBlockID, const CFGStmt &Elt, TypeErasedDataflowAnalysisState &InputState, AnalysisContext &AC)

Built-in transfer function for CFGStmt.

LatticeEffect

Effect indicating whether a lattice operation resulted in a new value.

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

Diagnostic wrappers for TextAPI types for error reporting.

A worklist implementation for forward dataflow analysis.

void enqueueSuccessors(const CFGBlock *Block)

A pair of callbacks to be called with the state before and after visiting a CFG element.

CFGEltCallbackTypeErased Before

CFGEltCallbackTypeErased After

Type-erased model of the program at a given program point.

TypeErasedLattice Lattice

Type-erased model of a program property.

Environment Env

Model of the state of the program (store and heap).


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