clang: lib/StaticAnalyzer/Core/ExprEngineC.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

17#include

18

19using namespace clang;

20using namespace ento;

21using llvm::APSInt;

22

23

24

25

26

27

28

36 }

37 return Symbol;

38}

39

43

46

47

51

52

54 it != ei; ++it) {

55

57 const LocationContext *LCtx = (*it)->getLocationContext();

58 SVal LeftV = state->getSVal(LHS, LCtx);

59 SVal RightV = state->getSVal(RHS, LCtx);

60

62

63 if (Op == BO_Assign) {

64

65

67 unsigned Count = currBldrCtx->blockCount();

69 Count);

70 }

71

72

74 evalStore(Tmp2, B, LHS, *it, state->BindExpr(B, LCtx, ExprVal),

75 LeftV, RightV);

76 continue;

77 }

78

81

83

84

85 unsigned Count = currBldrCtx->blockCount();

87 RightV, LeftV, RHS, svalBuilder, Count, LCtx);

89 LeftV, RightV, LHS, svalBuilder, Count, LCtx);

90 }

91

92

93

94

96 state = createTemporaryRegionIfNeeded(state, LCtx, LHS);

97

98

99

101 if (Result.isUnknown()) {

102 state = state->BindExpr(B, LCtx, Result);

103 } else {

104

107 }

108

110 continue;

111 }

112

114

115 switch (Op) {

116 default:

117 llvm_unreachable("Invalid opcode for compound assignment.");

118 case BO_MulAssign: Op = BO_Mul; break;

119 case BO_DivAssign: Op = BO_Div; break;

120 case BO_RemAssign: Op = BO_Rem; break;

121 case BO_AddAssign: Op = BO_Add; break;

122 case BO_SubAssign: Op = BO_Sub; break;

123 case BO_ShlAssign: Op = BO_Shl; break;

124 case BO_ShrAssign: Op = BO_Shr; break;

125 case BO_AndAssign: Op = BO_And; break;

126 case BO_XorAssign: Op = BO_Xor; break;

127 case BO_OrAssign: Op = BO_Or; break;

128 }

129

130

131

133 SVal location = LeftV;

134 evalLoad(Tmp, B, LHS, *it, state, location);

135

137 state = N->getState();

139 SVal V = state->getSVal(LHS, LCtx);

140

141

143 cast(B)->getComputationResultType();

145

147 cast(B)->getComputationLHSType();

149

151

152

153 V = svalBuilder.evalCast(V, CLHSTy, LTy);

154

155

158

159

160

161

163

164 if (Result.isUnknown()) {

165

166

167

170

172 } else {

173

174

176 }

177

178

179

181 state = state->BindExpr(B, LCtx, location);

182 else

183 state = state->BindExpr(B, LCtx, Result);

184

185 evalStore(Tmp2, B, LHS, N, state, location, LHSVal);

186 }

187 }

188

189

191}

192

195

197

199

203

205

206

207

209 dyn_cast_or_null(V.getAsRegion())) {

210

211 auto ReferencedVars = BDR->referenced_vars();

214 for (auto Var : ReferencedVars) {

215 const VarRegion *capturedR = Var.getCapturedRegion();

217

218

219

220

221

222

223

224 const Expr *copyExpr = nullptr;

225 if (CI != CE) {

226 assert(CI->getVariable() == capturedR->getDecl());

227 copyExpr = CI->getCopyExpr();

228 CI++;

229 }

230

231 if (capturedR != originalR) {

232 SVal originalV;

234 if (copyExpr) {

235 originalV = State->getSVal(copyExpr, LCtx);

236 } else {

238 }

239 State = State->bindLoc(loc::MemRegionVal(capturedR), originalV, LCtx);

240 }

241 }

242 }

243

249

250

252}

253

264 }

265

266 SVal OrigV = state->getSVal(Ex, LCtx);

267 SVal SimplifiedOrigV = svalBuilder.simplifySVal(state, OrigV);

268 SVal V = svalBuilder.evalCast(SimplifiedOrigV, T, ExTy);

269

270 if (CastE->getCastKind() == CK_BooleanToSignedIntegral && V.isValid())

272

273 state = state->BindExpr(CastE, LCtx, V);

274 if (V.isUnknown() && !OrigV.isUnknown()) {

276 }

278

279 return state;

280}

281

284

287

288 if (CastE->getCastKind() == CK_LValueToRValue ||

289 CastE->getCastKind() == CK_LValueToRValueBitCast) {

290 for (ExplodedNode *subExprNode : dstPreStmt) {

292 const LocationContext *LCtx = subExprNode->getLocationContext();

293 evalLoad(Dst, CastE, CastE, subExprNode, state, state->getSVal(Ex, LCtx));

294 }

295 return;

296 }

297

298

301

302 if (const ExplicitCastExpr *ExCast=dyn_cast_or_null(CastE))

303 T = ExCast->getTypeAsWritten();

304

309

311 case CK_LValueToRValue:

312 case CK_LValueToRValueBitCast:

313 llvm_unreachable("LValueToRValue casts handled earlier.");

314 case CK_ToVoid:

315 continue;

316

317

318 case CK_ARCProduceObject:

319 case CK_ARCConsumeObject:

320 case CK_ARCReclaimReturnedObject:

321 case CK_ARCExtendBlockObject:

322 case CK_CopyAndAutoreleaseBlockObject:

323

324

325

326 case CK_AtomicToNonAtomic:

327 case CK_NonAtomicToAtomic:

328

329 case CK_NoOp:

330 case CK_ConstructorConversion:

331 case CK_UserDefinedConversion:

332 case CK_FunctionToPointerDecay:

333 case CK_BuiltinFnToFnPtr:

334 case CK_HLSLArrayRValue: {

335

338 SVal V = state->getSVal(Ex, LCtx);

339 state = state->BindExpr(CastE, LCtx, V);

341 continue;

342 }

343 case CK_MemberPointerToBoolean:

344 case CK_PointerToBoolean: {

345 SVal V = state->getSVal(Ex, LCtx);

347 if (PTMSV)

348 V = svalBuilder.makeTruthVal(!PTMSV->isNullMemberPointer(), ExTy);

349 if (V.isUndef() || PTMSV) {

350 state = state->BindExpr(CastE, LCtx, V);

352 continue;

353 }

354

355 state =

357 continue;

358 }

359 case CK_Dependent:

360 case CK_ArrayToPointerDecay:

361 case CK_BitCast:

362 case CK_AddressSpaceConversion:

363 case CK_BooleanToSignedIntegral:

364 case CK_IntegralToPointer:

365 case CK_PointerToIntegral: {

366 SVal V = state->getSVal(Ex, LCtx);

367 if (isanonloc::PointerToMember(V)) {

368 state = state->BindExpr(CastE, LCtx, UnknownVal());

370 continue;

371 }

372

373 state =

375 continue;

376 }

377 case CK_IntegralToBoolean:

378 case CK_IntegralToFloating:

379 case CK_FloatingToIntegral:

380 case CK_FloatingToBoolean:

381 case CK_FloatingCast:

382 case CK_FloatingRealToComplex:

383 case CK_FloatingComplexToReal:

384 case CK_FloatingComplexToBoolean:

385 case CK_FloatingComplexCast:

386 case CK_FloatingComplexToIntegralComplex:

387 case CK_IntegralRealToComplex:

388 case CK_IntegralComplexToReal:

389 case CK_IntegralComplexToBoolean:

390 case CK_IntegralComplexCast:

391 case CK_IntegralComplexToFloatingComplex:

392 case CK_CPointerToObjCPointerCast:

393 case CK_BlockPointerToObjCPointerCast:

394 case CK_AnyPointerToBlockPointerCast:

395 case CK_ObjCObjectLValueCast:

396 case CK_ZeroToOCLOpaqueType:

397 case CK_IntToOCLSampler:

398 case CK_LValueBitCast:

399 case CK_FloatingToFixedPoint:

400 case CK_FixedPointToFloating:

401 case CK_FixedPointCast:

402 case CK_FixedPointToBoolean:

403 case CK_FixedPointToIntegral:

404 case CK_IntegralToFixedPoint: {

405 state =

407 continue;

408 }

409 case CK_IntegralCast: {

410

411 SVal V = state->getSVal(Ex, LCtx);

412 if (AMgr.options.ShouldSupportSymbolicIntegerCasts)

414 else

416 state = state->BindExpr(CastE, LCtx, V);

418 continue;

419 }

420 case CK_DerivedToBase:

421 case CK_UncheckedDerivedToBase: {

422

423 SVal val = state->getSVal(Ex, LCtx);

425 state = state->BindExpr(CastE, LCtx, val);

427 continue;

428 }

429

430 case CK_Dynamic: {

431 SVal val = state->getSVal(Ex, LCtx);

432

433

437

438 bool Failed = true;

439

440

442 if (std::optional V =

444 val = *V;

445 Failed = false;

446 }

447

448 if (Failed) {

450

451

453 continue;

454 } else {

455

456 state = state->BindExpr(CastE, LCtx,

458 }

459 } else {

460

463 svalBuilder.conjureSymbolVal(nullptr, CastE, LCtx, resultType,

465 state = state->BindExpr(CastE, LCtx, NewSym);

466 } else

467

468 state = state->BindExpr(CastE, LCtx, val);

469 }

471 continue;

472 }

473 case CK_BaseToDerived: {

474 SVal val = state->getSVal(Ex, LCtx);

478

482 }

483

484

486 val =

487 svalBuilder.conjureSymbolVal(nullptr, CastE, LCtx, resultType,

489 }

490 state = state->BindExpr(CastE, LCtx, val);

492 continue;

493 }

494 case CK_NullToPointer: {

496 state = state->BindExpr(CastE, LCtx, V);

498 continue;

499 }

500 case CK_NullToMemberPointer: {

502 state = state->BindExpr(CastE, LCtx, V);

504 continue;

505 }

506 case CK_DerivedToBaseMemberPointer:

507 case CK_BaseToDerivedMemberPointer:

508 case CK_ReinterpretMemberPointer: {

509 SVal V = state->getSVal(Ex, LCtx);

511 SVal CastedPTMSV =

514 state = state->BindExpr(CastE, LCtx, CastedPTMSV);

516 continue;

517 }

518

519 }

520 [[fallthrough]];

521

522 case CK_ToUnion:

523 case CK_MatrixCast:

524 case CK_VectorSplat:

525 case CK_HLSLVectorTruncation: {

530 nullptr, CastE, LCtx, resultType,

532 state = state->BindExpr(CastE, LCtx, result);

534 continue;

535 }

536 }

537 }

538}

539

544

547

550

551 if (isa<CXXConstructExpr, CXXStdInitializerListExpr>(Init)) {

552

553 } else {

554 assert(isa(Init));

555 Loc CLLoc = State->getLValue(CL, LCtx);

556 State = State->bindLoc(CLLoc, V, LCtx);

557

559 V = CLLoc;

560 }

561

562 B.generateNode(CL, Pred, State->BindExpr(CL, LCtx, V));

563}

564

567 if (isa(*DS->decl_begin())) {

568

569

570

571

572

576 return;

577 }

578

579

580 const VarDecl *VD = dyn_cast_or_null(*DS->decl_begin());

581

582 if (!VD) {

583

585 return;

586 }

587

588

591

593 StmtNodeBuilder B(dstPreVisit, dstEvaluated, *currBldrCtx);

595 I!=E; ++I) {

599

600

601 if (const Expr *InitEx = VD->getInit()) {

602

603

605 SVal InitVal = state->getSVal(InitEx, LC);

606

609 state = finishObjectConstruction(state, DS, LC);

610

611

613 } else {

614

615

617 QualType Ty = InitEx->getType();

618 if (InitEx->isGLValue()) {

620 }

621

622 InitVal = svalBuilder.conjureSymbolVal(nullptr, InitEx, LC, Ty,

624 }

625

626

629 evalBind(Dst2, DS, UpdatedN, state->getLValue(VD, LC), InitVal, true);

631 }

632 }

633 else {

635 }

636 }

637

639}

640

643

644

645

646

647

648

649

650

651

652

653

654

655

656

657

658 assert(B->getOpcode() == BO_LAnd ||

660

663

665

666

667

668

669

671 return;

672 }

673

678 (void) P;

680

682 return;

683 }

685 }

686

688

690 return;

691 }

692

696

697

698

699

701

703 if (const BinaryOperator *Term = cast_or_null(T.getStmt())) {

704 (void) Term;

705 assert(Term->isLogicalOp());

706 assert(SrcBlock->succ_size() == 2);

707

708 unsigned constant = (*SrcBlock->succ_begin() == BE.getDst()) ? 1 : 0;

710 }

711 else {

712

713

714

715 assert(!SrcBlock->empty());

717 const Expr *RHS = cast(Elem.getStmt());

719

721 X = RHSVal;

722 } else {

723

724

725

728 svalBuilder.evalCast(RHSVal, B->getType(), RHS->getType()),

730 }

731 }

733}

734

739

743 unsigned NumInitElements = IE->getNumInits();

744

749

750

751

752 if (NumInitElements == 0) {

754 B.generateNode(IE, Pred, state->BindExpr(IE, LCtx, V));

755 return;

756 }

757

758 for (const Stmt *S : llvm::reverse(*IE)) {

759 SVal V = state->getSVal(cast(S), LCtx);

761 }

762

764 state->BindExpr(IE, LCtx,

766 return;

767 }

768

769

770

771

772 assert(NumInitElements <= 1);

773

775 if (NumInitElements == 0)

777 else

778 V = state->getSVal(IE->getInit(0), LCtx);

779

780 B.generateNode(IE, Pred, state->BindExpr(IE, LCtx, V));

781}

782

784 const Expr *L,

785 const Expr *R,

788 assert(L && R);

789

793 const CFGBlock *SrcBlock = nullptr;

794

795

800

801

802

803

804

805 continue;

806 }

808 SrcState = N->getState();

809 break;

810 }

811

812 assert(SrcBlock && "missing function entry");

813

814

815

816 bool hasValue = false;

818

819 for (CFGElement CE : llvm::reverse(*SrcBlock)) {

820 if (std::optional CS = CE.getAs<CFGStmt>()) {

821 const Expr *ValEx = cast(CS->getStmt());

823

824

825

826 if (const OpaqueValueExpr *OpaqueEx = dyn_cast(L))

827 L = OpaqueEx->getSourceExpr();

828

829

830

832 hasValue = true;

833 V = SrcState->getSVal(ValEx, LCtx);

834 }

835 break;

836 }

837 }

838

839 if (!hasValue)

842

843

844 B.generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V, true));

845}

846

854 assert(IV.getBitWidth() == getContext().getTypeSize(OOE->getType()));

860 X));

861 }

862

863}

864

865

870

873

876

878

880 if (Ex->getKind() == UETT_SizeOf) {

883

884

885

886 continue;

888

889

890

891 continue;

892 }

893 }

894

897

899 state = state->BindExpr(

900 Ex, N->getLocationContext(),

903 }

904

906}

907

910

911

912

913

914

915

916

917 const Expr *Ex = U->getSubExpr()->IgnoreParens();

920 Bldr.generateNode(U, N, state->BindExpr(U, LCtx, state->getSVal(Ex, LCtx)));

921}

922

925

928

931

933 switch (U->getOpcode()) {

934 default: {

939 break;

940 }

941 case UO_Real: {

942 const Expr *Ex = U->getSubExpr()->IgnoreParens();

943

944

946

947 break;

948 }

949

950

951 assert (U->getType() == Ex->getType());

955 state->BindExpr(U, LCtx, state->getSVal(Ex, LCtx)));

956 break;

957 }

958

959 case UO_Imag: {

960 const Expr *Ex = U->getSubExpr()->IgnoreParens();

961

963

964 break;

965 }

966

971 break;

972 }

973

974 case UO_AddrOf: {

975

976 const Expr *Ex = U->getSubExpr()->IgnoreParens();

977 if (const DeclRefExpr *DRE = dyn_cast(Ex)) {

978 const ValueDecl *VD = DRE->getDecl();

979

980 if (isa<CXXMethodDecl, FieldDecl, IndirectFieldDecl>(VD)) {

984 Bldr.generateNode(U, N, State->BindExpr(U, LCtx, SV));

985 break;

986 }

987 }

988

990 break;

991 }

992 case UO_Plus:

993 assert(U->isGLValue());

994 [[fallthrough]];

995 case UO_Deref:

996 case UO_Extension: {

998 break;

999 }

1000

1001 case UO_LNot:

1002 case UO_Minus:

1003 case UO_Not: {

1004 assert (U->isGLValue());

1005 const Expr *Ex = U->getSubExpr()->IgnoreParens();

1008

1009

1010 SVal V = state->getSVal(Ex, LCtx);

1011

1012 if (V.isUnknownOrUndef()) {

1014 break;

1015 }

1016

1017 switch (U->getOpcode()) {

1018 default:

1019 llvm_unreachable("Invalid Opcode.");

1020 case UO_Not:

1021

1022 state = state->BindExpr(

1024 break;

1025 case UO_Minus:

1026

1027 state = state->BindExpr(U, LCtx,

1029 break;

1030 case UO_LNot:

1031

1032

1033

1034

1036 if (std::optional LV = V.getAs<Loc>()) {

1040

1042 } else {

1045 }

1046

1047 state = state->BindExpr(U, LCtx, Result);

1048 break;

1049 }

1051 break;

1052 }

1053 }

1054 }

1055

1057}

1058

1062

1063 assert (U->isIncrementDecrementOp());

1064 const Expr *Ex = U->getSubExpr()->IgnoreParens();

1065

1068 SVal loc = state->getSVal(Ex, LCtx);

1069

1070

1072 evalLoad(Tmp, U, Ex, Pred, state, loc);

1073

1077 state = N->getState();

1078 assert(LCtx == N->getLocationContext());

1079 SVal V2_untested = state->getSVal(Ex, LCtx);

1080

1081

1083 state = state->BindExpr(U, LCtx, V2_untested);

1084

1085

1088 evalStore(Dst3, U, Ex, N, state, loc, V2_untested);

1090

1091 continue;

1092 }

1094

1095

1097

1098

1099

1100

1103

1104 if (U->getType()->isAnyPointerType())

1106 else if (U->getType()->isIntegralOrEnumerationType())

1107 RHS = svalBuilder.makeIntVal(1, U->getType());

1108 else

1110

1111

1112

1113

1114

1115 if (U->getType()->isBooleanType() && U->isIncrementOp())

1117 else

1119

1120

1121 if (Result.isUnknown()){

1126

1127

1128

1129

1132 svalBuilder.evalEQ(state, V2,svalBuilder.makeZeroVal(U->getType()));

1133

1134 if (!state->assume(Constraint, true)) {

1135

1136

1137 Constraint = svalBuilder.evalEQ(state, SymVal,

1139

1140 state = state->assume(Constraint, false);

1141 assert(state);

1142 }

1143 }

1144 }

1145

1146

1147

1148 if (U->isGLValue())

1149 state = state->BindExpr(U, LCtx, loc);

1150 else

1151 state = state->BindExpr(U, LCtx, U->isPostfix() ? V2 : Result);

1152

1153

1158 }

1160}

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

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

static SVal conjureOffsetSymbolOnLocation(SVal Symbol, SVal Other, Expr *Expression, SValBuilder &svalBuilder, unsigned Count, const LocationContext *LCtx)

Optionally conjure and return a symbol for offset when processing an expression Expression.

QualType getRValueReferenceType(QualType T) const

Return the uniqued reference to the type for an rvalue reference to the specified type.

CanQualType getCanonicalType(QualType T) const

Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...

QualType getPointerType(QualType T) const

Return the uniqued reference to the type for a pointer to the specified type.

QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const

Return the uniqued reference to the type for an lvalue reference to the specified type.

A builtin binary operation expression such as "x + y" or "x <= y".

static bool isAdditiveOp(Opcode Opc)

static bool isAssignmentOp(Opcode Opc)

static bool isCompoundAssignmentOp(Opcode Opc)

Represents a block literal declaration, which is like an unnamed FunctionDecl.

capture_const_iterator capture_begin() const

capture_const_iterator capture_end() const

const CFGBlock * getSrc() const

const CFGBlock * getDst() const

BlockExpr - Adaptor class for mixing a BlockDecl with expressions.

const BlockDecl * getBlockDecl() const

This class is used for builtin types like 'int'.

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

reverse_iterator rbegin()

CFGTerminator getTerminator() const

succ_iterator succ_begin()

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

const Stmt * getStmt() const

Represents CFGBlock terminator statement.

CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...

CastKind getCastKind() const

llvm::iterator_range< path_iterator > path()

Path through the class hierarchy taken by casts between base and derived classes (see implementation ...

CharUnits - This is an opaque type for sizes expressed in character units.

QuantityType getQuantity() const

getQuantity - Get the raw integer representation of this quantity.

static CharUnits fromQuantity(QuantityType Quantity)

fromQuantity - Construct a CharUnits quantity from a raw integer type.

CompoundLiteralExpr - [C99 6.5.2.5].

const Expr * getInitializer() const

A reference to a declared variable, function, enum, etc.

DeclStmt - Adaptor class for mixing declarations with statements and expressions.

bool isSingleDecl() const

isSingleDecl - This method returns true if this DeclStmt refers to a single Decl.

decl_iterator decl_begin()

ExplicitCastExpr - An explicit cast written in the source code.

This represents one expression.

bool EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const

EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer,...

llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx, SmallVectorImpl< PartialDiagnosticAt > *Diag=nullptr) const

EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.

Expr * IgnoreParens() LLVM_READONLY

Skip past any parentheses which might surround this expression until reaching a fixed point.

Describes an C or C++ initializer list.

bool isTransparent() const

Is this a transparent initializer list (that is, an InitListExpr that is purely syntactic,...

unsigned getNumInits() const

const Expr * getInit(unsigned Init) const

It wraps the AnalysisDeclContext to represent both the call stack with the help of StackFrameContext ...

Represents a class type in Objective C.

OffsetOfExpr - [C99 7.17] - This represents an expression of the form offsetof(record-type,...

OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.

Represents a point after we ran remove dead bindings BEFORE processing the given statement.

T castAs() const

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

std::optional< T > getAs() const

Convert to the specified ProgramPoint type, returning std::nullopt if this ProgramPoint is not of the...

A (possibly-)qualified type.

Stmt - This represents one statement.

bool isSignedIntegerType() const

Return true if this is an integer type that is signed, according to C99 6.2.5p4 [char,...

bool isRValueReferenceType() const

bool isConstantSizeType() const

Return true if this is not a variable sized type, according to the rules of C99 6....

const T * castAs() const

Member-template castAs.

bool isReferenceType() const

bool isVariableArrayType() const

bool isIntegralOrEnumerationType() const

Determine whether this type is an integral or enumeration type.

bool isLValueReferenceType() const

bool isAnyComplexType() const

bool isIncompleteType(NamedDecl **Def=nullptr) const

Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...

bool isVectorType() const

bool isFloatingType() const

const T * getAs() const

Member-template getAs'.

bool isRecordType() const

UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand.

QualType getTypeOfArgument() const

Gets the argument type, or the type of the argument expression, whichever is appropriate.

UnaryExprOrTypeTrait getKind() const

UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...

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

Represents a variable declaration or definition.

const Expr * getInit() const

AnalyzerOptions & options

llvm::ImmutableList< SVal > getEmptySValList()

llvm::ImmutableList< SVal > prependSVal(SVal X, llvm::ImmutableList< SVal > L)

BlockDataRegion - A region that represents a block instance.

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

Run checkers for post-visiting Stmts.

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

Run checkers for pre-visiting Stmts.

ImplTy::iterator iterator

void insert(const ExplodedNodeSet &S)

const ProgramStateRef & getState() const

pred_iterator pred_begin()

ProgramPoint getLocation() const

getLocation - Returns the edge associated with the given node.

unsigned pred_size() const

const LocationContext * getLocationContext() const

void VisitBinaryOperator(const BinaryOperator *B, ExplodedNode *Pred, ExplodedNodeSet &Dst)

VisitBinaryOperator - Transfer function logic for binary operators.

void VisitGuardedExpr(const Expr *Ex, const Expr *L, const Expr *R, ExplodedNode *Pred, ExplodedNodeSet &Dst)

VisitGuardedExpr - Transfer function logic for ?, __builtin_choose.

void VisitCast(const CastExpr *CastE, const Expr *Ex, ExplodedNode *Pred, ExplodedNodeSet &Dst)

VisitCast - Transfer function logic for all casts (implicit and explicit).

BasicValueFactory & getBasicVals()

void VisitLogicalExpr(const BinaryOperator *B, ExplodedNode *Pred, ExplodedNodeSet &Dst)

VisitLogicalExpr - Transfer function logic for '&&', '||'.

SVal evalBinOp(ProgramStateRef ST, BinaryOperator::Opcode Op, SVal LHS, SVal RHS, QualType T)

void VisitUnaryOperator(const UnaryOperator *B, ExplodedNode *Pred, ExplodedNodeSet &Dst)

VisitUnaryOperator - Transfer function logic for unary operators.

void VisitDeclStmt(const DeclStmt *DS, ExplodedNode *Pred, ExplodedNodeSet &Dst)

VisitDeclStmt - Transfer function logic for DeclStmts.

ProgramStateRef handleLValueBitCast(ProgramStateRef state, const Expr *Ex, const LocationContext *LCtx, QualType T, QualType ExTy, const CastExpr *CastE, StmtNodeBuilder &Bldr, ExplodedNode *Pred)

static std::optional< SVal > getObjectUnderConstruction(ProgramStateRef State, const ConstructionContextItem &Item, const LocationContext *LC)

By looking at a certain item that may be potentially part of an object's ConstructionContext,...

void VisitBlockExpr(const BlockExpr *BE, ExplodedNode *Pred, ExplodedNodeSet &Dst)

VisitBlockExpr - Transfer function logic for BlockExprs.

void VisitIncrementDecrementOperator(const UnaryOperator *U, ExplodedNode *Pred, ExplodedNodeSet &Dst)

Handle ++ and – (both pre- and post-increment).

ASTContext & getContext() const

getContext - Return the ASTContext associated with this analysis.

StoreManager & getStoreManager()

void VisitInitListExpr(const InitListExpr *E, ExplodedNode *Pred, ExplodedNodeSet &Dst)

void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Ex, ExplodedNode *Pred, ExplodedNodeSet &Dst)

VisitUnaryExprOrTypeTraitExpr - Transfer function for sizeof.

CheckerManager & getCheckerManager() const

void VisitOffsetOfExpr(const OffsetOfExpr *Ex, ExplodedNode *Pred, ExplodedNodeSet &Dst)

VisitOffsetOfExpr - Transfer function for offsetof.

void evalLoad(ExplodedNodeSet &Dst, const Expr *NodeEx, const Expr *BoundExpr, ExplodedNode *Pred, ProgramStateRef St, SVal location, const ProgramPointTag *tag=nullptr, QualType LoadTy=QualType())

Simulate a read of the result of Ex.

void handleUOExtension(ExplodedNode *N, const UnaryOperator *U, StmtNodeBuilder &Bldr)

void VisitCompoundLiteralExpr(const CompoundLiteralExpr *CL, ExplodedNode *Pred, ExplodedNodeSet &Dst)

VisitCompoundLiteralExpr - Transfer function logic for compound literals.

SValBuilder & getSValBuilder()

void evalStore(ExplodedNodeSet &Dst, const Expr *AssignE, const Expr *StoreE, ExplodedNode *Pred, ProgramStateRef St, SVal TargetLV, SVal Val, const ProgramPointTag *tag=nullptr)

evalStore - Handle the semantics of a store via an assignment.

static bool isLocType(QualType T)

unsigned blockCount() const

Returns the number of times the current basic block has been visited on the exploded graph path.

void takeNodes(const ExplodedNodeSet &S)

void addNodes(const ExplodedNodeSet &S)

const ExplodedNodeSet & getResults()

StoreManager & getStoreManager()

DefinedOrUnknownSVal makeZeroVal(QualType type)

Construct an SVal representing '0' for the specified type.

DefinedSVal getMemberPointer(const NamedDecl *ND)

NonLoc makePointerToMember(const DeclaratorDecl *DD)

SVal evalMinus(NonLoc val)

SVal evalComplement(NonLoc val)

NonLoc makeCompoundVal(QualType type, llvm::ImmutableList< SVal > vals)

DefinedSVal getBlockPointer(const BlockDecl *block, CanQualType locTy, const LocationContext *locContext, unsigned blockCount)

NonLoc makeArrayIndex(uint64_t idx)

nonloc::ConcreteInt makeIntVal(const IntegerLiteral *integer)

SVal evalCast(SVal V, QualType CastTy, QualType OriginalTy)

Cast a given SVal to another SVal using given QualType's.

DefinedOrUnknownSVal conjureSymbolVal(const void *symbolTag, const Expr *expr, const LocationContext *LCtx, unsigned count)

Create a new symbol with a unique 'name'.

virtual SVal simplifySVal(ProgramStateRef State, SVal Val)=0

Simplify symbolic expressions within a given SVal.

SVal evalEQ(ProgramStateRef state, SVal lhs, SVal rhs)

nonloc::ConcreteInt makeTruthVal(bool b, QualType type)

loc::ConcreteInt makeNullWithType(QualType type)

Create NULL pointer, with proper pointer bit-width for given address space.

SVal evalIntegralCast(ProgramStateRef state, SVal val, QualType castTy, QualType originalType)

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

bool isZeroConstant() const

bool isUnknownOrUndef() const

T castAs() const

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

This builder class is useful for generating nodes that resulted from visiting a statement.

ExplodedNode * generateNode(const Stmt *S, ExplodedNode *Pred, ProgramStateRef St, const ProgramPointTag *tag=nullptr, ProgramPoint::Kind K=ProgramPoint::PostStmtKind)

ExplodedNode * generateSink(const Stmt *S, ExplodedNode *Pred, ProgramStateRef St, const ProgramPointTag *tag=nullptr, ProgramPoint::Kind K=ProgramPoint::PostStmtKind)

SVal evalDerivedToBase(SVal Derived, const CastExpr *Cast)

Evaluates a chain of derived-to-base casts through the path specified in Cast.

std::optional< SVal > evalBaseToDerived(SVal Base, QualType DerivedPtrType)

Attempts to do a down cast.

TypedValueRegion - An abstract class representing regions having a typed value.

const VarDecl * getDecl() const override=0

Value representing integer constant.

Value representing pointer-to-member.

@ PSK_EscapeOther

The reason for pointer escape is unknown.

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

@ Result

The result type of a method or function.

const FunctionProtoType * T

@ Other

Other implicit parameter.

EvalResult is a struct with detailed info about an evaluated expression.