clang 17.0.0git
ExprEngineC.cpp
Go to the documentation of this file.
1//=-- ExprEngineC.cpp - ExprEngine support for C expressions ----*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file defines ExprEngine's support for C expressions.
10//
11//===----------------------------------------------------------------------===//
12
13#include "clang/AST/ExprCXX.h"
14#include "clang/AST/DeclCXX.h"
17#include <optional>
18
19using namespace clang;
20using namespace ento;
21using llvm::APSInt;
22
23/// Optionally conjure and return a symbol for offset when processing
24/// an expression \p Expression.
25/// If \p Other is a location, conjure a symbol for \p Symbol
26/// (offset) if it is unknown so that memory arithmetic always
27/// results in an ElementRegion.
28/// \p Count The number of times the current basic block was visited.
30 SVal Symbol, SVal Other, Expr* Expression, SValBuilder &svalBuilder,
31 unsigned Count, const LocationContext *LCtx) {
32 QualType Ty = Expression->getType();
33 if (isa<Loc>(Other) && Ty->isIntegralOrEnumerationType() &&
34 Symbol.isUnknown()) {
35 return svalBuilder.conjureSymbolVal(Expression, LCtx, Ty, Count);
36 }
37 return Symbol;
38}
39
41 ExplodedNode *Pred,
42 ExplodedNodeSet &Dst) {
43
44 Expr *LHS = B->getLHS()->IgnoreParens();
45 Expr *RHS = B->getRHS()->IgnoreParens();
46
47 // FIXME: Prechecks eventually go in ::Visit().
48 ExplodedNodeSet CheckedSet;
49 ExplodedNodeSet Tmp2;
50 getCheckerManager().runCheckersForPreStmt(CheckedSet, Pred, B, *this);
51
52 // With both the LHS and RHS evaluated, process the operation itself.
53 for (ExplodedNodeSet::iterator it=CheckedSet.begin(), ei=CheckedSet.end();
54 it != ei; ++it) {
55
56 ProgramStateRef state = (*it)->getState();
57 const LocationContext *LCtx = (*it)->getLocationContext();
58 SVal LeftV = state->getSVal(LHS, LCtx);
59 SVal RightV = state->getSVal(RHS, LCtx);
60
62
63 if (Op == BO_Assign) {
64 // EXPERIMENTAL: "Conjured" symbols.
65 // FIXME: Handle structs.
66 if (RightV.isUnknown()) {
67 unsigned Count = currBldrCtx->blockCount();
68 RightV = svalBuilder.conjureSymbolVal(nullptr, B->getRHS(), LCtx,
69 Count);
70 }
71 // Simulate the effects of a "store": bind the value of the RHS
72 // to the L-Value represented by the LHS.
73 SVal ExprVal = B->isGLValue() ? LeftV : RightV;
74 evalStore(Tmp2, B, LHS, *it, state->BindExpr(B, LCtx, ExprVal),
75 LeftV, RightV);
76 continue;
77 }
78
79 if (!B->isAssignmentOp()) {
80 StmtNodeBuilder Bldr(*it, Tmp2, *currBldrCtx);
81
82 if (B->isAdditiveOp()) {
83 // TODO: This can be removed after we enable history tracking with
84 // SymSymExpr.
85 unsigned Count = currBldrCtx->blockCount();
87 RightV, LeftV, RHS, svalBuilder, Count, LCtx);
89 LeftV, RightV, LHS, svalBuilder, Count, LCtx);
90 }
91
92 // Although we don't yet model pointers-to-members, we do need to make
93 // sure that the members of temporaries have a valid 'this' pointer for
94 // other checks.
95 if (B->getOpcode() == BO_PtrMemD)
96 state = createTemporaryRegionIfNeeded(state, LCtx, LHS);
97
98 // Process non-assignments except commas or short-circuited
99 // logical expressions (LAnd and LOr).
100 SVal Result = evalBinOp(state, Op, LeftV, RightV, B->getType());
101 if (!Result.isUnknown()) {
102 state = state->BindExpr(B, LCtx, Result);
103 } else {
104 // If we cannot evaluate the operation escape the operands.
105 state = escapeValues(state, LeftV, PSK_EscapeOther);
106 state = escapeValues(state, RightV, PSK_EscapeOther);
107 }
108
109 Bldr.generateNode(B, *it, state);
110 continue;
111 }
112
113 assert (B->isCompoundAssignmentOp());
114
115 switch (Op) {
116 default:
117 llvm_unreachable("Invalid opcode for compound assignment.");
118 case BO_MulAssign: Op = BO_Mul; break;
119 case BO_DivAssign: Op = BO_Div; break;
120 case BO_RemAssign: Op = BO_Rem; break;
121 case BO_AddAssign: Op = BO_Add; break;
122 case BO_SubAssign: Op = BO_Sub; break;
123 case BO_ShlAssign: Op = BO_Shl; break;
124 case BO_ShrAssign: Op = BO_Shr; break;
125 case BO_AndAssign: Op = BO_And; break;
126 case BO_XorAssign: Op = BO_Xor; break;
127 case BO_OrAssign: Op = BO_Or; break;
128 }
129
130 // Perform a load (the LHS). This performs the checks for
131 // null dereferences, and so on.
132 ExplodedNodeSet Tmp;
133 SVal location = LeftV;
134 evalLoad(Tmp, B, LHS, *it, state, location);
135
136 for (ExplodedNodeSet::iterator I = Tmp.begin(), E = Tmp.end(); I != E;
137 ++I) {
138
139 state = (*I)->getState();
140 const LocationContext *LCtx = (*I)->getLocationContext();
141 SVal V = state->getSVal(LHS, LCtx);
142
143 // Get the computation type.
144 QualType CTy =
145 cast<CompoundAssignOperator>(B)->getComputationResultType();
146 CTy = getContext().getCanonicalType(CTy);
147
148 QualType CLHSTy =
149 cast<CompoundAssignOperator>(B)->getComputationLHSType();
150 CLHSTy = getContext().getCanonicalType(CLHSTy);
151
153
154 // Promote LHS.
155 V = svalBuilder.evalCast(V, CLHSTy, LTy);
156
157 // Compute the result of the operation.
158 SVal Result = svalBuilder.evalCast(evalBinOp(state, Op, V, RightV, CTy),
159 B->getType(), CTy);
160
161 // EXPERIMENTAL: "Conjured" symbols.
162 // FIXME: Handle structs.
163
164 SVal LHSVal;
165
166 if (Result.isUnknown()) {
167 // The symbolic value is actually for the type of the left-hand side
168 // expression, not the computation type, as this is the value the
169 // LValue on the LHS will bind to.
170 LHSVal = svalBuilder.conjureSymbolVal(nullptr, B->getRHS(), LCtx, LTy,
171 currBldrCtx->blockCount());
172 // However, we need to convert the symbol to the computation type.
173 Result = svalBuilder.evalCast(LHSVal, CTy, LTy);
174 }
175 else {
176 // The left-hand side may bind to a different value then the
177 // computation type.
178 LHSVal = svalBuilder.evalCast(Result, LTy, CTy);
179 }
180
181 // In C++, assignment and compound assignment operators return an
182 // lvalue.
183 if (B->isGLValue())
184 state = state->BindExpr(B, LCtx, location);
185 else
186 state = state->BindExpr(B, LCtx, Result);
187
188 evalStore(Tmp2, B, LHS, *I, state, location, LHSVal);
189 }
190 }
191
192 // FIXME: postvisits eventually go in ::Visit()
193 getCheckerManager().runCheckersForPostStmt(Dst, Tmp2, B, *this);
194}
195
197 ExplodedNodeSet &Dst) {
198
200
201 const BlockDecl *BD = BE->getBlockDecl();
202 // Get the value of the block itself.
203 SVal V = svalBuilder.getBlockPointer(BD, T,
204 Pred->getLocationContext(),
205 currBldrCtx->blockCount());
206
207 ProgramStateRef State = Pred->getState();
208
209 // If we created a new MemRegion for the block, we should explicitly bind
210 // the captured variables.
211 if (const BlockDataRegion *BDR =
212 dyn_cast_or_null<BlockDataRegion>(V.getAsRegion())) {
213
214 BlockDataRegion::referenced_vars_iterator I = BDR->referenced_vars_begin(),
215 E = BDR->referenced_vars_end();
216
217 auto CI = BD->capture_begin();
218 auto CE = BD->capture_end();
219 for (; I != E; ++I) {
220 const VarRegion *capturedR = I.getCapturedRegion();
221 const TypedValueRegion *originalR = I.getOriginalRegion();
222
223 // If the capture had a copy expression, use the result of evaluating
224 // that expression, otherwise use the original value.
225 // We rely on the invariant that the block declaration's capture variables
226 // are a prefix of the BlockDataRegion's referenced vars (which may include
227 // referenced globals, etc.) to enable fast lookup of the capture for a
228 // given referenced var.
229 const Expr *copyExpr = nullptr;
230 if (CI != CE) {
231 assert(CI->getVariable() == capturedR->getDecl());
232 copyExpr = CI->getCopyExpr();
233 CI++;
234 }
235
236 if (capturedR != originalR) {
237 SVal originalV;
238 const LocationContext *LCtx = Pred->getLocationContext();
239 if (copyExpr) {
240 originalV = State->getSVal(copyExpr, LCtx);
241 } else {
242 originalV = State->getSVal(loc::MemRegionVal(originalR));
243 }
244 State = State->bindLoc(loc::MemRegionVal(capturedR), originalV, LCtx);
245 }
246 }
247 }
248
249 ExplodedNodeSet Tmp;
250 StmtNodeBuilder Bldr(Pred, Tmp, *currBldrCtx);
251 Bldr.generateNode(BE, Pred,
252 State->BindExpr(BE, Pred->getLocationContext(), V),
254
255 // FIXME: Move all post/pre visits to ::Visit().
256 getCheckerManager().runCheckersForPostStmt(Dst, Tmp, BE, *this);
257}
258
260 ProgramStateRef state, const Expr* Ex, const LocationContext* LCtx,
261 QualType T, QualType ExTy, const CastExpr* CastE, StmtNodeBuilder& Bldr,
262 ExplodedNode* Pred) {
263 if (T->isLValueReferenceType()) {
264 assert(!CastE->getType()->isLValueReferenceType());
265 ExTy = getContext().getLValueReferenceType(ExTy);
266 } else if (T->isRValueReferenceType()) {
267 assert(!CastE->getType()->isRValueReferenceType());
268 ExTy = getContext().getRValueReferenceType(ExTy);
269 }
270 // Delegate to SValBuilder to process.
271 SVal OrigV = state->getSVal(Ex, LCtx);
272 SVal V = svalBuilder.evalCast(OrigV, T, ExTy);
273 // Negate the result if we're treating the boolean as a signed i1
274 if (CastE->getCastKind() == CK_BooleanToSignedIntegral && V.isValid())
275 V = svalBuilder.evalMinus(V.castAs<NonLoc>());
276
277 state = state->BindExpr(CastE, LCtx, V);
278 if (V.isUnknown() && !OrigV.isUnknown()) {
279 state = escapeValues(state, OrigV, PSK_EscapeOther);
280 }
281 Bldr.generateNode(CastE, Pred, state);
282
283 return state;
284}
285
286void ExprEngine::VisitCast(const CastExpr *CastE, const Expr *Ex,
287 ExplodedNode *Pred, ExplodedNodeSet &Dst) {
288
289 ExplodedNodeSet dstPreStmt;
290 getCheckerManager().runCheckersForPreStmt(dstPreStmt, Pred, CastE, *this);
291
292 if (CastE->getCastKind() == CK_LValueToRValue ||
293 CastE->getCastKind() == CK_LValueToRValueBitCast) {
294 for (ExplodedNodeSet::iterator I = dstPreStmt.begin(), E = dstPreStmt.end();
295 I!=E; ++I) {
296 ExplodedNode *subExprNode = *I;
297 ProgramStateRef state = subExprNode->getState();
298 const LocationContext *LCtx = subExprNode->getLocationContext();
299 evalLoad(Dst, CastE, CastE, subExprNode, state, state->getSVal(Ex, LCtx));
300 }
301 return;
302 }
303
304 // All other casts.
305 QualType T = CastE->getType();
306 QualType ExTy = Ex->getType();
307
308 if (const ExplicitCastExpr *ExCast=dyn_cast_or_null<ExplicitCastExpr>(CastE))
309 T = ExCast->getTypeAsWritten();
310
311 StmtNodeBuilder Bldr(dstPreStmt, Dst, *currBldrCtx);
312 for (ExplodedNodeSet::iterator I = dstPreStmt.begin(), E = dstPreStmt.end();
313 I != E; ++I) {
314
315 Pred = *I;
316 ProgramStateRef state = Pred->getState();
317 const LocationContext *LCtx = Pred->getLocationContext();
318
319 switch (CastE->getCastKind()) {
320 case CK_LValueToRValue:
321 case CK_LValueToRValueBitCast:
322 llvm_unreachable("LValueToRValue casts handled earlier.");
323 case CK_ToVoid:
324 continue;
325 // The analyzer doesn't do anything special with these casts,
326 // since it understands retain/release semantics already.
327 case CK_ARCProduceObject:
328 case CK_ARCConsumeObject:
329 case CK_ARCReclaimReturnedObject:
330 case CK_ARCExtendBlockObject: // Fall-through.
331 case CK_CopyAndAutoreleaseBlockObject:
332 // The analyser can ignore atomic casts for now, although some future
333 // checkers may want to make certain that you're not modifying the same
334 // value through atomic and nonatomic pointers.
335 case CK_AtomicToNonAtomic:
336 case CK_NonAtomicToAtomic:
337 // True no-ops.
338 case CK_NoOp:
339 case CK_ConstructorConversion:
340 case CK_UserDefinedConversion:
341 case CK_FunctionToPointerDecay:
342 case CK_BuiltinFnToFnPtr: {
343 // Copy the SVal of Ex to CastE.
344 ProgramStateRef state = Pred->getState();
345 const LocationContext *LCtx = Pred->getLocationContext();
346 SVal V = state->getSVal(Ex, LCtx);
347 state = state->BindExpr(CastE, LCtx, V);
348 Bldr.generateNode(CastE, Pred, state);
349 continue;
350 }
351 case CK_MemberPointerToBoolean:
352 case CK_PointerToBoolean: {
353 SVal V = state->getSVal(Ex, LCtx);
354 auto PTMSV = V.getAs<nonloc::PointerToMember>();
355 if (PTMSV)
356 V = svalBuilder.makeTruthVal(!PTMSV->isNullMemberPointer(), ExTy);
357 if (V.isUndef() || PTMSV) {
358 state = state->BindExpr(CastE, LCtx, V);
359 Bldr.generateNode(CastE, Pred, state);
360 continue;
361 }
362 // Explicitly proceed with default handler for this case cascade.
363 state =
364 handleLValueBitCast(state, Ex, LCtx, T, ExTy, CastE, Bldr, Pred);
365 continue;
366 }
367 case CK_Dependent:
368 case CK_ArrayToPointerDecay:
369 case CK_BitCast:
370 case CK_AddressSpaceConversion:
371 case CK_BooleanToSignedIntegral:
372 case CK_IntegralToPointer:
373 case CK_PointerToIntegral: {
374 SVal V = state->getSVal(Ex, LCtx);
375 if (isa<nonloc::PointerToMember>(V)) {
376 state = state->BindExpr(CastE, LCtx, UnknownVal());
377 Bldr.generateNode(CastE, Pred, state);
378 continue;
379 }
380 // Explicitly proceed with default handler for this case cascade.
381 state =
382 handleLValueBitCast(state, Ex, LCtx, T, ExTy, CastE, Bldr, Pred);
383 continue;
384 }
385 case CK_IntegralToBoolean:
386 case CK_IntegralToFloating:
387 case CK_FloatingToIntegral:
388 case CK_FloatingToBoolean:
389 case CK_FloatingCast:
390 case CK_FloatingRealToComplex:
391 case CK_FloatingComplexToReal:
392 case CK_FloatingComplexToBoolean:
393 case CK_FloatingComplexCast:
394 case CK_FloatingComplexToIntegralComplex:
395 case CK_IntegralRealToComplex:
396 case CK_IntegralComplexToReal:
397 case CK_IntegralComplexToBoolean:
398 case CK_IntegralComplexCast:
399 case CK_IntegralComplexToFloatingComplex:
400 case CK_CPointerToObjCPointerCast:
401 case CK_BlockPointerToObjCPointerCast:
402 case CK_AnyPointerToBlockPointerCast:
403 case CK_ObjCObjectLValueCast:
404 case CK_ZeroToOCLOpaqueType:
405 case CK_IntToOCLSampler:
406 case CK_LValueBitCast:
407 case CK_FloatingToFixedPoint:
408 case CK_FixedPointToFloating:
409 case CK_FixedPointCast:
410 case CK_FixedPointToBoolean:
411 case CK_FixedPointToIntegral:
412 case CK_IntegralToFixedPoint: {
413 state =
414 handleLValueBitCast(state, Ex, LCtx, T, ExTy, CastE, Bldr, Pred);
415 continue;
416 }
417 case CK_IntegralCast: {
418 // Delegate to SValBuilder to process.
419 SVal V = state->getSVal(Ex, LCtx);
420 if (AMgr.options.ShouldSupportSymbolicIntegerCasts)
421 V = svalBuilder.evalCast(V, T, ExTy);
422 else
423 V = svalBuilder.evalIntegralCast(state, V, T, ExTy);
424 state = state->BindExpr(CastE, LCtx, V);
425 Bldr.generateNode(CastE, Pred, state);
426 continue;
427 }
428 case CK_DerivedToBase:
429 case CK_UncheckedDerivedToBase: {
430 // For DerivedToBase cast, delegate to the store manager.
431 SVal val = state->getSVal(Ex, LCtx);
432 val = getStoreManager().evalDerivedToBase(val, CastE);
433 state = state->BindExpr(CastE, LCtx, val);
434 Bldr.generateNode(CastE, Pred, state);
435 continue;
436 }
437 // Handle C++ dyn_cast.
438 case CK_Dynamic: {
439 SVal val = state->getSVal(Ex, LCtx);
440
441 // Compute the type of the result.
442 QualType resultType = CastE->getType();
443 if (CastE->isGLValue())
444 resultType = getContext().getPointerType(resultType);
445
446 bool Failed = true;
447
448 // Check if the value being cast does not evaluates to 0.
449 if (!val.isZeroConstant())
450 if (std::optional<SVal> V =
451 StateMgr.getStoreManager().evalBaseToDerived(val, T)) {
452 val = *V;
453 Failed = false;
454 }
455
456 if (Failed) {
457 if (T->isReferenceType()) {
458 // A bad_cast exception is thrown if input value is a reference.
459 // Currently, we model this, by generating a sink.
460 Bldr.generateSink(CastE, Pred, state);
461 continue;
462 } else {
463 // If the cast fails on a pointer, bind to 0.
464 state = state->BindExpr(CastE, LCtx,
465 svalBuilder.makeNullWithType(resultType));
466 }
467 } else {
468 // If we don't know if the cast succeeded, conjure a new symbol.
469 if (val.isUnknown()) {
470 DefinedOrUnknownSVal NewSym =
471 svalBuilder.conjureSymbolVal(nullptr, CastE, LCtx, resultType,
472 currBldrCtx->blockCount());
473 state = state->BindExpr(CastE, LCtx, NewSym);
474 } else
475 // Else, bind to the derived region value.
476 state = state->BindExpr(CastE, LCtx, val);
477 }
478 Bldr.generateNode(CastE, Pred, state);
479 continue;
480 }
481 case CK_BaseToDerived: {
482 SVal val = state->getSVal(Ex, LCtx);
483 QualType resultType = CastE->getType();
484 if (CastE->isGLValue())
485 resultType = getContext().getPointerType(resultType);
486
487 if (!val.isConstant()) {
488 std::optional<SVal> V = getStoreManager().evalBaseToDerived(val, T);
489 val = V ? *V : UnknownVal();
490 }
491
492 // Failed to cast or the result is unknown, fall back to conservative.
493 if (val.isUnknown()) {
494 val =
495 svalBuilder.conjureSymbolVal(nullptr, CastE, LCtx, resultType,
496 currBldrCtx->blockCount());
497 }
498 state = state->BindExpr(CastE, LCtx, val);
499 Bldr.generateNode(CastE, Pred, state);
500 continue;
501 }
502 case CK_NullToPointer: {
503 SVal V = svalBuilder.makeNullWithType(CastE->getType());
504 state = state->BindExpr(CastE, LCtx, V);
505 Bldr.generateNode(CastE, Pred, state);
506 continue;
507 }
508 case CK_NullToMemberPointer: {
509 SVal V = svalBuilder.getMemberPointer(nullptr);
510 state = state->BindExpr(CastE, LCtx, V);
511 Bldr.generateNode(CastE, Pred, state);
512 continue;
513 }
514 case CK_DerivedToBaseMemberPointer:
515 case CK_BaseToDerivedMemberPointer:
516 case CK_ReinterpretMemberPointer: {
517 SVal V = state->getSVal(Ex, LCtx);
518 if (auto PTMSV = V.getAs<nonloc::PointerToMember>()) {
519 SVal CastedPTMSV =
520 svalBuilder.makePointerToMember(getBasicVals().accumCXXBase(
521 CastE->path(), *PTMSV, CastE->getCastKind()));
522 state = state->BindExpr(CastE, LCtx, CastedPTMSV);
523 Bldr.generateNode(CastE, Pred, state);
524 continue;
525 }
526 // Explicitly proceed with default handler for this case cascade.
527 }
528 [[fallthrough]];
529 // Various C++ casts that are not handled yet.
530 case CK_ToUnion:
531 case CK_MatrixCast:
532 case CK_VectorSplat: {
533 QualType resultType = CastE->getType();
534 if (CastE->isGLValue())
535 resultType = getContext().getPointerType(resultType);
536 SVal result = svalBuilder.conjureSymbolVal(
537 /*symbolTag=*/nullptr, CastE, LCtx, resultType,
538 currBldrCtx->blockCount());
539 state = state->BindExpr(CastE, LCtx, result);
540 Bldr.generateNode(CastE, Pred, state);
541 continue;
542 }
543 }
544 }
545}
546
548 ExplodedNode *Pred,
549 ExplodedNodeSet &Dst) {
550 StmtNodeBuilder B(Pred, Dst, *currBldrCtx);
551
552 ProgramStateRef State = Pred->getState();
553 const LocationContext *LCtx = Pred->getLocationContext();
554
555 const Expr *Init = CL->getInitializer();
556 SVal V = State->getSVal(CL->getInitializer(), LCtx);
557
558 if (isa<CXXConstructExpr, CXXStdInitializerListExpr>(Init)) {
559 // No work needed. Just pass the value up to this expression.
560 } else {
561 assert(isa<InitListExpr>(Init));
562 Loc CLLoc = State->getLValue(CL, LCtx);
563 State = State->bindLoc(CLLoc, V, LCtx);
564
565 if (CL->isGLValue())
566 V = CLLoc;
567 }
568
569 B.generateNode(CL, Pred, State->BindExpr(CL, LCtx, V));
570}
571
573 ExplodedNodeSet &Dst) {
574 if (isa<TypedefNameDecl>(*DS->decl_begin())) {
575 // C99 6.7.7 "Any array size expressions associated with variable length
576 // array declarators are evaluated each time the declaration of the typedef
577 // name is reached in the order of execution."
578 // The checkers should know about typedef to be able to handle VLA size
579 // expressions.
580 ExplodedNodeSet DstPre;
581 getCheckerManager().runCheckersForPreStmt(DstPre, Pred, DS, *this);
582 getCheckerManager().runCheckersForPostStmt(Dst, DstPre, DS, *this);
583 return;
584 }
585
586 // Assumption: The CFG has one DeclStmt per Decl.
587 const VarDecl *VD = dyn_cast_or_null<VarDecl>(*DS->decl_begin());
588
589 if (!VD) {
590 //TODO:AZ: remove explicit insertion after refactoring is done.
591 Dst.insert(Pred);
592 return;
593 }
594
595 // FIXME: all pre/post visits should eventually be handled by ::Visit().
596 ExplodedNodeSet dstPreVisit;
597 getCheckerManager().runCheckersForPreStmt(dstPreVisit, Pred, DS, *this);
598
599 ExplodedNodeSet dstEvaluated;
600 StmtNodeBuilder B(dstPreVisit, dstEvaluated, *currBldrCtx);
601 for (ExplodedNodeSet::iterator I = dstPreVisit.begin(), E = dstPreVisit.end();
602 I!=E; ++I) {
603 ExplodedNode *N = *I;
604 ProgramStateRef state = N->getState();
605 const LocationContext *LC = N->getLocationContext();
606
607 // Decls without InitExpr are not initialized explicitly.
608 if (const Expr *InitEx = VD->getInit()) {
609
610 // Note in the state that the initialization has occurred.
611 ExplodedNode *UpdatedN = N;
612 SVal InitVal = state->getSVal(InitEx, LC);
613
614 assert(DS->isSingleDecl());
615 if (getObjectUnderConstruction(state, DS, LC)) {
616 state = finishObjectConstruction(state, DS, LC);
617 // We constructed the object directly in the variable.
618 // No need to bind anything.
619 B.generateNode(DS, UpdatedN, state);
620 } else {
621 // Recover some path-sensitivity if a scalar value evaluated to
622 // UnknownVal.
623 if (InitVal.isUnknown()) {
624 QualType Ty = InitEx->getType();
625 if (InitEx->isGLValue()) {
626 Ty = getContext().getPointerType(Ty);
627 }
628
629 InitVal = svalBuilder.conjureSymbolVal(nullptr, InitEx, LC, Ty,
630 currBldrCtx->blockCount());
631 }
632
633
634 B.takeNodes(UpdatedN);
635 ExplodedNodeSet Dst2;
636 evalBind(Dst2, DS, UpdatedN, state->getLValue(VD, LC), InitVal, true);
637 B.addNodes(Dst2);
638 }
639 }
640 else {
641 B.generateNode(DS, N, state);
642 }
643 }
644
646}
647
649 ExplodedNodeSet &Dst) {
650 // This method acts upon CFG elements for logical operators && and ||
651 // and attaches the value (true or false) to them as expressions.
652 // It doesn't produce any state splits.
653 // If we made it that far, we're past the point when we modeled the short
654 // circuit. It means that we should have precise knowledge about whether
655 // we've short-circuited. If we did, we already know the value we need to
656 // bind. If we didn't, the value of the RHS (casted to the boolean type)
657 // is the answer.
658 // Currently this method tries to figure out whether we've short-circuited
659 // by looking at the ExplodedGraph. This method is imperfect because there
660 // could inevitably have been merges that would have resulted in multiple
661 // potential path traversal histories. We bail out when we fail.
662 // Due to this ambiguity, a more reliable solution would have been to
663 // track the short circuit operation history path-sensitively until
664 // we evaluate the respective logical operator.
665 assert(B->getOpcode() == BO_LAnd ||
666 B->getOpcode() == BO_LOr);
667
668 StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx);
669 ProgramStateRef state = Pred->getState();
670
671 if (B->getType()->isVectorType()) {
672 // FIXME: We do not model vector arithmetic yet. When adding support for
673 // that, note that the CFG-based reasoning below does not apply, because
674 // logical operators on vectors are not short-circuit. Currently they are
675 // modeled as short-circuit in Clang CFG but this is incorrect.
676 // Do not set the value for the expression. It'd be UnknownVal by default.
677 Bldr.generateNode(B, Pred, state);
678 return;
679 }
680
681 ExplodedNode *N = Pred;
682 while (!N->getLocation().getAs<BlockEntrance>()) {
684 assert(P.getAs<PreStmt>()|| P.getAs<PreStmtPurgeDeadSymbols>());
685 (void) P;
686 if (N->pred_size() != 1) {
687 // We failed to track back where we came from.
688 Bldr.generateNode(B, Pred, state);
689 return;
690 }
691 N = *N->pred_begin();
692 }
693
694 if (N->pred_size() != 1) {
695 // We failed to track back where we came from.
696 Bldr.generateNode(B, Pred, state);
697 return;
698 }
699
700 N = *N->pred_begin();
702 SVal X;
703
704 // Determine the value of the expression by introspecting how we
705 // got this location in the CFG. This requires looking at the previous
706 // block we were in and what kind of control-flow transfer was involved.
707 const CFGBlock *SrcBlock = BE.getSrc();
708 // The only terminator (if there is one) that makes sense is a logical op.
709 CFGTerminator T = SrcBlock->getTerminator();
710 if (const BinaryOperator *Term = cast_or_null<BinaryOperator>(T.getStmt())) {
711 (void) Term;
712 assert(Term->isLogicalOp());
713 assert(SrcBlock->succ_size() == 2);
714 // Did we take the true or false branch?
715 unsigned constant = (*SrcBlock->succ_begin() == BE.getDst()) ? 1 : 0;
716 X = svalBuilder.makeIntVal(constant, B->getType());
717 }
718 else {
719 // If there is no terminator, by construction the last statement
720 // in SrcBlock is the value of the enclosing expression.
721 // However, we still need to constrain that value to be 0 or 1.
722 assert(!SrcBlock->empty());
723 CFGStmt Elem = SrcBlock->rbegin()->castAs<CFGStmt>();
724 const Expr *RHS = cast<Expr>(Elem.getStmt());
725 SVal RHSVal = N->getState()->getSVal(RHS, Pred->getLocationContext());
726
727 if (RHSVal.isUndef()) {
728 X = RHSVal;
729 } else {
730 // We evaluate "RHSVal != 0" expression which result in 0 if the value is
731 // known to be false, 1 if the value is known to be true and a new symbol
732 // when the assumption is unknown.
734 X = evalBinOp(N->getState(), BO_NE,
735 svalBuilder.evalCast(RHSVal, B->getType(), RHS->getType()),
736 Zero, B->getType());
737 }
738 }
739 Bldr.generateNode(B, Pred, state->BindExpr(B, Pred->getLocationContext(), X));
740}
741
743 ExplodedNode *Pred,
744 ExplodedNodeSet &Dst) {
745 StmtNodeBuilder B(Pred, Dst, *currBldrCtx);
746
747 ProgramStateRef state = Pred->getState();
748 const LocationContext *LCtx = Pred->getLocationContext();
750 unsigned NumInitElements = IE->getNumInits();
751
752 if (!IE->isGLValue() && !IE->isTransparent() &&
753 (T->isArrayType() || T->isRecordType() || T->isVectorType() ||
754 T->isAnyComplexType())) {
755 llvm::ImmutableList<SVal> vals = getBasicVals().getEmptySValList();
756
757 // Handle base case where the initializer has no elements.
758 // e.g: static int* myArray[] = {};
759 if (NumInitElements == 0) {
760 SVal V = svalBuilder.makeCompoundVal(T, vals);
761 B.generateNode(IE, Pred, state->BindExpr(IE, LCtx, V));
762 return;
763 }
764
765 for (const Stmt *S : llvm::reverse(*IE)) {
766 SVal V = state->getSVal(cast<Expr>(S), LCtx);
767 vals = getBasicVals().prependSVal(V, vals);
768 }
769
770 B.generateNode(IE, Pred,
771 state->BindExpr(IE, LCtx,
772 svalBuilder.makeCompoundVal(T, vals)));
773 return;
774 }
775
776 // Handle scalars: int{5} and int{} and GLvalues.
777 // Note, if the InitListExpr is a GLvalue, it means that there is an address
778 // representing it, so it must have a single init element.
779 assert(NumInitElements <= 1);
780
781 SVal V;
782 if (NumInitElements == 0)
784 else
785 V = state->getSVal(IE->getInit(0), LCtx);
786
787 B.generateNode(IE, Pred, state->BindExpr(IE, LCtx, V));
788}
789
791 const Expr *L,
792 const Expr *R,
793 ExplodedNode *Pred,
794 ExplodedNodeSet &Dst) {
795 assert(L && R);
796
797 StmtNodeBuilder B(Pred, Dst, *currBldrCtx);
798 ProgramStateRef state = Pred->getState();
799 const LocationContext *LCtx = Pred->getLocationContext();
800 const CFGBlock *SrcBlock = nullptr;
801
802 // Find the predecessor block.
803 ProgramStateRef SrcState = state;
804 for (const ExplodedNode *N = Pred ; N ; N = *N->pred_begin()) {
805 ProgramPoint PP = N->getLocation();
807 // If the state N has multiple predecessors P, it means that successors
808 // of P are all equivalent.
809 // In turn, that means that all nodes at P are equivalent in terms
810 // of observable behavior at N, and we can follow any of them.
811 // FIXME: a more robust solution which does not walk up the tree.
812 continue;
813 }
814 SrcBlock = PP.castAs<BlockEdge>().getSrc();
815 SrcState = N->getState();
816 break;
817 }
818
819 assert(SrcBlock && "missing function entry");
820
821 // Find the last expression in the predecessor block. That is the
822 // expression that is used for the value of the ternary expression.
823 bool hasValue = false;
824 SVal V;
825
826 for (CFGElement CE : llvm::reverse(*SrcBlock)) {
827 if (std::optional<CFGStmt> CS = CE.getAs<CFGStmt>()) {
828 const Expr *ValEx = cast<Expr>(CS->getStmt());
829 ValEx = ValEx->IgnoreParens();
830
831 // For GNU extension '?:' operator, the left hand side will be an
832 // OpaqueValueExpr, so get the underlying expression.
833 if (const OpaqueValueExpr *OpaqueEx = dyn_cast<OpaqueValueExpr>(L))
834 L = OpaqueEx->getSourceExpr();
835
836 // If the last expression in the predecessor block matches true or false
837 // subexpression, get its the value.
838 if (ValEx == L->IgnoreParens() || ValEx == R->IgnoreParens()) {
839 hasValue = true;
840 V = SrcState->getSVal(ValEx, LCtx);
841 }
842 break;
843 }
844 }
845
846 if (!hasValue)
847 V = svalBuilder.conjureSymbolVal(nullptr, Ex, LCtx,
848 currBldrCtx->blockCount());
849
850 // Generate a new node with the binding from the appropriate path.
851 B.generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V, true));
852}
853
856 ExplodedNode *Pred, ExplodedNodeSet &Dst) {
857 StmtNodeBuilder B(Pred, Dst, *currBldrCtx);
859 if (OOE->EvaluateAsInt(Result, getContext())) {
860 APSInt IV = Result.Val.getInt();
861 assert(IV.getBitWidth() == getContext().getTypeSize(OOE->getType()));
862 assert(OOE->getType()->castAs<BuiltinType>()->isInteger());
863 assert(IV.isSigned() == OOE->getType()->isSignedIntegerType());
864 SVal X = svalBuilder.makeIntVal(IV);
865 B.generateNode(OOE, Pred,
866 Pred->getState()->BindExpr(OOE, Pred->getLocationContext(),
867 X));
868 }
869 // FIXME: Handle the case where __builtin_offsetof is not a constant.
870}
871
872
875 ExplodedNode *Pred,
876 ExplodedNodeSet &Dst) {
877 // FIXME: Prechecks eventually go in ::Visit().
878 ExplodedNodeSet CheckedSet;
879 getCheckerManager().runCheckersForPreStmt(CheckedSet, Pred, Ex, *this);
880
881 ExplodedNodeSet EvalSet;
882 StmtNodeBuilder Bldr(CheckedSet, EvalSet, *currBldrCtx);
883
884 QualType T = Ex->getTypeOfArgument();
885
886 for (ExplodedNodeSet::iterator I = CheckedSet.begin(), E = CheckedSet.end();
887 I != E; ++I) {
888 if (Ex->getKind() == UETT_SizeOf) {
889 if (!T->isIncompleteType() && !T->isConstantSizeType()) {
890 assert(T->isVariableArrayType() && "Unknown non-constant-sized type.");
891
892 // FIXME: Add support for VLA type arguments and VLA expressions.
893 // When that happens, we should probably refactor VLASizeChecker's code.
894 continue;
895 } else if (T->getAs<ObjCObjectType>()) {
896 // Some code tries to take the sizeof an ObjCObjectType, relying that
897 // the compiler has laid out its representation. Just report Unknown
898 // for these.
899 continue;
900 }
901 }
902
904 CharUnits amt = CharUnits::fromQuantity(Value.getZExtValue());
905
906 ProgramStateRef state = (*I)->getState();
907 state = state->BindExpr(Ex, (*I)->getLocationContext(),
908 svalBuilder.makeIntVal(amt.getQuantity(),
909 Ex->getType()));
910 Bldr.generateNode(Ex, *I, state);
911 }
912
913 getCheckerManager().runCheckersForPostStmt(Dst, EvalSet, Ex, *this);
914}
915
917 const UnaryOperator *U,
918 StmtNodeBuilder &Bldr) {
919 // FIXME: We can probably just have some magic in Environment::getSVal()
920 // that propagates values, instead of creating a new node here.
921 //
922 // Unary "+" is a no-op, similar to a parentheses. We still have places
923 // where it may be a block-level expression, so we need to
924 // generate an extra node that just propagates the value of the
925 // subexpression.
926 const Expr *Ex = U->getSubExpr()->IgnoreParens();
927 ProgramStateRef state = (*I)->getState();
928 const LocationContext *LCtx = (*I)->getLocationContext();
929 Bldr.generateNode(U, *I, state->BindExpr(U, LCtx,
930 state->getSVal(Ex, LCtx)));
931}
932
934 ExplodedNodeSet &Dst) {
935 // FIXME: Prechecks eventually go in ::Visit().
936 ExplodedNodeSet CheckedSet;
937 getCheckerManager().runCheckersForPreStmt(CheckedSet, Pred, U, *this);
938
939 ExplodedNodeSet EvalSet;
940 StmtNodeBuilder Bldr(CheckedSet, EvalSet, *currBldrCtx);
941
942 for (ExplodedNodeSet::iterator I = CheckedSet.begin(), E = CheckedSet.end();
943 I != E; ++I) {
944 switch (U->getOpcode()) {
945 default: {
946 Bldr.takeNodes(*I);
947 ExplodedNodeSet Tmp;
949 Bldr.addNodes(Tmp);
950 break;
951 }
952 case UO_Real: {
953 const Expr *Ex = U->getSubExpr()->IgnoreParens();
954
955 // FIXME: We don't have complex SValues yet.
956 if (Ex->getType()->isAnyComplexType()) {
957 // Just report "Unknown."
958 break;
959 }
960
961 // For all other types, UO_Real is an identity operation.
962 assert (U->getType() == Ex->getType());
963 ProgramStateRef state = (*I)->getState();
964 const LocationContext *LCtx = (*I)->getLocationContext();
965 Bldr.generateNode(U, *I, state->BindExpr(U, LCtx,
966 state->getSVal(Ex, LCtx)));
967 break;
968 }
969
970 case UO_Imag: {
971 const Expr *Ex = U->getSubExpr()->IgnoreParens();
972 // FIXME: We don't have complex SValues yet.
973 if (Ex->getType()->isAnyComplexType()) {
974 // Just report "Unknown."
975 break;
976 }
977 // For all other types, UO_Imag returns 0.
978 ProgramStateRef state = (*I)->getState();
979 const LocationContext *LCtx = (*I)->getLocationContext();
980 SVal X = svalBuilder.makeZeroVal(Ex->getType());
981 Bldr.generateNode(U, *I, state->BindExpr(U, LCtx, X));
982 break;
983 }
984
985 case UO_AddrOf: {
986 // Process pointer-to-member address operation.
987 const Expr *Ex = U->getSubExpr()->IgnoreParens();
988 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Ex)) {
989 const ValueDecl *VD = DRE->getDecl();
990
991 if (isa<CXXMethodDecl, FieldDecl, IndirectFieldDecl>(VD)) {
992 ProgramStateRef State = (*I)->getState();
993 const LocationContext *LCtx = (*I)->getLocationContext();
994 SVal SV = svalBuilder.getMemberPointer(cast<NamedDecl>(VD));
995 Bldr.generateNode(U, *I, State->BindExpr(U, LCtx, SV));
996 break;
997 }
998 }
999 // Explicitly proceed with default handler for this case cascade.
1000 handleUOExtension(I, U, Bldr);
1001 break;
1002 }
1003 case UO_Plus:
1004 assert(!U->isGLValue());
1005 [[fallthrough]];
1006 case UO_Deref:
1007 case UO_Extension: {
1008 handleUOExtension(I, U, Bldr);
1009 break;
1010 }
1011
1012 case UO_LNot:
1013 case UO_Minus:
1014 case UO_Not: {
1015 assert (!U->isGLValue());
1016 const Expr *Ex = U->getSubExpr()->IgnoreParens();
1017 ProgramStateRef state = (*I)->getState();
1018 const LocationContext *LCtx = (*I)->getLocationContext();
1019
1020 // Get the value of the subexpression.
1021 SVal V = state->getSVal(Ex, LCtx);
1022
1023 if (V.isUnknownOrUndef()) {
1024 Bldr.generateNode(U, *I, state->BindExpr(U, LCtx, V));
1025 break;
1026 }
1027
1028 switch (U->getOpcode()) {
1029 default:
1030 llvm_unreachable("Invalid Opcode.");
1031 case UO_Not:
1032 // FIXME: Do we need to handle promotions?
1033 state = state->BindExpr(
1034 U, LCtx, svalBuilder.evalComplement(V.castAs<NonLoc>()));
1035 break;
1036 case UO_Minus:
1037 // FIXME: Do we need to handle promotions?
1038 state = state->BindExpr(U, LCtx,
1039 svalBuilder.evalMinus(V.castAs<NonLoc>()));
1040 break;
1041 case UO_LNot:
1042 // C99 6.5.3.3: "The expression !E is equivalent to (0==E)."
1043 //
1044 // Note: technically we do "E == 0", but this is the same in the
1045 // transfer functions as "0 == E".
1046 SVal Result;
1047 if (std::optional<Loc> LV = V.getAs<Loc>()) {
1048 Loc X = svalBuilder.makeNullWithType(Ex->getType());
1049 Result = evalBinOp(state, BO_EQ, *LV, X, U->getType());
1050 } else if (Ex->getType()->isFloatingType()) {
1051 // FIXME: handle floating point types.
1052 Result = UnknownVal();
1053 } else {
1055 Result = evalBinOp(state, BO_EQ, V.castAs<NonLoc>(), X, U->getType());
1056 }
1057
1058 state = state->BindExpr(U, LCtx, Result);
1059 break;
1060 }
1061 Bldr.generateNode(U, *I, state);
1062 break;
1063 }
1064 }
1065 }
1066
1067 getCheckerManager().runCheckersForPostStmt(Dst, EvalSet, U, *this);
1068}
1069
1071 ExplodedNode *Pred,
1072 ExplodedNodeSet &Dst) {
1073 // Handle ++ and -- (both pre- and post-increment).
1074 assert (U->isIncrementDecrementOp());
1075 const Expr *Ex = U->getSubExpr()->IgnoreParens();
1076
1077 const LocationContext *LCtx = Pred->getLocationContext();
1078 ProgramStateRef state = Pred->getState();
1079 SVal loc = state->getSVal(Ex, LCtx);
1080
1081 // Perform a load.
1082 ExplodedNodeSet Tmp;
1083 evalLoad(Tmp, U, Ex, Pred, state, loc);
1084
1085 ExplodedNodeSet Dst2;
1086 StmtNodeBuilder Bldr(Tmp, Dst2, *currBldrCtx);
1087 for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end();I!=E;++I) {
1088
1089 state = (*I)->getState();
1090 assert(LCtx == (*I)->getLocationContext());
1091 SVal V2_untested = state->getSVal(Ex, LCtx);
1092
1093 // Propagate unknown and undefined values.
1094 if (V2_untested.isUnknownOrUndef()) {
1095 state = state->BindExpr(U, LCtx, V2_untested);
1096
1097 // Perform the store, so that the uninitialized value detection happens.
1098 Bldr.takeNodes(*I);
1099 ExplodedNodeSet Dst3;
1100 evalStore(Dst3, U, Ex, *I, state, loc, V2_untested);
1101 Bldr.addNodes(Dst3);
1102
1103 continue;
1104 }
1105 DefinedSVal V2 = V2_untested.castAs<DefinedSVal>();
1106
1107 // Handle all other values.
1108 BinaryOperator::Opcode Op = U->isIncrementOp() ? BO_Add : BO_Sub;
1109
1110 // If the UnaryOperator has non-location type, use its type to create the
1111 // constant value. If the UnaryOperator has location type, create the
1112 // constant with int type and pointer width.
1113 SVal RHS;
1114 SVal Result;
1115
1116 if (U->getType()->isAnyPointerType())
1117 RHS = svalBuilder.makeArrayIndex(1);
1118 else if (U->getType()->isIntegralOrEnumerationType())
1119 RHS = svalBuilder.makeIntVal(1, U->getType());
1120 else
1121 RHS = UnknownVal();
1122
1123 // The use of an operand of type bool with the ++ operators is deprecated
1124 // but valid until C++17. And if the operand of the ++ operator is of type
1125 // bool, it is set to true until C++17. Note that for '_Bool', it is also
1126 // set to true when it encounters ++ operator.
1127 if (U->getType()->isBooleanType() && U->isIncrementOp())
1128 Result = svalBuilder.makeTruthVal(true, U->getType());
1129 else
1130 Result = evalBinOp(state, Op, V2, RHS, U->getType());
1131
1132 // Conjure a new symbol if necessary to recover precision.
1133 if (Result.isUnknown()){
1134 DefinedOrUnknownSVal SymVal =
1135 svalBuilder.conjureSymbolVal(nullptr, U, LCtx,
1136 currBldrCtx->blockCount());
1137 Result = SymVal;
1138
1139 // If the value is a location, ++/-- should always preserve
1140 // non-nullness. Check if the original value was non-null, and if so
1141 // propagate that constraint.
1142 if (Loc::isLocType(U->getType())) {
1143 DefinedOrUnknownSVal Constraint =
1144 svalBuilder.evalEQ(state, V2,svalBuilder.makeZeroVal(U->getType()));
1145
1146 if (!state->assume(Constraint, true)) {
1147 // It isn't feasible for the original value to be null.
1148 // Propagate this constraint.
1149 Constraint = svalBuilder.evalEQ(state, SymVal,
1150 svalBuilder.makeZeroVal(U->getType()));
1151
1152 state = state->assume(Constraint, false);
1153 assert(state);
1154 }
1155 }
1156 }
1157
1158 // Since the lvalue-to-rvalue conversion is explicit in the AST,
1159 // we bind an l-value if the operator is prefix and an lvalue (in C++).
1160 if (U->isGLValue())
1161 state = state->BindExpr(U, LCtx, loc);
1162 else
1163 state = state->BindExpr(U, LCtx, U->isPostfix() ? V2 : Result);
1164
1165 // Perform the store.
1166 Bldr.takeNodes(*I);
1167 ExplodedNodeSet Dst3;
1168 evalStore(Dst3, U, Ex, *I, state, loc, Result);
1169 Bldr.addNodes(Dst3);
1170 }
1171 Dst.insert(Dst2);
1172}
#define V(N, I)
Definition: ASTContext.h:3217
StringRef P
static SVal getValue(SVal val, SValBuilder &svalBuilder)
llvm::APSInt APSInt
static CompilationDatabasePluginRegistry::Add< FixedCompilationDatabasePlugin > X("fixed-compilation-database", "Reads plain-text flags file")
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the clang::Expr interface and subclasses for C++ expressions.
static SVal conjureOffsetSymbolOnLocation(SVal Symbol, SVal Other, Expr *Expression, SValBuilder &svalBuilder, unsigned Count, const LocationContext *LCtx)
Optionally conjure and return a symbol for offset when processing an expression Expression.
Definition: ExprEngineC.cpp:29
QualType getRValueReferenceType(QualType T) const
Return the uniqued reference to the type for an rvalue reference to the specified type.
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
Definition: ASTContext.h:2505
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type.
A builtin binary operation expression such as "x + y" or "x <= y".
Definition: Expr.h:3814
Expr * getLHS() const
Definition: Expr.h:3863
Expr * getRHS() const
Definition: Expr.h:3865
static bool isAdditiveOp(Opcode Opc)
Definition: Expr.h:3899
static bool isAssignmentOp(Opcode Opc)
Definition: Expr.h:3949
static bool isCompoundAssignmentOp(Opcode Opc)
Definition: Expr.h:3954
Opcode getOpcode() const
Definition: Expr.h:3858
Represents a block literal declaration, which is like an unnamed FunctionDecl.
Definition: Decl.h:4334
capture_const_iterator capture_begin() const
Definition: Decl.h:4463
capture_const_iterator capture_end() const
Definition: Decl.h:4464
const CFGBlock * getSrc() const
Definition: ProgramPoint.h:506
const CFGBlock * getDst() const
Definition: ProgramPoint.h:510
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
Definition: Expr.h:5975
const BlockDecl * getBlockDecl() const
Definition: Expr.h:5987
This class is used for builtin types like 'int'.
Definition: Type.h:2634
bool isInteger() const
Definition: Type.h:2685
Represents a single basic block in a source-level CFG.
Definition: CFG.h:576
reverse_iterator rbegin()
Definition: CFG.h:880
bool empty() const
Definition: CFG.h:918
CFGTerminator getTerminator() const
Definition: CFG.h:1048
succ_iterator succ_begin()
Definition: CFG.h:955
unsigned succ_size() const
Definition: CFG.h:973
Represents a top-level expression in a basic block.
Definition: CFG.h:54
T castAs() const
Convert to the specified CFGElement type, asserting that this CFGElement is of the desired type.
Definition: CFG.h:97
const Stmt * getStmt() const
Definition: CFG.h:136
Represents CFGBlock terminator statement.
Definition: CFG.h:503
Stmt * getStmt()
Definition: CFG.h:535
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
Definition: Expr.h:3482
CastKind getCastKind() const
Definition: Expr.h:3526
llvm::iterator_range< path_iterator > path()
Definition: Expr.h:3557
CharUnits - This is an opaque type for sizes expressed in character units.
Definition: CharUnits.h:38
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
Definition: CharUnits.h:185
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
Definition: CharUnits.h:63
CompoundLiteralExpr - [C99 6.5.2.5].
Definition: Expr.h:3412
const Expr * getInitializer() const
Definition: Expr.h:3435
A reference to a declared variable, function, enum, etc.
Definition: Expr.h:1238
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
Definition: Stmt.h:1311
bool isSingleDecl() const
isSingleDecl - This method returns true if this DeclStmt refers to a single Decl.
Definition: Stmt.h:1324
decl_iterator decl_begin()
Definition: Stmt.h:1365
ExplicitCastExpr - An explicit cast written in the source code.
Definition: Expr.h:3704
This represents one expression.
Definition: Expr.h:110
bool EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer,...
bool isGLValue() const
Definition: Expr.h:274
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx, SmallVectorImpl< PartialDiagnosticAt > *Diag=nullptr) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
Definition: Expr.cpp:3042
QualType getType() const
Definition: Expr.h:142
Describes an C or C++ initializer list.
Definition: Expr.h:4800
bool isTransparent() const
Is this a transparent initializer list (that is, an InitListExpr that is purely syntactic,...
Definition: Expr.cpp:2419
unsigned getNumInits() const
Definition: Expr.h:4830
const Expr * getInit(unsigned Init) const
Definition: Expr.h:4846
It wraps the AnalysisDeclContext to represent both the call stack with the help of StackFrameContext ...
Represents a class type in Objective C.
Definition: Type.h:6043
OffsetOfExpr - [C99 7.17] - This represents an expression of the form offsetof(record-type,...
Definition: Expr.h:2457
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
Definition: Expr.h:1146
Represents a point after we ran remove dead bindings BEFORE processing the given statement.
Definition: ProgramPoint.h:468
T castAs() const
Convert to the specified ProgramPoint type, asserting that this ProgramPoint is of the desired type.
Definition: ProgramPoint.h:137
std::optional< T > getAs() const
Convert to the specified ProgramPoint type, returning std::nullopt if this ProgramPoint is not of the...
Definition: ProgramPoint.h:147
A (possibly-)qualified type.
Definition: Type.h:736
Stmt - This represents one statement.
Definition: Stmt.h:72
bool isSignedIntegerType() const
Return true if this is an integer type that is signed, according to C99 6.2.5p4 [char,...
Definition: Type.cpp:2042
bool isRValueReferenceType() const
Definition: Type.h:6930
bool isConstantSizeType() const
Return true if this is not a variable sized type, according to the rules of C99 6....
Definition: Type.cpp:2249
bool isArrayType() const
Definition: Type.h:6976
const T * castAs() const
Member-template castAs<specific type>.
Definition: Type.h:7491
bool isReferenceType() const
Definition: Type.h:6922
bool isVariableArrayType() const
Definition: Type.h:6988
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
Definition: Type.h:7321
bool isLValueReferenceType() const
Definition: Type.h:6926
bool isAnyComplexType() const
Definition: Type.h:7008
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
Definition: Type.cpp:2259
bool isVectorType() const
Definition: Type.h:7012
bool isFloatingType() const
Definition: Type.cpp:2145
const T * getAs() const
Member-template getAs<specific type>'.
Definition: Type.h:7424
bool isRecordType() const
Definition: Type.h:7000
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand.
Definition: Expr.h:2560
QualType getTypeOfArgument() const
Gets the argument type, or the type of the argument expression, whichever is appropriate.
Definition: Expr.h:2629
UnaryExprOrTypeTrait getKind() const
Definition: Expr.h:2592
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Definition: Expr.h:2176
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition: Decl.h:701
Represents a variable declaration or definition.
Definition: Decl.h:913
const Expr * getInit() const
Definition: Decl.h:1325
llvm::ImmutableList< SVal > getEmptySValList()
llvm::ImmutableList< SVal > prependSVal(SVal X, llvm::ImmutableList< SVal > L)
LLVM_ATTRIBUTE_RETURNS_NONNULL const VarRegion * getCapturedRegion() const
Definition: MemRegion.h:718
LLVM_ATTRIBUTE_RETURNS_NONNULL const VarRegion * getOriginalRegion() const
Definition: MemRegion.h:723
BlockDataRegion - A region that represents a block instance.
Definition: MemRegion.h:674
void runCheckersForPostStmt(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const Stmt *S, ExprEngine &Eng, bool wasInlined=false)
Run checkers for post-visiting Stmts.
void runCheckersForPreStmt(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const Stmt *S, ExprEngine &Eng)
Run checkers for pre-visiting Stmts.
void insert(const ExplodedNodeSet &S)
const ProgramStateRef & getState() const
pred_iterator pred_begin()
ProgramPoint getLocation() const
getLocation - Returns the edge associated with the given node.
unsigned pred_size() const
const LocationContext * getLocationContext() const
void VisitBinaryOperator(const BinaryOperator *B, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitBinaryOperator - Transfer function logic for binary operators.
Definition: ExprEngineC.cpp:40
void VisitGuardedExpr(const Expr *Ex, const Expr *L, const Expr *R, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitGuardedExpr - Transfer function logic for ?, __builtin_choose.
void VisitCast(const CastExpr *CastE, const Expr *Ex, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitCast - Transfer function logic for all casts (implicit and explicit).
BasicValueFactory & getBasicVals()
Definition: ExprEngine.h:432
void VisitLogicalExpr(const BinaryOperator *B, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitLogicalExpr - Transfer function logic for '&&', '||'.
SVal evalBinOp(ProgramStateRef ST, BinaryOperator::Opcode Op, SVal LHS, SVal RHS, QualType T)
Definition: ExprEngine.h:621
void VisitUnaryOperator(const UnaryOperator *B, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitUnaryOperator - Transfer function logic for unary operators.
void VisitDeclStmt(const DeclStmt *DS, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitDeclStmt - Transfer function logic for DeclStmts.
ProgramStateRef handleLValueBitCast(ProgramStateRef state, const Expr *Ex, const LocationContext *LCtx, QualType T, QualType ExTy, const CastExpr *CastE, StmtNodeBuilder &Bldr, ExplodedNode *Pred)
static std::optional< SVal > getObjectUnderConstruction(ProgramStateRef State, const ConstructionContextItem &Item, const LocationContext *LC)
By looking at a certain item that may be potentially part of an object's ConstructionContext,...
Definition: ExprEngine.cpp:598
void VisitBlockExpr(const BlockExpr *BE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitBlockExpr - Transfer function logic for BlockExprs.
void VisitIncrementDecrementOperator(const UnaryOperator *U, ExplodedNode *Pred, ExplodedNodeSet &Dst)
Handle ++ and – (both pre- and post-increment).
ASTContext & getContext() const
getContext - Return the ASTContext associated with this analysis.
Definition: ExprEngine.h:204
StoreManager & getStoreManager()
Definition: ExprEngine.h:425
void handleUOExtension(ExplodedNodeSet::iterator I, const UnaryOperator *U, StmtNodeBuilder &Bldr)
void VisitInitListExpr(const InitListExpr *E, ExplodedNode *Pred, ExplodedNodeSet &Dst)
void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Ex, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitUnaryExprOrTypeTraitExpr - Transfer function for sizeof.
CheckerManager & getCheckerManager() const
Definition: ExprEngine.h:212
void VisitOffsetOfExpr(const OffsetOfExpr *Ex, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitOffsetOfExpr - Transfer function for offsetof.
void evalLoad(ExplodedNodeSet &Dst, const Expr *NodeEx, const Expr *BoundExpr, ExplodedNode *Pred, ProgramStateRef St, SVal location, const ProgramPointTag *tag=nullptr, QualType LoadTy=QualType())
Simulate a read of the result of Ex.
void VisitCompoundLiteralExpr(const CompoundLiteralExpr *CL, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitCompoundLiteralExpr - Transfer function logic for compound literals.
SValBuilder & getSValBuilder()
Definition: ExprEngine.h:216
void evalStore(ExplodedNodeSet &Dst, const Expr *AssignE, const Expr *StoreE, ExplodedNode *Pred, ProgramStateRef St, SVal TargetLV, SVal Val, const ProgramPointTag *tag=nullptr)
evalStore - Handle the semantics of a store via an assignment.
static bool isLocType(QualType T)
Definition: SVals.h:289
void takeNodes(const ExplodedNodeSet &S)
Definition: CoreEngine.h:342
void addNodes(const ExplodedNodeSet &S)
Definition: CoreEngine.h:348
const ExplodedNodeSet & getResults()
Definition: CoreEngine.h:319
DefinedOrUnknownSVal makeZeroVal(QualType type)
Construct an SVal representing '0' for the specified type.
Definition: SValBuilder.cpp:62
DefinedSVal getMemberPointer(const NamedDecl *ND)
NonLoc makePointerToMember(const DeclaratorDecl *DD)
Definition: SValBuilder.h:251
SVal evalMinus(NonLoc val)
SVal evalComplement(NonLoc val)
NonLoc makeCompoundVal(QualType type, llvm::ImmutableList< SVal > vals)
Definition: SValBuilder.h:241
DefinedSVal getBlockPointer(const BlockDecl *block, CanQualType locTy, const LocationContext *locContext, unsigned blockCount)
NonLoc makeArrayIndex(uint64_t idx)
Definition: SValBuilder.h:263
nonloc::ConcreteInt makeIntVal(const IntegerLiteral *integer)
Definition: SValBuilder.h:269
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'.
SVal evalEQ(ProgramStateRef state, SVal lhs, SVal rhs)
nonloc::ConcreteInt makeTruthVal(bool b, QualType type)
Definition: SValBuilder.h:329
loc::ConcreteInt makeNullWithType(QualType type)
Create NULL pointer, with proper pointer bit-width for given address space.
Definition: SValBuilder.h:340
SVal evalIntegralCast(ProgramStateRef state, SVal val, QualType castTy, QualType originalType)
SVal - This represents a symbolic expression, which can be either an L-value or an R-value.
Definition: SVals.h:72
bool isUndef() const
Definition: SVals.h:128
bool isZeroConstant() const
Definition: SVals.cpp:261
bool isUnknownOrUndef() const
Definition: SVals.h:132
bool isConstant() const
Definition: SVals.cpp:249
T castAs() const
Convert to the specified SVal type, asserting that this SVal is of the desired type.
Definition: SVals.h:99
bool isUnknown() const
Definition: SVals.h:124
This builder class is useful for generating nodes that resulted from visiting a statement.
Definition: CoreEngine.h:391
ExplodedNode * generateNode(const Stmt *S, ExplodedNode *Pred, ProgramStateRef St, const ProgramPointTag *tag=nullptr, ProgramPoint::Kind K=ProgramPoint::PostStmtKind)
Definition: CoreEngine.h:420
ExplodedNode * generateSink(const Stmt *S, ExplodedNode *Pred, ProgramStateRef St, const ProgramPointTag *tag=nullptr, ProgramPoint::Kind K=ProgramPoint::PostStmtKind)
Definition: CoreEngine.h:430
SVal evalDerivedToBase(SVal Derived, const CastExpr *Cast)
Evaluates a chain of derived-to-base casts through the path specified in Cast.
Definition: Store.cpp:251
std::optional< SVal > evalBaseToDerived(SVal Base, QualType DerivedPtrType)
Attempts to do a down cast.
Definition: Store.cpp:317
TypedValueRegion - An abstract class representing regions having a typed value.
Definition: MemRegion.h:531
const VarDecl * getDecl() const override=0
Value representing integer constant.
Definition: SVals.h:329
Value representing pointer-to-member.
Definition: SVals.h:441
@ PSK_EscapeOther
The reason for pointer escape is unknown.
BinaryOperatorKind
@ Result
The result type of a method or function.
EvalResult is a struct with detailed info about an evaluated expression.
Definition: Expr.h:623
unsigned blockCount() const
Returns the number of times the current basic block has been visited on the exploded graph path.
Definition: CoreEngine.h:231