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

32 unsigned Count,

37 }

38 return Symbol;

39}

40

44

47

48

52

53

55 it != ei; ++it) {

56

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

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

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

61

63

64 if (Op == BO_Assign) {

65

66

68 unsigned Count = currBldrCtx->blockCount();

69 RightV = svalBuilder.conjureSymbolVal(nullptr, getCFGElementRef(), LCtx,

70 Count);

71 }

72

73

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

76 LeftV, RightV);

77 continue;

78 }

79

82

84

85

86 unsigned Count = currBldrCtx->blockCount();

89 Count, LCtx);

91 LHS->getType(), svalBuilder,

92 Count, LCtx);

93 }

94

95

96

97

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

100

101

102

104 if (Result.isUnknown()) {

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

106 } else {

107

110 }

111

113 continue;

114 }

115

117

118 switch (Op) {

119 default:

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

121 case BO_MulAssign: Op = BO_Mul; break;

122 case BO_DivAssign: Op = BO_Div; break;

123 case BO_RemAssign: Op = BO_Rem; break;

124 case BO_AddAssign: Op = BO_Add; break;

125 case BO_SubAssign: Op = BO_Sub; break;

126 case BO_ShlAssign: Op = BO_Shl; break;

127 case BO_ShrAssign: Op = BO_Shr; break;

128 case BO_AndAssign: Op = BO_And; break;

129 case BO_XorAssign: Op = BO_Xor; break;

130 case BO_OrAssign: Op = BO_Or; break;

131 }

132

133

134

136 SVal location = LeftV;

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

138

140 state = N->getState();

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

143

144

148

152

154

155

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

157

158

161

162

163

164

166

167 if (Result.isUnknown()) {

168

169

170

171 LHSVal = svalBuilder.conjureSymbolVal(nullptr,

173 currBldrCtx->blockCount());

174

175 Result = svalBuilder.evalCast(LHSVal, CTy, LTy);

176 } else {

177

178

179 LHSVal = svalBuilder.evalCast(Result, LTy, CTy);

180 }

181

182

183

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

186 else

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

188

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

190 }

191 }

192

193

195}

196

199

201

203

204 SVal V = svalBuilder.getBlockPointer(BD, T,

206 currBldrCtx->blockCount());

207

209

210

211

213 dyn_cast_or_null(V.getAsRegion())) {

214

215 auto ReferencedVars = BDR->referenced_vars();

218 for (auto Var : ReferencedVars) {

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

221

222

223

224

225

226

227

228 const Expr *copyExpr = nullptr;

229 if (CI != CE) {

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

231 copyExpr = CI->getCopyExpr();

232 CI++;

233 }

234

235 if (capturedR != originalR) {

236 SVal originalV;

238 if (copyExpr) {

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

240 } else {

242 }

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

244 }

245 }

246 }

247

253

254

256}

257

262 if (T->isLValueReferenceType()) {

265 } else if (T->isRValueReferenceType()) {

268 }

269

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

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

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

273

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

275 V = svalBuilder.evalMinus(V.castAs<NonLoc>());

276

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

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

280 }

282

283 return state;

284}

285

288

291

292 if (CastE->getCastKind() == CK_LValueToRValue) {

295 const LocationContext *LCtx = Node->getLocationContext();

296 evalLoad(Dst, CastE, CastE, Node, State, State->getSVal(Ex, LCtx));

297 }

298 return;

299 }

300 if (CastE->getCastKind() == CK_LValueToRValueBitCast) {

301

303

304

307 const LocationContext *LCtx = Node->getLocationContext();

308 evalLocation(DstEvalLoc, CastE, Ex, Node, State, State->getSVal(Ex, LCtx),

309 true);

310 }

311

312

314

317 const LocationContext *LCtx = Node->getLocationContext();

318

319

320

322

323 if (const MemRegion *MR = State->getSVal(Ex, LCtx).getAsRegion()) {

324 SVal OrigV = State->getSVal(MR);

325 CastedV = svalBuilder.evalCast(svalBuilder.simplifySVal(State, OrigV),

327 }

328 State = State->BindExpr(CastE, LCtx, CastedV);

330 }

331 return;

332 }

333

334

337

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

339 T = ExCast->getTypeAsWritten();

340

345

347 case CK_LValueToRValue:

348 case CK_LValueToRValueBitCast:

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

350 case CK_ToVoid:

351 continue;

352

353

354 case CK_ARCProduceObject:

355 case CK_ARCConsumeObject:

356 case CK_ARCReclaimReturnedObject:

357 case CK_ARCExtendBlockObject:

358 case CK_CopyAndAutoreleaseBlockObject:

359

360

361

362 case CK_AtomicToNonAtomic:

363 case CK_NonAtomicToAtomic:

364

365 case CK_NoOp:

366 case CK_ConstructorConversion:

367 case CK_UserDefinedConversion:

368 case CK_FunctionToPointerDecay:

369 case CK_BuiltinFnToFnPtr:

370 case CK_HLSLArrayRValue: {

371

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

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

377 continue;

378 }

379 case CK_MemberPointerToBoolean:

380 case CK_PointerToBoolean: {

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

383 if (PTMSV)

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

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

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

388 continue;

389 }

390

391 state =

393 continue;

394 }

395 case CK_Dependent:

396 case CK_ArrayToPointerDecay:

397 case CK_BitCast:

398 case CK_AddressSpaceConversion:

399 case CK_BooleanToSignedIntegral:

400 case CK_IntegralToPointer:

401 case CK_PointerToIntegral: {

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

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

406 continue;

407 }

408

409 state =

411 continue;

412 }

413 case CK_IntegralToBoolean:

414 case CK_IntegralToFloating:

415 case CK_FloatingToIntegral:

416 case CK_FloatingToBoolean:

417 case CK_FloatingCast:

418 case CK_FloatingRealToComplex:

419 case CK_FloatingComplexToReal:

420 case CK_FloatingComplexToBoolean:

421 case CK_FloatingComplexCast:

422 case CK_FloatingComplexToIntegralComplex:

423 case CK_IntegralRealToComplex:

424 case CK_IntegralComplexToReal:

425 case CK_IntegralComplexToBoolean:

426 case CK_IntegralComplexCast:

427 case CK_IntegralComplexToFloatingComplex:

428 case CK_CPointerToObjCPointerCast:

429 case CK_BlockPointerToObjCPointerCast:

430 case CK_AnyPointerToBlockPointerCast:

431 case CK_ObjCObjectLValueCast:

432 case CK_ZeroToOCLOpaqueType:

433 case CK_IntToOCLSampler:

434 case CK_LValueBitCast:

435 case CK_FloatingToFixedPoint:

436 case CK_FixedPointToFloating:

437 case CK_FixedPointCast:

438 case CK_FixedPointToBoolean:

439 case CK_FixedPointToIntegral:

440 case CK_IntegralToFixedPoint: {

441 state =

443 continue;

444 }

445 case CK_IntegralCast: {

446

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

448 if (AMgr.options.ShouldSupportSymbolicIntegerCasts)

449 V = svalBuilder.evalCast(V, T, ExTy);

450 else

451 V = svalBuilder.evalIntegralCast(state, V, T, ExTy);

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

454 continue;

455 }

456 case CK_DerivedToBase:

457 case CK_UncheckedDerivedToBase: {

458

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

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

463 continue;

464 }

465

466 case CK_Dynamic: {

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

468

469

473

474 bool Failed = true;

475

476

478 if (std::optional V =

479 StateMgr.getStoreManager().evalBaseToDerived(val, T)) {

480 val = *V;

481 Failed = false;

482 }

483

484 if (Failed) {

485 if (T->isReferenceType()) {

486

487

489 continue;

490 } else {

491

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

493 svalBuilder.makeNullWithType(resultType));

494 }

495 } else {

496

500 currBldrCtx->blockCount());

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

502 } else

503

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

505 }

507 continue;

508 }

509 case CK_BaseToDerived: {

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

514

518 }

519

520

522 val = svalBuilder.conjureSymbolVal(

524 currBldrCtx->blockCount());

525 }

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

528 continue;

529 }

530 case CK_NullToPointer: {

531 SVal V = svalBuilder.makeNullWithType(CastE->getType());

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

534 continue;

535 }

536 case CK_NullToMemberPointer: {

537 SVal V = svalBuilder.getMemberPointer(nullptr);

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

540 continue;

541 }

542 case CK_DerivedToBaseMemberPointer:

543 case CK_BaseToDerivedMemberPointer:

544 case CK_ReinterpretMemberPointer: {

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

547 SVal CastedPTMSV =

548 svalBuilder.makePointerToMember(getBasicVals().accumCXXBase(

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

552 continue;

553 }

554

555 }

556 [[fallthrough]];

557

558 case CK_ToUnion:

559 case CK_MatrixCast:

560 case CK_VectorSplat:

561 case CK_HLSLElementwiseCast:

562 case CK_HLSLAggregateSplatCast:

563 case CK_HLSLMatrixTruncation:

564 case CK_HLSLVectorTruncation: {

568 SVal result = svalBuilder.conjureSymbolVal(

570 currBldrCtx->blockCount());

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

573 continue;

574 }

575 }

576 }

577}

578

583

586

587 const Expr *Init = CL->getInitializer();

588 SVal V = State->getSVal(CL->getInitializer(), LCtx);

589

591

592 } else {

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

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

596

597 if (CL->isGLValue())

598 V = CLLoc;

599 }

600

602}

603

607

608

609

610

611

615 return;

616 }

617

618

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

620

621 if (!VD) {

622

624 return;

625 }

626

627

630

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

634 I!=E; ++I) {

638

639

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

641

642

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

645

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

649

650

652 } else {

653

654

656 QualType Ty = InitEx->getType();

657 if (InitEx->isGLValue()) {

659 }

660

661 InitVal = svalBuilder.conjureSymbolVal(

663 currBldrCtx->blockCount());

664 }

665

666

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

671 }

672 }

673 else {

675 }

676 }

677

679}

680

683

684

685

686

687

688

689

690

691

692

693

694

695

696

697

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

700

703

705

706

707

708

709

711 return;

712 }

713

719 (void) P;

721

723 return;

724 }

726 }

727

729

731 return;

732 }

733

736

737

738

739

741

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

744 (void) Term;

745 assert(Term->isLogicalOp());

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

747

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

749 X = svalBuilder.makeIntVal(constant, B->getType());

750 }

751 else {

752

753

754

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

759

761 X = RHSVal;

762 } else {

763

764

765

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

770 }

771 }

773}

774

776 const Expr *L,

777 const Expr *R,

780 assert(L && R);

781

785 const CFGBlock *SrcBlock = nullptr;

786

787

790 auto Edge = N->getLocationAs<BlockEdge>();

791 if (!Edge.has_value()) {

792

793

794

795

796

797 continue;

798 }

799 SrcBlock = Edge->getSrc();

800 SrcState = N->getState();

801 break;

802 }

803

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

805

806

807

808 bool hasValue = false;

810

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

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

815

816

817

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

819 L = OpaqueEx->getSourceExpr();

820

821

822

824 hasValue = true;

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

826 }

827 break;

828 }

829 }

830

831 if (!hasValue)

832 V = svalBuilder.conjureSymbolVal(nullptr, getCFGElementRef(), LCtx,

833 currBldrCtx->blockCount());

834

835

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

837}

838

845 APSInt IV = Result.Val.getInt();

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

849 SVal X = svalBuilder.makeIntVal(IV);

852 X));

853 }

854

855}

856

857

862

865

868

870

872 if (Ex->getKind() == UETT_SizeOf || Ex->getKind() == UETT_DataSizeOf ||

873 Ex->getKind() == UETT_CountOf) {

874 if (T->isIncompleteType() && T->isConstantSizeType()) {

875 assert(T->isVariableArrayType() && "Unknown non-constant-sized type.");

876

877

878

879 continue;

881

882

883

884 continue;

885 }

886 }

887

890

892 state = state->BindExpr(

893 Ex, N->getLocationContext(),

896 }

897

899}

900

903

904

905

906

907

908

909

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

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

914}

915

918

921

924

926 switch (U->getOpcode()) {

927 default: {

932 break;

933 }

934 case UO_Real: {

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

936

937

939

940 break;

941 }

942

943

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

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

949 break;

950 }

951

952 case UO_Imag: {

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

954

956

957 break;

958 }

959

962 SVal X = svalBuilder.makeZeroVal(Ex->getType());

964 break;

965 }

966

967 case UO_AddrOf: {

968

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

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

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

972

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

978 break;

979 }

980 }

981

983 break;

984 }

985 case UO_Plus:

986 assert(U->isGLValue());

987 [[fallthrough]];

988 case UO_Deref:

989 case UO_Extension: {

991 break;

992 }

993

994 case UO_LNot:

995 case UO_Minus:

996 case UO_Not: {

997 assert (U->isGLValue());

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

1001

1002

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

1004

1005 if (V.isUnknownOrUndef()) {

1007 break;

1008 }

1009

1010 switch (U->getOpcode()) {

1011 default:

1012 llvm_unreachable("Invalid Opcode.");

1013 case UO_Not:

1014

1015 state = state->BindExpr(

1016 U, LCtx, svalBuilder.evalComplement(V.castAs<NonLoc>()));

1017 break;

1018 case UO_Minus:

1019

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

1021 svalBuilder.evalMinus(V.castAs<NonLoc>()));

1022 break;

1023 case UO_LNot:

1024

1025

1026

1027

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

1030 Loc X = svalBuilder.makeNullWithType(Ex->getType());

1033

1035 } else {

1038 }

1039

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

1041 break;

1042 }

1044 break;

1045 }

1046 }

1047 }

1048

1050}

1051

1055

1056 assert (U->isIncrementDecrementOp());

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

1058

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

1062

1063

1066

1070 state = N->getState();

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

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

1073

1074

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

1077

1078

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

1083

1084 continue;

1085 }

1087

1088

1090

1091

1092

1093

1096

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

1098 RHS = svalBuilder.makeArrayIndex(1);

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

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

1101 else

1103

1104

1105

1106

1107

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

1109 Result = svalBuilder.makeTruthVal(true, U->getType());

1110 else

1112

1113

1114 if (Result.isUnknown()){

1117 currBldrCtx->blockCount());

1119

1120

1121

1122

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

1126

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

1128

1129

1130 Constraint = svalBuilder.evalEQ(state, SymVal,

1131 svalBuilder.makeZeroVal(U->getType()));

1132

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

1134 assert(state);

1135 }

1136 }

1137 }

1138

1139

1140

1141 if (U->isGLValue())

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

1143 else

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

1145

1146

1151 }

1153}

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, ConstCFGElementRef Elem, QualType Ty, SValBuilder &svalBuilder, unsigned Count, const LocationContext *LCtx)

Optionally conjure and return a symbol for offset when processing Elem.

Definition ExprEngineC.cpp:29

QualType getRValueReferenceType(QualType T) const

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

static CanQualType getCanonicalType(QualType T)

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)

BinaryOperatorKind Opcode

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

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

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

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.

bool isSignedIntegerType() const

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

bool isRValueReferenceType() const

const T * castAs() const

Member-template castAs.

bool isIntegralOrEnumerationType() const

Determine whether this type is an integral or enumeration type.

bool isLValueReferenceType() const

bool isAnyComplexType() const

bool isVectorType() const

bool isFloatingType() 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

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.

Definition ExprEngineC.cpp:41

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

VisitGuardedExpr - Transfer function logic for ?, __builtin_choose.

Definition ExprEngineC.cpp:775

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

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

Definition ExprEngineC.cpp:286

BasicValueFactory & getBasicVals()

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

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

Definition ExprEngineC.cpp:681

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.

Definition ExprEngineC.cpp:916

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

VisitDeclStmt - Transfer function logic for DeclStmts.

Definition ExprEngineC.cpp:604

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

Definition ExprEngineC.cpp:258

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.

Definition ExprEngineC.cpp:197

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

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

Definition ExprEngineC.cpp:1052

ASTContext & getContext() const

getContext - Return the ASTContext associated with this analysis.

StoreManager & getStoreManager()

ConstCFGElementRef getCFGElementRef() const

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

VisitUnaryExprOrTypeTraitExpr - Transfer function for sizeof.

Definition ExprEngineC.cpp:859

ProgramStateRef escapeValues(ProgramStateRef State, ArrayRef< SVal > Vs, PointerEscapeKind K, const CallEvent *Call=nullptr) const

A simple wrapper when you only need to notify checkers of pointer-escape of some values.

CheckerManager & getCheckerManager() const

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

VisitOffsetOfExpr - Transfer function for offsetof.

Definition ExprEngineC.cpp:840

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)

Definition ExprEngineC.cpp:901

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

VisitCompoundLiteralExpr - Transfer function logic for compound literals.

Definition ExprEngineC.cpp:579

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)

MemRegion - The root abstract class for all memory regions.

void takeNodes(const ExplodedNodeSet &S)

void addNodes(const ExplodedNodeSet &S)

const ExplodedNodeSet & getResults()

DefinedOrUnknownSVal conjureSymbolVal(const void *symbolTag, ConstCFGElementRef elem, const LocationContext *LCtx, unsigned count)

Create a new symbol with a unique 'name'.

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.

IntrusiveRefCntPtr< const ProgramState > ProgramStateRef

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

CanQual< Type > CanQualType

Represents a canonical, potentially-qualified type.

bool isa(CodeGen::Address addr)

CFGBlock::ConstCFGElementRef ConstCFGElementRef

@ Result

The result type of a method or function.

const FunctionProtoType * T

U cast(CodeGen::Address addr)

@ Other

Other implicit parameter.

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