A RetroSearch Logo

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

Search Query:

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

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

32#include "llvm/Support/Casting.h" 33#include "llvm/Support/Debug.h" 37#define DEBUG_TYPE "dataflow" 44 if

(

Block

==

nullptr

) {

50 if

(

Block

->getBlockID() == CurBlockID)

51 return

&CurState.

Env

;

52 const auto

&State = BlockToState[

Block

->getBlockID()];

63 if

(LHSValue == RHSValue)

66 if

(

auto

*LHSBool = dyn_cast_or_null<BoolValue>(LHSValue))

67 if

(

auto

*RHSBool = dyn_cast_or_null<BoolValue>(RHSValue))

70 if

(

auto

*LHSPtr = dyn_cast_or_null<PointerValue>(LHSValue))

71 if

(

auto

*RHSPtr = dyn_cast_or_null<PointerValue>(RHSValue))

75 if

(&LHSPtr->getPointeeLoc() == &RHSPtr->getPointeeLoc())

82 if

(

auto

*Top = llvm::dyn_cast<TopBoolValue>(&

V

)) {

98 auto

*B = dyn_cast_or_null<BoolValue>(Val);

103 if

(&UnpackedVal == Val)

138

TransferVisitor(

const

StmtToEnvMap &StmtToEnv, Environment &Env,

139

Environment::ValueModel &Model)

140

: StmtToEnv(StmtToEnv),

Env

(

Env

), Model(Model) {}

142 void

VisitBinaryOperator(

const

BinaryOperator *S) {

143 const

Expr *LHS = S->getLHS();

144

assert(LHS !=

nullptr

);

146 const

Expr *RHS = S->getRHS();

147

assert(RHS !=

nullptr

);

153 if

(S->isCompoundAssignmentOp())

156 switch

(S->getOpcode()) {

158 auto

*LHSLoc =

Env

.getStorageLocation(*LHS);

159 if

(LHSLoc ==

nullptr

)

162 auto

*RHSVal =

Env

.getValue(*RHS);

163 if

(RHSVal ==

nullptr

)

167 Env

.setValue(*LHSLoc, *RHSVal);

170 Env

.setStorageLocation(*S, *LHSLoc);

175

BoolValue &LHSVal = getLogicOperatorSubExprValue(*LHS);

176

BoolValue &RHSVal = getLogicOperatorSubExprValue(*RHS);

178 if

(S->getOpcode() == BO_LAnd)

179 Env

.setValue(*S,

Env

.makeAnd(LHSVal, RHSVal));

181 Env

.setValue(*S,

Env

.makeOr(LHSVal, RHSVal));

187 Env

.setValue(*S, S->getOpcode() == BO_EQ ? LHSEqRHSValue

188

:

Env

.makeNot(LHSEqRHSValue));

200 void

VisitDeclRefExpr(

const

DeclRefExpr *S) {

201 const

ValueDecl *VD = S->getDecl();

202

assert(VD !=

nullptr

);

216 auto

*DeclLoc =

Env

.getStorageLocation(*VD);

217 if

(DeclLoc ==

nullptr

)

220 Env

.setStorageLocation(*S, *DeclLoc);

223 void

VisitDeclStmt(

const

DeclStmt *S) {

226 const auto

&

D

= *cast<VarDecl>(S->getSingleDecl());

231 void

ProcessVarDecl(

const

VarDecl &

D

) {

233 if

(

D

.hasGlobalStorage())

239 if

(

D

.getType()->isReferenceType() &&

Env

.getStorageLocation(

D

) !=

nullptr

)

242

assert(

Env

.getStorageLocation(

D

) ==

nullptr

);

244 Env

.setStorageLocation(

D

,

Env

.createObject(

D

));

249 if

(

const auto

*Decomp = dyn_cast<DecompositionDecl>(&

D

)) {

255 for

(

const auto

*B : Decomp->bindings()) {

256 if

(

auto

*ME = dyn_cast_or_null<MemberExpr>(B->getBinding())) {

257 auto

*DE = dyn_cast_or_null<DeclRefExpr>(ME->getBase());

263

VisitDeclRefExpr(DE);

266 if

(

auto

*

Loc

=

Env

.getStorageLocation(*ME))

267 Env

.setStorageLocation(*B, *

Loc

);

268

}

else if

(

auto

*VD = B->getHoldingVar()) {

276 auto

*VDLoc =

Env

.getStorageLocation(*VD);

277

assert(VDLoc !=

nullptr

);

278 Env

.setStorageLocation(*B, *VDLoc);

284 void

VisitImplicitCastExpr(

const

ImplicitCastExpr *S) {

285 const

Expr *SubExpr = S->getSubExpr();

286

assert(SubExpr !=

nullptr

);

288 switch

(S->getCastKind()) {

289 case

CK_IntegralToBoolean: {

293 if

(

auto

*SubExprVal =

294

dyn_cast_or_null<BoolValue>(

Env

.getValue(*SubExpr)))

295 Env

.setValue(*S, *SubExprVal);

299 Env

.setValue(*S,

Env

.makeAtomicBoolValue());

303 case

CK_LValueToRValue: {

307 if

(SubExprVal ==

nullptr

)

310 Env

.setValue(*S, *SubExprVal);

314 case

CK_IntegralCast:

320 case

CK_UncheckedDerivedToBase:

321 case

CK_ConstructorConversion:

322 case

CK_UserDefinedConversion:

332 case

CK_NullToPointer: {

333 auto

&NullPointerVal =

334 Env

.getOrCreateNullPointerValue(S->getType()->getPointeeType());

335 Env

.setValue(*S, NullPointerVal);

338 case

CK_NullToMemberPointer:

342 case

CK_FunctionToPointerDecay: {

343

StorageLocation *PointeeLoc =

Env

.getStorageLocation(*SubExpr);

344 if

(PointeeLoc ==

nullptr

)

347 Env

.setValue(*S,

Env

.create<PointerValue>(*PointeeLoc));

350 case

CK_BuiltinFnToFnPtr:

361 void

VisitUnaryOperator(

const

UnaryOperator *S) {

362 const

Expr *SubExpr = S->getSubExpr();

363

assert(SubExpr !=

nullptr

);

365 switch

(S->getOpcode()) {

367 const auto

*SubExprVal =

Env

.get<PointerValue>(*SubExpr);

368 if

(SubExprVal ==

nullptr

)

371 Env

.setStorageLocation(*S, SubExprVal->getPointeeLoc());

376 if

(S->getType()->isMemberPointerType())

379 if

(StorageLocation *PointeeLoc =

Env

.getStorageLocation(*SubExpr))

380 Env

.setValue(*S,

Env

.create<PointerValue>(*PointeeLoc));

384 auto

*SubExprVal = dyn_cast_or_null<BoolValue>(

Env

.getValue(*SubExpr));

385 if

(SubExprVal ==

nullptr

)

388 Env

.setValue(*S,

Env

.makeNot(*SubExprVal));

398 if

(StorageLocation *

Loc

=

Env

.getStorageLocation(*S->getSubExpr()))

407 if

(StorageLocation *

Loc

=

Env

.getStorageLocation(*S->getSubExpr()))

415 void

VisitCXXThisExpr(

const

CXXThisExpr *S) {

416 auto

*ThisPointeeLoc =

Env

.getThisPointeeStorageLocation();

417 if

(ThisPointeeLoc ==

nullptr

)

422 Env

.setValue(*S,

Env

.create<PointerValue>(*ThisPointeeLoc));

425 void

VisitCXXNewExpr(

const

CXXNewExpr *S) {

426 if

(

Value

*Val =

Env

.createValue(S->getType()))

427 Env

.setValue(*S, *Val);

430 void

VisitCXXDeleteExpr(

const

CXXDeleteExpr *S) {

437 void

VisitReturnStmt(

const

ReturnStmt *S) {

438 if

(!

Env

.getDataflowAnalysisContext().getOptions().ContextSensitiveOpts)

441 auto

*

Ret

= S->getRetValue();

445 if

(

Ret

->isPRValue()) {

446 if

(

Ret

->getType()->isRecordType())

449 auto

*Val =

Env

.getValue(*Ret);

454 Env

.setReturnValue(Val);

456 auto

*

Loc

=

Env

.getStorageLocation(*Ret);

457 if

(

Loc

==

nullptr

)

461 Env

.setReturnStorageLocation(

Loc

);

465 void

VisitMemberExpr(

const

MemberExpr *S) {

466

ValueDecl *

Member

= S->getMemberDecl();

467

assert(

Member

!=

nullptr

);

470 if

(

Member

->isFunctionOrFunctionTemplate())

474 if

(isa<EnumConstantDecl>(

Member

))

477 if

(

auto

*

D

= dyn_cast<VarDecl>(

Member

)) {

478 if

(

D

->hasGlobalStorage()) {

479 auto

*VarDeclLoc =

Env

.getStorageLocation(*

D

);

480 if

(VarDeclLoc ==

nullptr

)

483 Env

.setStorageLocation(*S, *VarDeclLoc);

489 if

(BaseLoc ==

nullptr

)

492 auto

*MemberLoc = BaseLoc->getChild(*

Member

);

493 if

(MemberLoc ==

nullptr

)

495 Env

.setStorageLocation(*S, *MemberLoc);

498 void

VisitCXXDefaultArgExpr(

const

CXXDefaultArgExpr *S) {

499 const

Expr *ArgExpr = S->getExpr();

500

assert(ArgExpr !=

nullptr

);

503 if

(S->isPRValue() && S->getType()->isRecordType()) {

504 auto

&

Loc

=

Env

.getResultObjectLocation(*S);

505 Env

.initializeFieldsWithValues(

Loc

);

509 void

VisitCXXDefaultInitExpr(

const

CXXDefaultInitExpr *S) {

510 const

Expr *InitExpr = S->getExpr();

511

assert(InitExpr !=

nullptr

);

516 if

(S->getType()->isRecordType() && S->isPRValue())

522 void

VisitCXXConstructExpr(

const

CXXConstructExpr *S) {

523 const

CXXConstructorDecl *ConstructorDecl = S->getConstructor();

524

assert(ConstructorDecl !=

nullptr

);

529 if

(!S->getType()->isRecordType()) {

530

transferInlineCall(S, ConstructorDecl);

534

RecordStorageLocation &

Loc

=

Env

.getResultObjectLocation(*S);

536 if

(ConstructorDecl->isCopyOrMoveConstructor()) {

539

assert(S->getNumArgs() != 0);

541 const

Expr *Arg = S->getArg(0);

542

assert(Arg !=

nullptr

);

544 auto

*ArgLoc =

Env

.get<RecordStorageLocation>(*Arg);

545 if

(ArgLoc ==

nullptr

)

555 Env

.initializeFieldsWithValues(

Loc

, S->getType());

557

transferInlineCall(S, ConstructorDecl);

560 void

VisitCXXOperatorCallExpr(

const

CXXOperatorCallExpr *S) {

561 if

(S->getOperator() == OO_Equal) {

562

assert(S->getNumArgs() == 2);

564 const

Expr *Arg0 = S->getArg(0);

565

assert(Arg0 !=

nullptr

);

567 const

Expr *Arg1 = S->getArg(1);

568

assert(Arg1 !=

nullptr

);

572

dyn_cast_or_null<CXXMethodDecl>(S->getDirectCallee());

575 if

(!Method->isCopyAssignmentOperator() &&

576

!Method->isMoveAssignmentOperator())

579

RecordStorageLocation *LocSrc =

nullptr

;

580 if

(Arg1->isPRValue()) {

581

LocSrc = &

Env

.getResultObjectLocation(*Arg1);

583

LocSrc =

Env

.get<RecordStorageLocation>(*Arg1);

585 auto

*LocDst =

Env

.get<RecordStorageLocation>(*Arg0);

587 if

(LocSrc ==

nullptr

|| LocDst ==

nullptr

)

595 if

(S->getType().getCanonicalType().getUnqualifiedType() !=

596

LocDst->getType().getCanonicalType().getUnqualifiedType()) {

597 auto

ReturnDecl = S->getType()->getAsCXXRecordDecl();

598 auto

DstDecl = LocDst->getType()->getAsCXXRecordDecl();

599 if

(ReturnDecl ==

nullptr

|| DstDecl ==

nullptr

)

601 if

(!DstDecl->isDerivedFrom(ReturnDecl))

606 Env

.setStorageLocation(*S, *LocDst);

618 void

VisitCXXRewrittenBinaryOperator(

const

CXXRewrittenBinaryOperator *RBO) {

622 void

VisitCallExpr(

const

CallExpr *S) {

626 if

(S->isCallToStdMove()) {

627

assert(S->getNumArgs() == 1);

629 const

Expr *Arg = S->getArg(0);

630

assert(Arg !=

nullptr

);

632 auto

*ArgLoc =

Env

.getStorageLocation(*Arg);

633 if

(ArgLoc ==

nullptr

)

636 Env

.setStorageLocation(*S, *ArgLoc);

637

}

else if

(S->getDirectCallee() !=

nullptr

&&

638

S->getDirectCallee()->getBuiltinID() ==

639

Builtin::BI__builtin_expect) {

640

assert(S->getNumArgs() > 0);

641

assert(S->getArg(0) !=

nullptr

);

642 auto

*ArgVal =

Env

.getValue(*S->getArg(0));

643 if

(ArgVal ==

nullptr

)

645 Env

.setValue(*S, *ArgVal);

646

}

else if

(

const

FunctionDecl *F = S->getDirectCallee()) {

647

transferInlineCall(S, F);

651 if

(S->getType()->isRecordType() && S->isPRValue()) {

652

RecordStorageLocation &

Loc

=

Env

.getResultObjectLocation(*S);

653 Env

.initializeFieldsWithValues(

Loc

);

658 void

VisitMaterializeTemporaryExpr(

const

MaterializeTemporaryExpr *S) {

659 const

Expr *SubExpr = S->getSubExpr();

660

assert(SubExpr !=

nullptr

);

662

StorageLocation &

Loc

=

Env

.createStorageLocation(*S);

663 Env

.setStorageLocation(*S,

Loc

);

665 if

(SubExpr->getType()->isRecordType())

670 if

(

Value

*SubExprVal =

Env

.getValue(*SubExpr))

671 Env

.setValue(

Loc

, *SubExprVal);

674 void

VisitCXXBindTemporaryExpr(

const

CXXBindTemporaryExpr *S) {

675 const

Expr *SubExpr = S->getSubExpr();

676

assert(SubExpr !=

nullptr

);

681 void

VisitCXXStaticCastExpr(

const

CXXStaticCastExpr *S) {

682 if

(S->getCastKind() == CK_NoOp) {

683 const

Expr *SubExpr = S->getSubExpr();

684

assert(SubExpr !=

nullptr

);

690 void

VisitConditionalOperator(

const

ConditionalOperator *S) {

691 const

Environment *TrueEnv = StmtToEnv.getEnvironment(*S->getTrueExpr());

692 const

Environment *FalseEnv = StmtToEnv.getEnvironment(*S->getFalseExpr());

694 if

(TrueEnv ==

nullptr

|| FalseEnv ==

nullptr

) {

702 if

(S->isGLValue()) {

703

StorageLocation *TrueLoc = TrueEnv->getStorageLocation(*S->getTrueExpr());

704

StorageLocation *FalseLoc =

705

FalseEnv->getStorageLocation(*S->getFalseExpr());

706 if

(TrueLoc == FalseLoc && TrueLoc !=

nullptr

)

707 Env

.setStorageLocation(*S, *TrueLoc);

708

}

else if

(!S->getType()->isRecordType()) {

725

S->getType(), TrueEnv->getValue(*S->getTrueExpr()), *TrueEnv,

726

FalseEnv->getValue(*S->getFalseExpr()), *FalseEnv, Env, Model))

727 Env

.setValue(*S, *Val);

731 void

VisitInitListExpr(

const

InitListExpr *S) {

732

QualType

Type

= S->getType();

734 if

(!

Type

->isRecordType()) {

737 if

(!

Type

->isArrayType() && S->getNumInits() == 1)

743 if

(S->isSemanticForm() && S->isTransparent())

746

RecordStorageLocation &

Loc

=

Env

.getResultObjectLocation(*S);

753

RecordInitListHelper InitListHelper(S);

755 for

(

auto

[Field,

Init

] : InitListHelper.field_inits()) {

756 if

(

Field

->getType()->isRecordType())

758 if

(

Field

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

759

assert(

Field

->getType().getCanonicalType()->getPointeeType() ==

760 Init

->getType().getCanonicalType());

764

assert(

Field

->getType().getCanonicalType().getUnqualifiedType() ==

765 Init

->getType().getCanonicalType().getUnqualifiedType());

766

StorageLocation *FieldLoc =

Loc

.getChild(*Field);

768

assert(FieldLoc !=

nullptr

);

770 if

(Val ==

nullptr

&& isa<ImplicitValueInitExpr>(

Init

) &&

771 Init

->getType()->isPointerType())

773

&

Env

.getOrCreateNullPointerValue(

Init

->getType()->getPointeeType());

775

Val =

Env

.createValue(

Field

->getType());

777 Env

.setValue(*FieldLoc, *Val);

780 for

(

const auto

&[FieldName, FieldLoc] :

Loc

.synthetic_fields()) {

781

QualType FieldType = FieldLoc->getType();

782 if

(FieldType->isRecordType()) {

783 Env

.initializeFieldsWithValues(*cast<RecordStorageLocation>(FieldLoc));

785 if

(

Value

*Val =

Env

.createValue(FieldType))

786 Env

.setValue(*FieldLoc, *Val);

793 void

VisitCXXBoolLiteralExpr(

const

CXXBoolLiteralExpr *S) {

794 Env

.setValue(*S,

Env

.getBoolLiteralValue(S->getValue()));

797 void

VisitIntegerLiteral(

const

IntegerLiteral *S) {

798 Env

.setValue(*S,

Env

.getIntLiteralValue(S->getValue()));

801 void

VisitParenExpr(

const

ParenExpr *S) {

805 auto

*SubExpr = S->getSubExpr();

806

assert(SubExpr !=

nullptr

);

810 void

VisitExprWithCleanups(

const

ExprWithCleanups *S) {

814 auto

*SubExpr = S->getSubExpr();

815

assert(SubExpr !=

nullptr

);

821

BoolValue &getLogicOperatorSubExprValue(

const

Expr &SubExpr) {

825 if

(

const

Environment *SubExprEnv = StmtToEnv.getEnvironment(SubExpr))

827

dyn_cast_or_null<BoolValue>(SubExprEnv->getValue(SubExpr)))

835 if

(

Env

.getValue(SubExpr) ==

nullptr

)

837 if

(

auto

*Val = dyn_cast_or_null<BoolValue>(

Env

.getValue(SubExpr)))

842 return Env

.makeAtomicBoolValue();

847 template

<

typename

E>

848 void

transferInlineCall(

const E

*S,

const

FunctionDecl *F) {

849 const auto

&Options =

Env

.getDataflowAnalysisContext().getOptions();

850 if

(!(Options.ContextSensitiveOpts &&

851 Env

.canDescend(Options.ContextSensitiveOpts->Depth, F)))

854 const

AdornedCFG *ACFG =

Env

.getDataflowAnalysisContext().getAdornedCFG(F);

862 auto

ExitBlock = ACFG->getCFG().getExit().getBlockID();

864 auto

CalleeEnv =

Env

.pushCall(S);

869 auto Analysis

= NoopAnalysis(ACFG->getDecl().getASTContext(),

870

DataflowAnalysisOptions{Options});

872 auto

BlockToOutputState =

874

assert(BlockToOutputState);

875

assert(ExitBlock < BlockToOutputState->size());

877 auto

&ExitState = (*BlockToOutputState)[ExitBlock];

880 Env

.popCall(S, ExitState->Env);

883 const

StmtToEnvMap &StmtToEnv;

885

Environment::ValueModel &Model;

892

TransferVisitor(StmtToEnv,

Env

, Model).Visit(&S);

Defines enum values for all the target-independent builtin functions.

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

Defines the clang::Expr interface and subclasses for C++ expressions.

Defines an enumeration for C++ overloaded operators.

TypeErasedDataflowAnalysis & Analysis

The analysis to be run.

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

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

This represents one expression.

Stmt - This represents one statement.

bool isRecordType() const

const CFGBlock * blockForStmt(const Stmt &S) const

Returns the basic block that contains S, or null if no basic block containing S is found.

bool isBlockReachable(const CFGBlock &B) const

Returns whether B is reachable from the entry block.

BoolValue & makeBoolValue(const Formula &)

Creates a BoolValue wrapping a particular formula.

Supplements Environment with non-standard comparison and join operations.

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

BoolValue & makeIff(BoolValue &LHS, BoolValue &RHS) const

Returns a boolean value represents LHS <=> RHS.

StorageLocation * getStorageLocation(const ValueDecl &D) const

Returns the storage location assigned to D in the environment, or null if D isn't assigned a storage ...

BoolValue & makeAtomicBoolValue() const

Returns an atomic boolean value.

Value * getValue(const StorageLocation &Loc) const

Returns the value assigned to Loc in the environment or null if Loc isn't assigned a value in the env...

BoolValue & getBoolLiteralValue(bool Value) const

Returns a symbolic boolean value that models a boolean literal equal to Value

DataflowAnalysisContext & getDataflowAnalysisContext() const

Returns the DataflowAnalysisContext used by the environment.

static Value * joinValues(QualType Ty, Value *Val1, const Environment &Env1, Value *Val2, const Environment &Env2, Environment &JoinedEnv, Environment::ValueModel &Model)

Returns a value that approximates both Val1 and Val2, or null if no such value can be produced.

void setStorageLocation(const ValueDecl &D, StorageLocation &Loc)

Assigns Loc as the storage location of D in the environment.

void setValue(const StorageLocation &Loc, Value &Val)

Assigns Val as the value of Loc in the environment.

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

const Environment * getEnvironment(const Stmt &S) const

Returns the environment of the basic block that contains S.

Base class for all values computed by abstract interpretation.

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

Evaluates S and updates Env accordingly.

static void propagateValueOrStorageLocation(const Expr &From, const Expr &To, Environment &Env)

static void propagateStorageLocation(const Expr &From, const Expr &To, Environment &Env)

static void propagateValue(const Expr &From, const Expr &To, Environment &Env)

static Value * maybeUnpackLValueExpr(const Expr &E, Environment &Env)

void copyRecord(RecordStorageLocation &Src, RecordStorageLocation &Dst, Environment &Env)

Copies a record (struct, class, or union) from Src to Dst.

static BoolValue & unpackValue(BoolValue &V, Environment &Env)

static BoolValue & evaluateBooleanEquality(const Expr &LHS, const Expr &RHS, Environment &Env)

RecordStorageLocation * getBaseObjectLocation(const MemberExpr &ME, const Environment &Env)

Returns the storage location for the base object of a MemberExpr, or null if none is defined in the e...

llvm::Expected< std::vector< std::optional< DataflowAnalysisState< typename AnalysisT::Lattice > > > > runDataflowAnalysis(const AdornedCFG &ACFG, AnalysisT &Analysis, const Environment &InitEnv, CFGEltCallbacks< AnalysisT > PostAnalysisCallbacks={}, std::int32_t MaxBlockVisits=kDefaultMaxBlockVisits)

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

bool Ret(InterpState &S, CodePtr &PC)

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

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