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