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

1

2

3

4

5

6

7

8

9

10

11

12

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

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

25#include

26

27using namespace clang;

28using namespace ento;

29

37

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

40}

41

42

43

47 bool AlwaysReturnsLValue;

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

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

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

52 ThisVal = Ctor->getCXXThisVal();

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

54 AlwaysReturnsLValue = false;

55 } else {

56 assert(cast(Call.getDecl())->isTrivial());

57 assert(cast(Call.getDecl())->getOverloadedOperator() ==

58 OO_Equal);

59 ThisVal = cast(Call).getCXXThisVal();

60 ThisRD = cast(Call.getDecl())->getParent();

61 AlwaysReturnsLValue = true;

62 }

63

66

69

70 assert(ThisRD);

72

73

74

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

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

77 else

78 assert(V.isUnknownOrUndef());

79 evalBind(Dst, CallExpr, Pred, ThisVal, V, true);

80

84 if (AlwaysReturnsLValue)

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

86 else

89 }

90}

91

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

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

96

98 while (AT) {

99 Ty = AT->getElementType();

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

101 }

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

103 IsArray = true;

104 }

105

106 return LValue;

107}

108

109

110

111

112

117

121

122

123 if (CC) {

127 const auto *DSCC = cast(CC);

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

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

130 QualType Ty = Var->getType();

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

133 }

136 const auto *ICC = cast(CC);

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

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

141 if (Init->isBaseInitializer()) {

142 const auto *ThisReg = cast(ThisVal.getAsRegion());

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

145 const auto *BaseReg =

147 Init->isBaseVirtual());

148 return SVB.makeLoc(BaseReg);

149 }

150 if (Init->isDelegatingInitializer())

151 return ThisVal;

152

154 SVal FieldVal;

155 if (Init->isIndirectMemberInitializer()) {

156 Field = Init->getIndirectMember();

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

158 } else {

159 Field = Init->getMember();

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

161 }

162

163 QualType Ty = Field->getType();

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

165 Idx);

166 }

169 const auto *NECC = cast(CC);

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

173 dyn_cast_or_null(V.getAsRegion())) {

174 if (NE->isArray()) {

176

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

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

179 Ty = AT->getElementType();

180

183

185 }

186 return V;

187 }

188

189

190 }

191 break;

192 }

195

196

197

202 if (!RTC) {

203

204

205

206 break;

207 }

208 if (isa(CallerLCtx)) {

209

210

211 CallerLCtx = CallerLCtx->getParent();

212 assert(!isa(CallerLCtx));

213 }

214

218 cast(SFC->getCallSite()), State, &CallerBldrCtx, CallerLCtx,

219 RTC->getConstructionContext(), CallOpts);

220 } else {

221

222

223

224

225

226

227

228

229

230 const auto *RCC = cast(CC);

231

232

233 static const int TopLevelSymRegionTag = 0;

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

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

238 return SVB.conjureSymbolVal(&TopLevelSymRegionTag, RetE, SFC, RegionTy,

240 }

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

242 }

245 const auto *TCC = cast(CC);

246

247

248

249

250

251

252

253

256

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

259 TCC->getConstructionContextAfterElision(), CallOpts);

260

261

262

263

265 return V;

266

267

268

269 CallOpts = PreElideCallOpts;

271 [[fallthrough]];

272 }

274 const auto *TCC = cast(CC);

276

278 if (MTE) {

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

283

284

285

286

287

289 }

290

294

297 }

299 }

300

302 }

305

306 const auto *LCC = cast(CC);

307

310

311 const auto *CE = dyn_cast_or_null(E);

316 }

317

319 }

321

323

324 const auto *ACC = cast(CC);

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

326 unsigned Idx = ACC->getIndex();

327

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

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

332

333

334 if (!FutureSFC)

335 return std::nullopt;

336

337

338

339

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

341

342

344 return std::nullopt;

345

346

347

348

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

351 if (!TVR)

352 return std::nullopt;

353

355 };

356

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

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

361 return *V;

362 else

363 break;

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

365

366

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

370 return *V;

371 else

372 break;

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

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

377 return *V;

378 else

379 break;

380 }

381 }

382 }

383 }

384

385

386

389}

390

395

396

397 return State;

398 }

399

400

401

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

406 const auto *DSCC = cast(CC);

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

408 }

411 const auto *ICC = cast(CC);

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

413

414 assert(Init->isAnyMemberInitializer() &&

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

416 "computeObjectUnderConstruction()");

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

418 }

420 return State;

421 }

426 if (!CallerLCtx) {

427

428 return State;

429 }

430

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

434 if (isa(CallerLCtx)) {

435

436

437 CallerLCtx = CallerLCtx->getParent();

438 assert(!isa(CallerLCtx));

439 }

440

442 cast(SFC->getCallSite()), State, CallerLCtx,

443 RTC->getConstructionContext(), CallOpts);

444 }

448 const auto *TCC = cast(CC);

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

451 TCC->getConstructionContextAfterElision(), CallOpts);

452

453

454 State = addObjectUnderConstruction(

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

456

457

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

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

460

461

462

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

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

465

466 return State;

467 }

468

469

470 [[fallthrough]];

471 }

473 const auto *TCC = cast(CC);

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

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

476

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

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

479

480 return State;

481 }

483 const auto *LCC = cast(CC);

484

485

486

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

489

490 return addObjectUnderConstruction(

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

492 }

494 const auto *ACC = cast(CC);

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

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

497

498 return addObjectUnderConstruction(

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

500 }

501 }

502 llvm_unreachable("Unhandled construction context!");

503}

504

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

512

513

514

515

517 const auto *Ctor =

519

520 const auto *SourceArrayRegion =

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

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

524

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

527}

528

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

532 const auto *CE = dyn_cast(E);

533 const auto *CIE = dyn_cast(E);

534 assert(CE || CIE);

535

538

540

541 if (CE) {

542 if (std::optional ElidedTarget =

544

545

546

547 Target = *ElidedTarget;

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

550 if (auto L = Target.getAs<Loc>())

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

553 return;

554 }

555 }

556

561

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

564 switch (CK) {

566

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

568

569

570

572

573 unsigned Idx = 0;

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

575

576 auto isZeroSizeArray = [&] {

578

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

581 else if (AILE)

583

584 return Size == 0;

585 };

586

587

588 if (isZeroSizeArray()) {

591 "Skipping 0 size array construction"};

593 return;

594 }

595

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

598 }

599

600 if (AILE) {

601

603 State = setPendingInitLoop(

604 State, CE, LCtx,

605 getContext().getArrayInitLoopExprElementCount(AILE));

606

609 }

610

611

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

614 break;

615 }

617

618

619 const auto *OuterCtor = dyn_cast_or_null(

621 assert(

622 (!OuterCtor ||

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

626 "the most derived class!"));

627 (void)OuterCtor;

628 [[fallthrough]];

629 }

631

632

633

634

635

636

637

638

639

640

641

646 break;

647 }

648 [[fallthrough]];

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

654

657 } else {

658

660 SVal BaseVal =

663 }

664 break;

665 }

666 }

667

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

670 "Prepare for object construction");

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

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

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

676 return;

677 Pred = *BldrPrepare.begin();

678 }

679

687

690

692 if (CE) {

693

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

697 if (CE->requiresZeroInitialization()) {

698

699

700

701

702

703

704

705

706

707

708

709

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

711 }

712

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

715 }

716 } else {

717 PreInitialized = DstPreVisit;

718 }

719

722 *Call, *this);

723

725

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

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

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

730

732 performTrivialCopy(Bldr, N, *Call);

733

734 } else {

737 CallOpts);

738 }

739

740

741

742

743

744

745

746

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

753 cast(Call->getDecl())

754 ->getParent()

755 ->isAnyDestructorNoReturn()) {

756

757

758

759

760

761

762

763

764 assert(!DstEvaluated.empty() &&

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

766

769 }

770

771

772

773

774 return;

775 }

776 }

777

779 for (ExplodedNode *I : DstEvaluatedPostProcessed)

780 finishArgumentConstruction(DstPostArgumentCleanup, I, *Call);

781

782

783

786 DstPostArgumentCleanup,

787 *Call, *this);

789}

790

794 handleConstructor(CE, Pred, Dst);

795}

796

800 handleConstructor(CE, Pred, Dst);

801}

802

805 const Stmt *S,

806 bool IsBaseDtor,

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

813

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

817

818

819 if (!DtorDecl) {

820

821

823

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

828 return;

829 }

830

831 if (!Dest) {

832

833

834

835

836

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

840 } else {

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

845 return;

846 }

847 }

848

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

852

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

855 "Error evaluating destructor");

856

859 *Call, *this);

860

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

865

867 *Call, *this);

868}

869

877 "Error evaluating New Allocator Call");

881

884 *Call, *this);

885

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

889

891 }

892

893

894

895

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

899

900

901

902

903

904

905

906

907

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

910

911

912

913

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

915

916

917

918

919

920

921

922

926 if (!ProtoType->isNothrow())

928 }

929

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

932 }

933

936 DstPostValue, *Call, *this);

937 for (ExplodedNode *I : DstPostPostCallCallback) {

939 }

940}

941

944

945

946

947

948

949 unsigned blockCount = currBldrCtx->blockCount();

953

954 bool IsStandardGlobalOpNewFunction =

956

958

959

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

963 }

964

965

966

967

969 if (IsStandardGlobalOpNewFunction)

971 else

973 blockCount);

974 }

975

979

981

982

983

984

985 State = Call->invalidateRegions(blockCount);

986 if (!State)

987 return;

988

989

990

991

992

993

994

995

997 if (!ProtoType->isNothrow())

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

1000 }

1001

1003

1005

1007

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

1009

1010

1011

1013 bool isInitList = isa_and_nonnull(Init);

1014

1021

1022

1023

1024 if (isInitList) {

1027

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

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

1031

1034

1035 Pred = *evaluated.begin();

1037 }

1038 }

1039

1042 return;

1043 }

1044

1045

1046

1047

1048

1050

1054 }

1055

1056

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

1059 if (!NewN)

1060 return;

1061

1062

1063

1065 if (!isa(Init)) {

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

1069 IsStandardGlobalOpNewFunction);

1070 }

1071 }

1072}

1073

1076

1080

1084

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

1089 }

1090 } else {

1091 DstPostCall = DstPreCall;

1092 }

1094}

1095

1099 if (!VD) {

1100 Dst.Add(Pred);

1101 return;

1102 }

1103

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

1109

1112}

1113

1117

1118

1123 LCtx);

1124

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

1128}

1129

1133

1134

1136 LE, LocCtxt);

1138

1140

1141

1142

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

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

1145 LE->capture_inits())) {

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

1147

1148 SVal InitVal;

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

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

1151

1152

1153

1154

1155

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

1157 if (FTy->isConstantArrayType() &&

1158 getContext().getConstantArrayElementCount(

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

1160 continue;

1161

1162

1163

1164

1165 if (const auto OUC =

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

1168

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

1170 } else

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

1172

1173 } else {

1174

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

1177

1178

1179

1180

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

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

1183 }

1184

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

1186 }

1187

1188

1189

1190

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

1192

1195

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

1199

1200

1202}

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)

llvm::MachO::Target Target

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.

AnalysisDeclContext contains the context data for the function, method or block under analysis.

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

Represents an array type, per C99 6.7.5.2 - Array Declarators.

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

Represents C++ constructor call.

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.

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 isReservedGlobalPlacementOperator() const

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

bool isReplaceableGlobalAllocationFunction(std::optional< unsigned > *AlignmentParam=nullptr, bool *IsNothrow=nullptr) const

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

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.

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.

AnalyzerOptions & getAnalyzerOptions() override

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)

const CoreEngine & getCoreEngine() const

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

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

VisitLambdaExpr - Transfer function logic for LambdaExprs.

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.

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)

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

Create a C++ temporary object for an rvalue.

CFGBlock::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)

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

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

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

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)

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

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

Retreives the size of the array in the pending ArrayInitLoopExpr.

const CXXThisRegion * getCXXThisRegion(QualType thisPointerTy, const LocationContext *LC)

getCXXThisRegion - Retrieve the [artificial] region associated with the parameter 'this'.

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

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

const CXXLifetimeExtendedObjectRegion * getCXXLifetimeExtendedObjectRegion(Expr const *Ex, ValueDecl const *VD, LocationContext const *LC)

Create a CXXLifetimeExtendedObjectRegion for temporaries which are lifetime-extended by local referen...

const CXXTempObjectRegion * getCXXTempObjectRegion(Expr const *Ex, LocationContext const *LC)

const CXXBaseObjectRegion * getCXXBaseObjectRegion(const CXXRecordDecl *BaseClass, const SubRegion *Super, bool IsVirtual)

Create a CXXBaseObjectRegion with the given base class for region Super.

const CXXLifetimeExtendedObjectRegion * getCXXStaticLifetimeExtendedObjectRegion(const Expr *Ex, ValueDecl const *VD)

Create a CXXLifetimeExtendedObjectRegion for temporaries which are lifetime-extended by static refere...

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

CallEventManager & getCallEventManager()

MemRegionManager & getRegionManager()

NonLoc makeArrayIndex(uint64_t idx)

ASTContext & getContext()

loc::MemRegionVal makeLoc(SymbolRef sym)

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

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

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

DefinedSVal getConjuredHeapSymbolVal(const Expr *E, const LocationContext *LCtx, unsigned Count)

Conjure a symbol representing heap allocated memory region.

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.

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

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

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