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

1

2

3

4

5

6

7

8

9

10

11

12

25#include "llvm/ADT/STLExtras.h"

26#include "llvm/ADT/Sequence.h"

27#include "llvm/Support/Casting.h"

28#include

29

30using namespace clang;

31using namespace ento;

32

40

41 state = createTemporaryRegionIfNeeded(state, LCtx, tempExpr, ME);

43}

44

45

46

50 bool AlwaysReturnsLValue;

51 [[maybe_unused]] const CXXRecordDecl *ThisRD = nullptr;

53 assert(Ctor->getDecl()->isTrivial());

54 assert(Ctor->getDecl()->isCopyOrMoveConstructor());

55 ThisVal = Ctor->getCXXThisVal();

56 ThisRD = Ctor->getDecl()->getParent();

57 AlwaysReturnsLValue = false;

58 } else {

61 OO_Equal);

64 AlwaysReturnsLValue = true;

65 }

66

69

72

73 assert(ThisRD);

74

77 const Expr *VExpr = Call.getArgExpr(0);

78

79

80

81 if (std::optional L = V.getAs<Loc>())

82 V = Pred->getState()->getSVal(*L);

83 else

84 assert(V.isUnknownOrUndef());

85

88 true);

90 evalBind(Dst, CallExpr, N, ThisVal, V, !AlwaysReturnsLValue);

91 } else {

92

93

94

95

96 Dst.Add(Pred);

97 }

98

99 PostStmt PS(CallExpr, LCtx);

100 for (ExplodedNode *N : Dst) {

102 if (AlwaysReturnsLValue)

103 State = State->BindExpr(CallExpr, LCtx, ThisVal);

104 else

107 }

108}

109

111 QualType &Ty, bool &IsArray, unsigned Idx) {

112 SValBuilder &SVB = State->getStateManager().getSValBuilder();

114

116 while (AT) {

117 Ty = AT->getElementType();

118 AT = dyn_cast(AT->getElementType());

119 }

120 LValue = State->getLValue(Ty, SVB.makeArrayIndex(Idx), LValue);

121 IsArray = true;

122 }

123

124 return LValue;

125}

126

127

128

129

130

135

139

140

141 if (CC) {

146 const auto *DS = DSCC->getDeclStmt();

147 const auto *Var = cast(DS->getSingleDecl());

148 QualType Ty = Var->getType();

149 return makeElementRegion(State, State->getLValue(Var, LCtx), Ty,

151 }

155 const auto *Init = ICC->getCXXCtorInitializer();

158 SVal ThisVal = State->getSVal(ThisPtr);

159 if (Init->isBaseInitializer()) {

162 Init->getBaseClass()->getAsCXXRecordDecl();

163 const auto *BaseReg =

164 MRMgr.getCXXBaseObjectRegion(BaseClass, ThisReg,

165 Init->isBaseVirtual());

166 return SVB.makeLoc(BaseReg);

167 }

168 if (Init->isDelegatingInitializer())

169 return ThisVal;

170

172 SVal FieldVal;

173 if (Init->isIndirectMemberInitializer()) {

174 Field = Init->getIndirectMember();

175 FieldVal = State->getLValue(Init->getIndirectMember(), ThisVal);

176 } else {

177 Field = Init->getMember();

178 FieldVal = State->getLValue(Init->getMember(), ThisVal);

179 }

180

181 QualType Ty = Field->getType();

182 return makeElementRegion(State, FieldVal, Ty, CallOpts.IsArrayCtorOrDtor,

183 Idx);

184 }

186 if (AMgr.getAnalyzerOptions().MayInlineCXXAllocator) {

188 const auto *NE = NECC->getCXXNewExpr();

191 dyn_cast_or_null(V.getAsRegion())) {

192 if (NE->isArray()) {

194

195 auto Ty = NE->getType()->getPointeeType();

196 while (const auto *AT = getContext().getAsArrayType(Ty))

197 Ty = AT->getElementType();

198

199 auto R = MRMgr.getElementRegion(Ty, svalBuilder.makeArrayIndex(Idx),

201

203 }

204 return V;

205 }

206

207

208 }

209 break;

210 }

213

214

215

220 if (!RTC) {

221

222

223

224 break;

225 }

227

228

229 CallerLCtx = CallerLCtx->getParent();

231 }

232

237 RTC->getConstructionContext(), CallOpts);

238 } else {

239

240

241

242

243

244

245

246

247

249

250

251 static const int TopLevelSymRegionTag = 0;

252 const Expr *RetE = RCC->getReturnStmt()->getRetValue();

253 assert(RetE && "Void returns should not have a construction context");

257 SFC, RegionTy, currBldrCtx->blockCount());

258 }

259 llvm_unreachable("Unhandled return value construction context!");

260 }

262 assert(AMgr.getAnalyzerOptions().ShouldElideConstructors);

264

265

266

267

268

269

270

271

274

276 TCC->getConstructorAfterElision(), State, BldrCtx, LCtx,

277 TCC->getConstructionContextAfterElision(), CallOpts);

278

279

280

281

283 return V;

284

285

286

287 CallOpts = PreElideCallOpts;

289 [[fallthrough]];

290 }

294

296 if (MTE) {

300 if (!VD->getType()->isReferenceType()) {

301

302

303

304

305

307 }

308

311 MRMgr.getCXXStaticLifetimeExtendedObjectRegion(E, VD));

312

314 MRMgr.getCXXLifetimeExtendedObjectRegion(E, VD, LCtx));

315 }

317 }

318

320 }

323

325

327 MRMgr.getCXXTempObjectRegion(LCC->getInitializer(), LCtx));

328

329 const auto *CE = dyn_cast_or_null(E);

332 Base = State->getLValue(E->getType(), svalBuilder.makeArrayIndex(Idx),

334 }

335

337 }

339

341

343 const Expr *E = ACC->getCallLikeExpr();

344 unsigned Idx = ACC->getIndex();

345

347 auto getArgLoc = [&](CallEventRef<> Caller) -> std::optional {

349 Caller->getCalleeStackFrame(BldrCtx->blockCount());

350

351

352 if (!FutureSFC)

353 return std::nullopt;

354

355

356

357

358 const Decl *CalleeD = FutureSFC->getDecl();

359

360

362 return std::nullopt;

363

364

365

366

368 *Caller->getAdjustedParameterIndex(Idx), BldrCtx->blockCount());

369 if (!TVR)

370 return std::nullopt;

371

373 };

374

375 if (const auto *CE = dyn_cast(E)) {

378 if (std::optional V = getArgLoc(Caller))

379 return *V;

380 else

381 break;

382 } else if (const auto *CCE = dyn_cast(E)) {

383

384

387 if (std::optional V = getArgLoc(Caller))

388 return *V;

389 else

390 break;

391 } else if (const auto *ME = dyn_cast(E)) {

394 if (std::optional V = getArgLoc(Caller))

395 return *V;

396 else

397 break;

398 }

399 }

400 }

401 }

402

403

404

407}

408

413

414

415 return State;

416 }

417

418

419

420 assert(CC && "Computed target region without construction context?");

425 return addObjectUnderConstruction(State, DSCC->getDeclStmt(), LCtx, V);

426 }

430 const auto *Init = ICC->getCXXCtorInitializer();

431

432 assert(Init->isAnyMemberInitializer() &&

433 "Base and delegating initializers should have been handled by"

434 "computeObjectUnderConstruction()");

435 return addObjectUnderConstruction(State, Init, LCtx, V);

436 }

438 return State;

439 }

444 if (!CallerLCtx) {

445

446 return State;

447 }

448

451 assert(RTC && "Could not have had a target region without it");

453

454

455 CallerLCtx = CallerLCtx->getParent();

457 }

458

461 RTC->getConstructionContext(), CallOpts);

462 }

464 assert(AMgr.getAnalyzerOptions().ShouldElideConstructors);

468 V, TCC->getConstructorAfterElision(), State, LCtx,

469 TCC->getConstructionContextAfterElision(), CallOpts);

470

471

472 State = addObjectUnderConstruction(

473 State, TCC->getConstructorAfterElision(), LCtx, V);

474

475

476 if (const auto *BTE = TCC->getCXXBindTemporaryExpr())

477 State = elideDestructor(State, BTE, LCtx);

478

479

480

481 if (const auto *MTE = TCC->getMaterializedTemporaryExpr())

482 State = addObjectUnderConstruction(State, MTE, LCtx, V);

483

484 return State;

485 }

486

487

488 [[fallthrough]];

489 }

492 if (const auto *BTE = TCC->getCXXBindTemporaryExpr())

493 State = addObjectUnderConstruction(State, BTE, LCtx, V);

494

495 if (const auto *MTE = TCC->getMaterializedTemporaryExpr())

496 State = addObjectUnderConstruction(State, MTE, LCtx, V);

497

498 return State;

499 }

502

503

504

505 if (const auto *EL = dyn_cast_or_null(V.getAsRegion()))

507

508 return addObjectUnderConstruction(

509 State, {LCC->getLambdaExpr(), LCC->getIndex()}, LCtx, V);

510 }

513 if (const auto *BTE = ACC->getCXXBindTemporaryExpr())

514 State = addObjectUnderConstruction(State, BTE, LCtx, V);

515

516 return addObjectUnderConstruction(

517 State, {ACC->getCallLikeExpr(), ACC->getIndex()}, LCtx, V);

518 }

519 }

520 llvm_unreachable("Unhandled construction context!");

521}

522

530

531

532

533

535 const auto *Ctor =

537

538 const auto *SourceArrayRegion =

539 cast(State->getSVal(SourceArray, LCtx).getAsRegion());

541 MRMgr.getElementRegion(Ctor->getType(), Idx, SourceArrayRegion, Ctx);

542

543 return State->BindExpr(Ctor->getArg(0), LCtx,

545}

546

547void ExprEngine::handleConstructor(const Expr *E,

550 const auto *CE = dyn_cast(E);

551 const auto *CIE = dyn_cast(E);

552 assert(CE || CIE);

553

556

557 SVal Target = UnknownVal();

558

559 if (CE) {

560 if (std::optional ElidedTarget =

562

563

564

565 Target = *ElidedTarget;

566 StmtNodeBuilder Bldr(Pred, destNodes, *currBldrCtx);

567 State = finishObjectConstruction(State, CE, LCtx);

568 if (auto L = Target.getAs())

569 State = State->BindExpr(CE, LCtx, State->getSVal(*L, CE->getType()));

571 return;

572 }

573 }

574

575 EvalCallOptions CallOpts;

578 const ConstructionContext *CC = C ? C->getConstructionContext() : nullptr;

579

581 CE ? CE->getConstructionKind() : CIE->getConstructionKind();

582 switch (CK) {

584

585 assert(CE && !CIE && "A complete constructor is inherited?!");

586

587

588

590

591 unsigned Idx = 0;

592 if (CE->getType()->isArrayType() || AILE) {

593

594 auto isZeroSizeArray = [&] {

596

597 if (const auto *CAT = dyn_cast(CE->getType()))

599 else if (AILE)

601

602 return Size == 0;

603 };

604

605

606 if (isZeroSizeArray()) {

607 StmtNodeBuilder Bldr(Pred, destNodes, *currBldrCtx);

608 static SimpleProgramPointTag T{"ExprEngine",

609 "Skipping 0 size array construction"};

611 return;

612 }

613

615 State = setIndexOfElementToConstruct(State, CE, LCtx, Idx + 1);

616 }

617

618 if (AILE) {

619

621 State = setPendingInitLoop(

622 State, CE, LCtx,

623 getContext().getArrayInitLoopExprElementCount(AILE));

624

626 State, AILE, LCtx, svalBuilder.makeArrayIndex(Idx));

627 }

628

629

631 CE, State, currBldrCtx, LCtx, CC, CallOpts, Idx);

632 break;

633 }

635

636

637 const auto *OuterCtor = dyn_cast_or_null(

639 assert(

640 (!OuterCtor ||

643 ("This virtual base should have already been initialized by "

644 "the most derived class!"));

645 (void)OuterCtor;

646 [[fallthrough]];

647 }

649

650

651

652

653

654

655

656

657

658

659

660 if (isa_and_nonnull<InitListExpr, CXXParenListInitExpr>(

663 Target = loc::MemRegionVal(MRMgr.getCXXTempObjectRegion(E, LCtx));

665 break;

666 }

667 [[fallthrough]];

672 SVal ThisVal = State->getSVal(ThisPtr);

673

676 } else {

677

679 SVal BaseVal =

682 }

683 break;

684 }

685 }

686

687 if (State != Pred->getState()) {

688 static SimpleProgramPointTag T("ExprEngine",

689 "Prepare for object construction");

690 ExplodedNodeSet DstPrepare;

691 StmtNodeBuilder BldrPrepare(Pred, DstPrepare, *currBldrCtx);

693 assert(DstPrepare.size() <= 1);

694 if (DstPrepare.size() == 0)

695 return;

696 Pred = *BldrPrepare.begin();

697 }

698

699 const MemRegion *TargetRegion = Target.getAsRegion();

701 CallEventRef<> Call =

706

707 ExplodedNodeSet DstPreVisit;

709

710 ExplodedNodeSet PreInitialized;

711 if (CE) {

712

713 StmtNodeBuilder Bldr(DstPreVisit, PreInitialized, *currBldrCtx);

714 for (ExplodedNode *N : DstPreVisit) {

716 if (CE->requiresZeroInitialization()) {

717

718

719

720

721

722

723

724

725

726

727

728

729 const CXXRecordDecl *TargetHeldRecord =

730 dyn_cast_or_null(CE->getType()->getAsRecordDecl());

731

732 if (!TargetHeldRecord || !TargetHeldRecord->isEmpty())

733 State = State->bindDefaultZero(Target, LCtx);

734 }

735

736 Bldr.generateNode(CE, N, State, nullptr,

738 }

739 } else {

740 PreInitialized = DstPreVisit;

741 }

742

743 ExplodedNodeSet DstPreCall;

745 *Call, *this);

746

747 ExplodedNodeSet DstEvaluated;

748

749 if (CE && CE->getConstructor()->isTrivial() &&

750 CE->getConstructor()->isCopyOrMoveConstructor() &&

752 StmtNodeBuilder Bldr(DstPreCall, DstEvaluated, *currBldrCtx);

753

754 for (ExplodedNode *N : DstPreCall)

755 performTrivialCopy(Bldr, N, *Call);

756

757 } else {

758 for (ExplodedNode *N : DstPreCall)

760 CallOpts);

761 }

762

763

764

765

766

767

768

769

770 ExplodedNodeSet DstEvaluatedPostProcessed;

771 StmtNodeBuilder Bldr(DstEvaluated, DstEvaluatedPostProcessed, *currBldrCtx);

774 if (llvm::isa_and_nonnull<CXXTempObjectRegion,

775 CXXLifetimeExtendedObjectRegion>(TargetRegion) &&

777 ->getParent()

778 ->isAnyDestructorNoReturn()) {

779

780

781

782

783

784

785

786

787 assert(!DstEvaluated.empty() &&

788 "We should not have inlined this constructor!");

789

790 for (ExplodedNode *N : DstEvaluated) {

792 }

793

794

795

796

797 return;

798 }

799 }

800

801 ExplodedNodeSet DstPostArgumentCleanup;

802 for (ExplodedNode *I : DstEvaluatedPostProcessed)

803 finishArgumentConstruction(DstPostArgumentCleanup, I, *Call);

804

805

806

807 ExplodedNodeSet DstPostCall;

809 DstPostArgumentCleanup,

810 *Call, *this);

812}

813

817 handleConstructor(CE, Pred, Dst);

818}

819

823 handleConstructor(CE, Pred, Dst);

824}

825

828 const Stmt *S,

829 bool IsBaseDtor,

833 assert(S && "A destructor without a trigger!");

836

838 assert(RecordDecl && "Only CXXRecordDecls should have destructors");

840

841

842 if (!DtorDecl) {

843

844

846

849 NodeBuilder Bldr(Pred, Dst, *currBldrCtx);

851 return;

852 }

853

854 if (!Dest) {

855

856

857

858

859

861 if (const Expr *E = dyn_cast_or_null(S)) {

863 } else {

865 NodeBuilder Bldr(Pred, Dst, *currBldrCtx);

868 return;

869 }

870 }

871

874 DtorDecl, S, Dest, IsBaseDtor, State, LCtx, getCFGElementRef());

875

877 Call->getSourceRange().getBegin(),

878 "Error evaluating destructor");

879

882 *Call, *this);

883

885 StmtNodeBuilder Bldr(DstPreCall, DstInvalidated, *currBldrCtx);

888

890 *Call, *this);

891}

892

900 "Error evaluating New Allocator Call");

904

907 *Call, *this);

908

910 StmtNodeBuilder CallBldr(DstPreCall, DstPostCall, *currBldrCtx);

912

913

914

915

916

917

918

919

921 }

922

923

924

925

927 StmtNodeBuilder ValueBldr(DstPostCall, DstPostValue, *currBldrCtx);

929

930

931

932

933

934

935

936

937

939 SVal RetVal = State->getSVal(CNE, LCtx);

940

941

942

943

944 State = State->bindDefaultInitial(RetVal, UndefinedVal{}, LCtx);

945

946

947

948

949

950

951

952

956 if (!ProtoType->isNothrow())

958 }

959

961 CNE, I, addObjectUnderConstruction(State, CNE, LCtx, RetVal));

962 }

963

966 DstPostValue, *Call, *this);

967 for (ExplodedNode *I : DstPostPostCallCallback) {

969 }

970}

971

974

975

976

977

978

979 unsigned blockCount = currBldrCtx->blockCount();

983

984 bool IsStandardGlobalOpNewFunction =

986

988

989

990 if (AMgr.getAnalyzerOptions().MayInlineCXXAllocator) {

992 State = finishObjectConstruction(State, CNE, LCtx);

993 }

994

995

996

997

999 if (IsStandardGlobalOpNewFunction)

1000 symVal = svalBuilder.getConjuredHeapSymbolVal(getCFGElementRef(), LCtx,

1001 CNE->getType(), blockCount);

1002 else

1003 symVal = svalBuilder.conjureSymbolVal(

1004 nullptr, getCFGElementRef(), LCtx, blockCount);

1005 }

1006

1010

1011 if (!AMgr.getAnalyzerOptions().MayInlineCXXAllocator) {

1012

1013

1014

1015

1016 State = Call->invalidateRegions(blockCount, State);

1017 if (!State)

1018 return;

1019

1020

1021

1022

1023

1024

1025

1026

1028 if (!ProtoType->isNothrow())

1030 State = State->assume(*dSymVal, true);

1031 }

1032

1034

1036

1038

1039 if (const auto *NewReg = cast_or_null(symVal.getAsRegion())) {

1040

1041

1042

1044 bool isInitList =

1045 isa_and_nonnull<InitListExpr, CXXParenListInitExpr>(Init);

1046

1050 MRMgr.getElementRegion(ObjTy, svalBuilder.makeArrayIndex(0), NewReg,

1051 svalBuilder.getContext());

1053

1054

1055

1056 if (isInitList) {

1059

1060 SVal V = State->getSVal(Init, LCtx);

1062 evalBind(evaluated, CNE, Pred, Result, V, true);

1063

1066

1067 Pred = *evaluated.begin();

1069 }

1070 }

1071

1074 return;

1075 }

1076

1077

1078

1079

1080

1082

1084 Result = svalBuilder.evalCast(PlacementLoc, CNE->getType(),

1086 }

1087

1088

1089 State = State->BindExpr(CNE, LCtx, Result);

1091 if (!NewN)

1092 return;

1093

1094

1095

1100 evalBind(Dst, CNE, NewN, Result, State->getSVal(Init, LCtx),

1101 IsStandardGlobalOpNewFunction);

1102 }

1103 }

1104}

1105

1108

1112

1116

1117 if (AMgr.getAnalyzerOptions().MayInlineCXXAllocator) {

1118 StmtNodeBuilder Bldr(DstPreCall, DstPostCall, *currBldrCtx);

1120

1121

1122

1123

1125 }

1126 } else {

1127 DstPostCall = DstPreCall;

1128 }

1130}

1131

1135 if (!VD) {

1136 Dst.Add(Pred);

1137 return;

1138 }

1139

1142 currBldrCtx->blockCount());

1144 state = state->bindLoc(state->getLValue(VD, LCtx), V, LCtx);

1145

1148}

1149

1153

1154

1157 svalBuilder.getRegionManager().getCXXThisRegion(

1159 LCtx);

1160

1163 Bldr.generateNode(TE, Pred, state->BindExpr(TE, LCtx, V));

1164}

1165

1169

1170

1171 const MemRegion *R = svalBuilder.getRegionManager().getCXXTempObjectRegion(

1172 LE, LocCtxt);

1174

1176

1177

1178

1179 for (auto const [Idx, FieldForCapture, InitExpr] :

1180 llvm::zip(llvm::seq(0, -1), LE->getLambdaClass()->fields(),

1181 LE->capture_inits())) {

1182 SVal FieldLoc = State->getLValue(FieldForCapture, V);

1183

1184 SVal InitVal;

1185 if (!FieldForCapture->hasCapturedVLAType()) {

1186 assert(InitExpr && "Capture missing initialization expression");

1187

1188

1189

1190

1191

1192 const auto FTy = FieldForCapture->getType();

1193 if (FTy->isConstantArrayType() &&

1194 getContext().getConstantArrayElementCount(

1195 getContext().getAsConstantArrayType(FTy)) == 0)

1196 continue;

1197

1198

1199

1200

1201 if (const auto OUC =

1203 InitVal = State->getSVal(OUC->getAsRegion());

1204

1205 State = finishObjectConstruction(State, {LE, Idx}, LocCtxt);

1206 } else

1207 InitVal = State->getSVal(InitExpr, LocCtxt);

1208

1209 } else {

1210

1212 "VLA capture by value is a compile time error!");

1213

1214

1215

1216

1217 Expr *SizeExpr = FieldForCapture->getCapturedVLAType()->getSizeExpr();

1218 InitVal = State->getSVal(SizeExpr, LocCtxt);

1219 }

1220

1221 State = State->bindLoc(FieldLoc, InitVal, LocCtxt);

1222 }

1223

1224

1225

1226

1227 SVal LambdaRVal = State->getSVal(R);

1228

1231

1233 State->BindExpr(LE, LocCtxt, LambdaRVal),

1235

1236

1238}

1239

1244

1246 StmtNodeBuilder Bldr(CheckerPreStmt, EvalSet, *currBldrCtx);

1247

1250 Visit(Attr->getAssumption()->IgnoreParens(), N, EvalSet);

1251 }

1252 }

1253

1255}

Defines the clang::ASTContext interface.

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

static ProgramStateRef bindRequiredArrayElementToEnvironment(ProgramStateRef State, const ArrayInitLoopExpr *AILE, const LocationContext *LCtx, NonLoc Idx)

Definition ExprEngineCXX.cpp:524

Defines the PrettyStackTraceEntry class, which is used to make crashes give more contextual informati...

Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...

QualType getPointerType(QualType T) const

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

const ArrayType * getAsArrayType(QualType T) const

Type Query functions.

uint64_t getConstantArrayElementCount(const ConstantArrayType *CA) const

Return number of constant array elements.

uint64_t getArrayInitLoopExprElementCount(const ArrayInitLoopExpr *AILE) const

Return number of elements initialized in an ArrayInitLoopExpr.

CFG::BuildOptions & getCFGBuildOptions()

Represents a loop initializing the elements of an array.

OpaqueValueExpr * getCommonExpr() const

Get the common subexpression shared by all initializations (the source array).

Attr - This represents one attribute.

Represents an attribute applied to a statement.

ArrayRef< const Attr * > getAttrs() const

Represents a function call that returns a C++ object by value.

std::optional< T > getAs() const

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

CXXCatchStmt - This represents a C++ catch block.

VarDecl * getExceptionDecl() const

Represents a call to a C++ constructor.

Represents a delete expression for memory deallocation and destructor calls, e.g.

Represents a C++ destructor within a class.

Represents a call to an inherited base class constructor from an inheriting constructor.

Represents a static or instance method of a struct/union/class.

Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)".

Expr * getPlacementArg(unsigned I)

SourceLocation getBeginLoc() const

FunctionDecl * getOperatorNew() const

Expr * getInitializer()

The initializer of this new-expression.

Represents a C++ struct/union/class.

bool isEmpty() const

Determine whether this is an empty class in the sense of (C++11 [meta.unary.prop]).

Represents the this expression in C++.

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

ConstructionContext's subclasses describe different ways of constructing an object in C++.

virtual const ArrayInitLoopExpr * getArrayInitLoop() const

@ CXX17ElidedCopyVariableKind

@ ElidedTemporaryObjectKind

@ SimpleTemporaryObjectKind

@ CXX17ElidedCopyConstructorInitializerKind

@ SimpleConstructorInitializerKind

@ SimpleReturnedValueKind

@ CXX17ElidedCopyReturnedValueKind

DeclContext * getParent()

getParent - Returns the containing DeclContext.

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

This represents one expression.

Expr * IgnoreParens() LLVM_READONLY

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

Represents a function declaration or definition.

bool isReplaceableGlobalAllocationFunction(UnsignedOrNone *AlignmentParam=nullptr, bool *IsNothrow=nullptr) const

Determines whether this function is one of the replaceable global allocation functions: void *operato...

bool isReservedGlobalPlacementOperator() const

Determines whether this operator new or delete is one of the reserved global placement operators: voi...

Represents a prototype with parameter type info, e.g.

A C++ lambda expression, which produces a function object (of unspecified type) that can be invoked l...

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

const Decl * getDecl() const

const ParentMap & getParentMap() const

LLVM_ATTRIBUTE_RETURNS_NONNULL AnalysisDeclContext * getAnalysisDeclContext() const

const LocationContext * getParent() const

It might return null.

const StackFrameContext * getStackFrame() const

Represents a prvalue temporary that is written into memory so that a reference can bind to it.

StorageDuration getStorageDuration() const

Retrieve the storage duration for the materialized temporary.

Expr * getSubExpr() const

Retrieve the temporary-generating subexpression whose value will be materialized into a glvalue.

ValueDecl * getExtendingDecl()

Get the declaration which triggered the lifetime-extension of this temporary, if any.

Expr * getSourceExpr() const

The source expression of an opaque value expression is the expression which originally generated the ...

Stmt * getParent(Stmt *) const

Represents a program point just after an implicit call event.

If a crash happens while one of these objects are live, the message is printed out along with the spe...

ProgramPoint withTag(const ProgramPointTag *tag) const

Create a new ProgramPoint object that is the same as the original except for using the specified tag ...

A (possibly-)qualified type.

Represents a struct/union/class.

It represents a stack frame of the call stack (based on CallEvent).

unsigned getIndex() const

const Stmt * getCallSite() const

const CFGBlock * getCallSiteBlock() const

Stmt - This represents one statement.

SourceLocation getEndLoc() const LLVM_READONLY

CXXRecordDecl * getAsCXXRecordDecl() const

Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...

QualType getPointeeType() const

If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.

const T * getAs() const

Member-template getAs'.

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.

Represents a call to a C++ constructor.

Manages the lifetime of CallEvent objects.

CallEventRef< CXXDestructorCall > getCXXDestructorCall(const CXXDestructorDecl *DD, const Stmt *Trigger, const MemRegion *Target, bool IsBase, ProgramStateRef State, const LocationContext *LCtx, CFGBlock::ConstCFGElementRef ElemRef)

CallEventRef< CXXDeallocatorCall > getCXXDeallocatorCall(const CXXDeleteExpr *E, ProgramStateRef State, const LocationContext *LCtx, CFGBlock::ConstCFGElementRef ElemRef)

CallEventRef getSimpleCall(const CallExpr *E, ProgramStateRef State, const LocationContext *LCtx, CFGBlock::ConstCFGElementRef ElemRef)

CallEventRef< ObjCMethodCall > getObjCMethodCall(const ObjCMessageExpr *E, ProgramStateRef State, const LocationContext *LCtx, CFGBlock::ConstCFGElementRef ElemRef)

CallEventRef< CXXAllocatorCall > getCXXAllocatorCall(const CXXNewExpr *E, ProgramStateRef State, const LocationContext *LCtx, CFGBlock::ConstCFGElementRef ElemRef)

CallEventRef< CXXConstructorCall > getCXXConstructorCall(const CXXConstructExpr *E, const MemRegion *Target, ProgramStateRef State, const LocationContext *LCtx, CFGBlock::ConstCFGElementRef ElemRef)

CallEventRef< CXXInheritedConstructorCall > getCXXInheritedConstructorCall(const CXXInheritedCtorInitExpr *E, const MemRegion *Target, ProgramStateRef State, const LocationContext *LCtx, CFGBlock::ConstCFGElementRef ElemRef)

Represents an abstract call to a function or method along a particular path.

static bool isVariadic(const Decl *D)

Returns true if the given decl is known to be variadic.

void runCheckersForPreCall(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const CallEvent &Call, ExprEngine &Eng)

Run checkers for pre-visiting obj-c messages.

void runCheckersForEvalCall(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const CallEvent &CE, ExprEngine &Eng, const EvalCallOptions &CallOpts)

Run checkers for evaluating a call.

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

Run checkers for post-visiting Stmts.

void runCheckersForNewAllocator(const CXXAllocatorCall &Call, ExplodedNodeSet &Dst, ExplodedNode *Pred, ExprEngine &Eng, bool wasInlined=false)

Run checkers between C++ operator new and constructor calls.

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

Run checkers for pre-visiting Stmts.

void runCheckersForPostCall(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const CallEvent &Call, ExprEngine &Eng, bool wasInlined=false)

Run checkers for post-visiting obj-c messages.

ElementRegion is used to represent both array elements and casts.

void Add(ExplodedNode *N)

const ProgramStateRef & getState() const

ProgramPoint getLocation() const

getLocation - Returns the edge associated with the given node.

const LocationContext * getLocationContext() const

ProgramStateManager & getStateManager()

std::pair< ProgramStateRef, SVal > handleConstructionContext(const Expr *E, ProgramStateRef State, const NodeBuilderContext *BldrCtx, const LocationContext *LCtx, const ConstructionContext *CC, EvalCallOptions &CallOpts, unsigned Idx=0)

A convenient wrapper around computeObjectUnderConstruction and updateObjectsUnderConstruction.

void VisitCXXDestructor(QualType ObjectType, const MemRegion *Dest, const Stmt *S, bool IsBaseDtor, ExplodedNode *Pred, ExplodedNodeSet &Dst, EvalCallOptions &Options)

Definition ExprEngineCXX.cpp:826

const CoreEngine & getCoreEngine() const

void VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred, ExplodedNodeSet &Dst)

Definition ExprEngineCXX.cpp:972

void VisitLambdaExpr(const LambdaExpr *LE, ExplodedNode *Pred, ExplodedNodeSet &Dst)

VisitLambdaExpr - Transfer function logic for LambdaExprs.

Definition ExprEngineCXX.cpp:1166

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

CFGElement getCurrentCFGElement()

Return the CFG element corresponding to the worklist element that is currently being processed by Exp...

SVal computeObjectUnderConstruction(const Expr *E, ProgramStateRef State, const NodeBuilderContext *BldrCtx, const LocationContext *LCtx, const ConstructionContext *CC, EvalCallOptions &CallOpts, unsigned Idx=0)

Find location of the object that is being constructed by a given constructor.

Definition ExprEngineCXX.cpp:131

static std::optional< unsigned > getIndexOfElementToConstruct(ProgramStateRef State, const CXXConstructExpr *E, const LocationContext *LCtx)

Retreives which element is being constructed in a non-POD type array.

ASTContext & getContext() const

getContext - Return the ASTContext associated with this analysis.

StoreManager & getStoreManager()

void VisitCXXNewAllocatorCall(const CXXNewExpr *CNE, ExplodedNode *Pred, ExplodedNodeSet &Dst)

Definition ExprEngineCXX.cpp:893

void CreateCXXTemporaryObject(const MaterializeTemporaryExpr *ME, ExplodedNode *Pred, ExplodedNodeSet &Dst)

Create a C++ temporary object for an rvalue.

Definition ExprEngineCXX.cpp:33

ConstCFGElementRef getCFGElementRef() const

CheckerManager & getCheckerManager() const

ProgramStateRef bindReturnValue(const CallEvent &Call, const LocationContext *LCtx, ProgramStateRef State)

Create a new state in which the call return value is binded to the call origin expression.

void VisitCXXThisExpr(const CXXThisExpr *TE, ExplodedNode *Pred, ExplodedNodeSet &Dst)

Definition ExprEngineCXX.cpp:1150

void VisitCXXDeleteExpr(const CXXDeleteExpr *CDE, ExplodedNode *Pred, ExplodedNodeSet &Dst)

Definition ExprEngineCXX.cpp:1106

void VisitCXXConstructExpr(const CXXConstructExpr *E, ExplodedNode *Pred, ExplodedNodeSet &Dst)

Definition ExprEngineCXX.cpp:814

void VisitCXXInheritedCtorInitExpr(const CXXInheritedCtorInitExpr *E, ExplodedNode *Pred, ExplodedNodeSet &Dst)

Definition ExprEngineCXX.cpp:820

void Visit(const Stmt *S, ExplodedNode *Pred, ExplodedNodeSet &Dst)

Visit - Transfer function logic for all statements.

void defaultEvalCall(NodeBuilder &B, ExplodedNode *Pred, const CallEvent &Call, const EvalCallOptions &CallOpts={})

Default implementation of call evaluation.

void VisitCXXCatchStmt(const CXXCatchStmt *CS, ExplodedNode *Pred, ExplodedNodeSet &Dst)

Definition ExprEngineCXX.cpp:1132

SValBuilder & getSValBuilder()

ProgramStateRef updateObjectsUnderConstruction(SVal V, const Expr *E, ProgramStateRef State, const LocationContext *LCtx, const ConstructionContext *CC, const EvalCallOptions &CallOpts)

Update the program state with all the path-sensitive information that's necessary to perform construc...

Definition ExprEngineCXX.cpp:409

void VisitAttributedStmt(const AttributedStmt *A, ExplodedNode *Pred, ExplodedNodeSet &Dst)

VisitAttributedStmt - Transfer function logic for AttributedStmt.

Definition ExprEngineCXX.cpp:1240

static std::optional< unsigned > getPendingInitLoop(ProgramStateRef State, const CXXConstructExpr *E, const LocationContext *LCtx)

Retreives the size of the array in the pending ArrayInitLoopExpr.

const ElementRegion * getElementRegion(QualType elementType, NonLoc Idx, const SubRegion *superRegion, const ASTContext &Ctx)

getElementRegion - Retrieve the memory region associated with the associated element type,...

MemRegion - The root abstract class for all memory regions.

unsigned blockCount() const

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

This is the simplest builder which generates nodes in the ExplodedGraph.

ExplodedNode * generateNode(const ProgramPoint &PP, ProgramStateRef State, ExplodedNode *Pred)

Generates a node in the ExplodedGraph.

void takeNodes(const ExplodedNodeSet &S)

ExplodedNode * generateSink(const ProgramPoint &PP, ProgramStateRef State, ExplodedNode *Pred)

Generates a sink in the ExplodedGraph.

void addNodes(const ExplodedNodeSet &S)

const ExplodedNodeSet & getResults()

SValBuilder & getSValBuilder()

CallEventManager & getCallEventManager()

MemRegionManager & getRegionManager()

ProgramStateManager & getStateManager()

NonLoc makeArrayIndex(uint64_t idx)

ASTContext & getContext()

loc::MemRegionVal makeLoc(SymbolRef sym)

loc::MemRegionVal getCXXThis(const CXXMethodDecl *D, const StackFrameContext *SFC)

Return a memory region for the 'this' object reference.

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.

std::optional< T > getAs() const

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

const MemRegion * getAsRegion() 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)

SVal evalDerivedToBase(SVal Derived, const CastExpr *Cast)

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

SubRegion - A region that subsets another larger region.

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

IntrusiveRefCntPtr< const ProgramState > ProgramStateRef

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

bool isa(CodeGen::Address addr)

StorageDuration

The storage duration for an object (per C++ [basic.stc]).

@ SD_Thread

Thread storage duration.

@ SD_Static

Static storage duration.

@ SD_FullExpression

Full-expression storage duration (for temporaries).

@ Result

The result type of a method or function.

const FunctionProtoType * T

auto getSpecificAttrs(const Container &container)

U cast(CodeGen::Address addr)

Expr * extractElementInitializerFromNestedAILE(const ArrayInitLoopExpr *AILE)

Hints for figuring out of a call should be inlined during evalCall().

bool IsTemporaryLifetimeExtendedViaAggregate

This call is a constructor for a temporary that is lifetime-extended by binding it to a reference-typ...

bool IsTemporaryCtorOrDtor

This call is a constructor or a destructor of a temporary value.

bool IsArrayCtorOrDtor

This call is a constructor or a destructor for a single element within an array, a part of array cons...

bool IsElidableCtorThatHasNotBeenElided

This call is a pre-C++17 elidable constructor that we failed to elide because we failed to compute th...

bool IsCtorOrDtorWithImproperlyModeledTargetRegion

This call is a constructor or a destructor for which we do not currently compute the this-region corr...