clang 18.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/DeclCXX.h"
14#include "clang/AST/ExprCXX.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 (ExplodedNode *N : Tmp) {
137 state = N->getState();
138 const LocationContext *LCtx = N->getLocationContext();
139 SVal V = state->getSVal(LHS, LCtx);
140
141 // Get the computation type.
142 QualType CTy =
143 cast<CompoundAssignOperator>(B)->getComputationResultType();
144 CTy = getContext().getCanonicalType(CTy);
145
146 QualType CLHSTy =
147 cast<CompoundAssignOperator>(B)->getComputationLHSType();
148 CLHSTy = getContext().getCanonicalType(CLHSTy);
149
151
152 // Promote LHS.
153 V = svalBuilder.evalCast(V, CLHSTy, LTy);
154
155 // Compute the result of the operation.
156 SVal Result = svalBuilder.evalCast(evalBinOp(state, Op, V, RightV, CTy),
157 B->getType(), CTy);
158
159 // EXPERIMENTAL: "Conjured" symbols.
160 // FIXME: Handle structs.
161
162 SVal LHSVal;
163
164 if (Result.isUnknown()) {
165 // The symbolic value is actually for the type of the left-hand side
166 // expression, not the computation type, as this is the value the
167 // LValue on the LHS will bind to.
168 LHSVal = svalBuilder.conjureSymbolVal(nullptr, B->getRHS(), LCtx, LTy,
169 currBldrCtx->blockCount());
170 // However, we need to convert the symbol to the computation type.
171 Result = svalBuilder.evalCast(LHSVal, CTy, LTy);
172 } else {
173 // The left-hand side may bind to a different value then the
174 // computation type.
175 LHSVal = svalBuilder.evalCast(Result, LTy, CTy);
176 }
177
178 // In C++, assignment and compound assignment operators return an
179 // lvalue.
180 if (B->isGLValue())
181 state = state->BindExpr(B, LCtx, location);
182 else
183 state = state->BindExpr(B, LCtx, Result);
184
185 evalStore(Tmp2, B, LHS, N, state, location, LHSVal);
186 }
187 }
188
189 // FIXME: postvisits eventually go in ::Visit()
190 getCheckerManager().runCheckersForPostStmt(Dst, Tmp2, B, *this);
191}
192
194 ExplodedNodeSet &Dst) {
195
197
198 const BlockDecl *BD = BE->getBlockDecl();
199 // Get the value of the block itself.
200 SVal V = svalBuilder.getBlockPointer(BD, T,
201 Pred->getLocationContext(),
202 currBldrCtx->blockCount());
203
204 ProgramStateRef State = Pred->getState();
205
206 // If we created a new MemRegion for the block, we should explicitly bind
207 // the captured variables.
208 if (const BlockDataRegion *BDR =
209 dyn_cast_or_null<BlockDataRegion>(V.getAsRegion())) {
210
211 auto ReferencedVars = BDR->referenced_vars();
212 auto CI = BD->capture_begin();
213 auto CE = BD->capture_end();
214 for (auto Var : ReferencedVars) {
215 const VarRegion *capturedR = Var.getCapturedRegion();
216 const TypedValueRegion *originalR = Var.getOriginalRegion();
217
218 // If the capture had a copy expression, use the result of evaluating
219 // that expression, otherwise use the original value.
220 // We rely on the invariant that the block declaration's capture variables
221 // are a prefix of the BlockDataRegion's referenced vars (which may include
222 // referenced globals, etc.) to enable fast lookup of the capture for a
223 // given referenced var.
224 const Expr *copyExpr = nullptr;
225 if (CI != CE) {
226 assert(CI->getVariable() == capturedR->getDecl());
227 copyExpr = CI->getCopyExpr();
228 CI++;
229 }
230
231 if (capturedR != originalR) {
232 SVal originalV;
233 const LocationContext *LCtx = Pred->getLocationContext();
234 if (copyExpr) {
235 originalV = State->getSVal(copyExpr, LCtx);
236 } else {
237 originalV = State->getSVal(loc::MemRegionVal(originalR));
238 }
239 State = State->bindLoc(loc::MemRegionVal(capturedR), originalV, LCtx);
240 }
241 }
242 }
243
244 ExplodedNodeSet Tmp;
245 StmtNodeBuilder Bldr(Pred, Tmp, *currBldrCtx);
246 Bldr.generateNode(BE, Pred,
247 State->BindExpr(BE, Pred->getLocationContext(), V),
249
250 // FIXME: Move all post/pre visits to ::Visit().
251 getCheckerManager().runCheckersForPostStmt(Dst, Tmp, BE, *this);
252}
253
255 ProgramStateRef state, const Expr* Ex, const LocationContext* LCtx,
256 QualType T, QualType ExTy, const CastExpr* CastE, StmtNodeBuilder& Bldr,
257 ExplodedNode* Pred) {
258 if (T->isLValueReferenceType()) {
259 assert(!CastE->getType()->isLValueReferenceType());
260 ExTy = getContext().getLValueReferenceType(ExTy);
261 } else if (T->isRValueReferenceType()) {
262 assert(!CastE->getType()->isRValueReferenceType());
263 ExTy = getContext().getRValueReferenceType(ExTy);
264 }
265 // Delegate to SValBuilder to process.
266 SVal OrigV = state->getSVal(Ex, LCtx);
267 SVal SimplifiedOrigV = svalBuilder.simplifySVal(state, OrigV);
268 SVal V = svalBuilder.evalCast(SimplifiedOrigV, T, ExTy);
269 // Negate the result if we're treating the boolean as a signed i1
270 if (CastE->getCastKind() == CK_BooleanToSignedIntegral && V.isValid())
271 V = svalBuilder.evalMinus(V.castAs<NonLoc>());
272
273 state = state->BindExpr(CastE, LCtx, V);
274 if (V.isUnknown() && !OrigV.isUnknown()) {
275 state = escapeValues(state, OrigV, PSK_EscapeOther);
276 }
277 Bldr.generateNode(CastE, Pred, state);
278
279 return state;
280}
281
282void ExprEngine::VisitCast(const CastExpr *CastE, const Expr *Ex,
283 ExplodedNode *Pred, ExplodedNodeSet &Dst) {
284
285 ExplodedNodeSet dstPreStmt;
286 getCheckerManager().runCheckersForPreStmt(dstPreStmt, Pred, CastE, *this);
287
288 if (CastE->getCastKind() == CK_LValueToRValue ||
289 CastE->getCastKind() == CK_LValueToRValueBitCast) {
290 for (ExplodedNode *subExprNode : dstPreStmt) {
291 ProgramStateRef state = subExprNode->getState();
292 const LocationContext *LCtx = subExprNode->getLocationContext();
293 evalLoad(Dst, CastE, CastE, subExprNode, state, state->getSVal(Ex, LCtx));
294 }
295 return;
296 }
297
298 // All other casts.
299 QualType T = CastE->getType();
300 QualType ExTy = Ex->getType();
301
302 if (const ExplicitCastExpr *ExCast=dyn_cast_or_null<ExplicitCastExpr>(CastE))
303 T = ExCast->getTypeAsWritten();
304
305 StmtNodeBuilder Bldr(dstPreStmt, Dst, *currBldrCtx);
306 for (ExplodedNode *Pred : dstPreStmt) {
307 ProgramStateRef state = Pred->getState();
308 const LocationContext *LCtx = Pred->getLocationContext();
309
310 switch (CastE->getCastKind()) {
311 case CK_LValueToRValue:
312 case CK_LValueToRValueBitCast:
313 llvm_unreachable("LValueToRValue casts handled earlier.");
314 case CK_ToVoid:
315 continue;
316 // The analyzer doesn't do anything special with these casts,
317 // since it understands retain/release semantics already.
318 case CK_ARCProduceObject:
319 case CK_ARCConsumeObject:
320 case CK_ARCReclaimReturnedObject:
321 case CK_ARCExtendBlockObject: // Fall-through.
322 case CK_CopyAndAutoreleaseBlockObject:
323 // The analyser can ignore atomic casts for now, although some future
324 // checkers may want to make certain that you're not modifying the same
325 // value through atomic and nonatomic pointers.
326 case CK_AtomicToNonAtomic:
327 case CK_NonAtomicToAtomic:
328 // True no-ops.
329 case CK_NoOp:
330 case CK_ConstructorConversion:
331 case CK_UserDefinedConversion:
332 case CK_FunctionToPointerDecay:
333 case CK_BuiltinFnToFnPtr: {
334 // Copy the SVal of Ex to CastE.
335 ProgramStateRef state = Pred->getState();
336 const LocationContext *LCtx = Pred->getLocationContext();
337 SVal V = state->getSVal(Ex, LCtx);
338 state = state->BindExpr(CastE, LCtx, V);
339 Bldr.generateNode(CastE, Pred, state);
340 continue;
341 }
342 case CK_MemberPointerToBoolean:
343 case CK_PointerToBoolean: {
344 SVal V = state->getSVal(Ex, LCtx);
345 auto PTMSV = V.getAs<nonloc::PointerToMember>();
346 if (PTMSV)
347 V = svalBuilder.makeTruthVal(!PTMSV->isNullMemberPointer(), ExTy);
348 if (V.isUndef() || PTMSV) {
349 state = state->BindExpr(CastE, LCtx, V);
350 Bldr.generateNode(CastE, Pred, state);
351 continue;
352 }
353 // Explicitly proceed with default handler for this case cascade.
354 state =
355 handleLValueBitCast(state, Ex, LCtx, T, ExTy, CastE, Bldr, Pred);
356 continue;
357 }
358 case CK_Dependent:
359 case CK_ArrayToPointerDecay:
360 case CK_BitCast:
361 case CK_AddressSpaceConversion:
362 case CK_BooleanToSignedIntegral:
363 case CK_IntegralToPointer:
364 case CK_PointerToIntegral: {
365 SVal V = state->getSVal(Ex, LCtx);
366 if (isa<nonloc::PointerToMember>(V)) {
367 state = state->BindExpr(CastE, LCtx, UnknownVal());
368 Bldr.generateNode(CastE, Pred, state);
369 continue;
370 }
371 // Explicitly proceed with default handler for this case cascade.
372 state =
373 handleLValueBitCast(state, Ex, LCtx, T, ExTy, CastE, Bldr, Pred);
374 continue;
375 }
376 case CK_IntegralToBoolean:
377 case CK_IntegralToFloating:
378 case CK_FloatingToIntegral:
379 case CK_FloatingToBoolean:
380 case CK_FloatingCast:
381 case CK_FloatingRealToComplex:
382 case CK_FloatingComplexToReal:
383 case CK_FloatingComplexToBoolean:
384 case CK_FloatingComplexCast:
385 case CK_FloatingComplexToIntegralComplex:
386 case CK_IntegralRealToComplex:
387 case CK_IntegralComplexToReal:
388 case CK_IntegralComplexToBoolean:
389 case CK_IntegralComplexCast:
390 case CK_IntegralComplexToFloatingComplex:
391 case CK_CPointerToObjCPointerCast:
392 case CK_BlockPointerToObjCPointerCast:
393 case CK_AnyPointerToBlockPointerCast:
394 case CK_ObjCObjectLValueCast:
395 case CK_ZeroToOCLOpaqueType:
396 case CK_IntToOCLSampler:
397 case CK_LValueBitCast:
398 case CK_FloatingToFixedPoint:
399 case CK_FixedPointToFloating:
400 case CK_FixedPointCast:
401 case CK_FixedPointToBoolean:
402 case CK_FixedPointToIntegral:
403 case CK_IntegralToFixedPoint: {
404 state =
405 handleLValueBitCast(state, Ex, LCtx, T, ExTy, CastE, Bldr, Pred);
406 continue;
407 }
408 case CK_IntegralCast: {
409 // Delegate to SValBuilder to process.
410 SVal V = state->getSVal(Ex, LCtx);
411 if (AMgr.options.ShouldSupportSymbolicIntegerCasts)
412 V = svalBuilder.evalCast(V, T, ExTy);
413 else
414 V = svalBuilder.evalIntegralCast(state, V, T, ExTy);
415 state = state->BindExpr(CastE, LCtx, V);
416 Bldr.generateNode(CastE, Pred, state);
417 continue;
418 }
419 case CK_DerivedToBase:
420 case CK_UncheckedDerivedToBase: {
421 // For DerivedToBase cast, delegate to the store manager.
422 SVal val = state->getSVal(Ex, LCtx);
423 val = getStoreManager().evalDerivedToBase(val, CastE);
424 state = state->BindExpr(CastE, LCtx, val);
425 Bldr.generateNode(CastE, Pred, state);
426 continue;
427 }
428 // Handle C++ dyn_cast.
429 case CK_Dynamic: {
430 SVal val = state->getSVal(Ex, LCtx);
431
432 // Compute the type of the result.
433 QualType resultType = CastE->getType();
434 if (CastE->isGLValue())
435 resultType = getContext().getPointerType(resultType);
436
437 bool Failed = true;
438
439 // Check if the value being cast does not evaluates to 0.
440 if (!val.isZeroConstant())
441 if (std::optional<SVal> V =
442 StateMgr.getStoreManager().evalBaseToDerived(val, T)) {
443 val = *V;
444 Failed = false;
445 }
446
447 if (Failed) {
448 if (T->isReferenceType()) {
449 // A bad_cast exception is thrown if input value is a reference.
450 // Currently, we model this, by generating a sink.
451 Bldr.generateSink(CastE, Pred, state);
452 continue;
453 } else {
454 // If the cast fails on a pointer, bind to 0.
455 state = state->BindExpr(CastE, LCtx,
456 svalBuilder.makeNullWithType(resultType));
457 }
458 } else {
459 // If we don't know if the cast succeeded, conjure a new symbol.
460 if (val.isUnknown()) {
461 DefinedOrUnknownSVal NewSym =
462 svalBuilder.conjureSymbolVal(nullptr, CastE, LCtx, resultType,
463 currBldrCtx->blockCount());
464 state = state->BindExpr(CastE, LCtx, NewSym);
465 } else
466 // Else, bind to the derived region value.
467 state = state->BindExpr(CastE, LCtx, val);
468 }
469 Bldr.generateNode(CastE, Pred, state);
470 continue;
471 }
472 case CK_BaseToDerived: {
473 SVal val = state->getSVal(Ex, LCtx);
474 QualType resultType = CastE->getType();
475 if (CastE->isGLValue())
476 resultType = getContext().getPointerType(resultType);
477
478 if (!val.isConstant()) {
479 std::optional<SVal> V = getStoreManager().evalBaseToDerived(val, T);
480 val = V ? *V : UnknownVal();
481 }
482
483 // Failed to cast or the result is unknown, fall back to conservative.
484 if (val.isUnknown()) {
485 val =
486 svalBuilder.conjureSymbolVal(nullptr, CastE, LCtx, resultType,
487 currBldrCtx->blockCount());
488 }
489 state = state->BindExpr(CastE, LCtx, val);
490 Bldr.generateNode(CastE, Pred, state);
491 continue;
492 }
493 case CK_NullToPointer: {
494 SVal V = svalBuilder.makeNullWithType(CastE->getType());
495 state = state->BindExpr(CastE, LCtx, V);
496 Bldr.generateNode(CastE, Pred, state);
497 continue;
498 }
499 case CK_NullToMemberPointer: {
500 SVal V = svalBuilder.getMemberPointer(nullptr);
501 state = state->BindExpr(CastE, LCtx, V);
502 Bldr.generateNode(CastE, Pred, state);
503 continue;
504 }
505 case CK_DerivedToBaseMemberPointer:
506 case CK_BaseToDerivedMemberPointer:
507 case CK_ReinterpretMemberPointer: {
508 SVal V = state->getSVal(Ex, LCtx);
509 if (auto PTMSV = V.getAs<nonloc::PointerToMember>()) {
510 SVal CastedPTMSV =
511 svalBuilder.makePointerToMember(getBasicVals().accumCXXBase(
512 CastE->path(), *PTMSV, CastE->getCastKind()));
513 state = state->BindExpr(CastE, LCtx, CastedPTMSV);
514 Bldr.generateNode(CastE, Pred, state);
515 continue;
516 }
517 // Explicitly proceed with default handler for this case cascade.
518 }
519 [[fallthrough]];
520 // Various C++ casts that are not handled yet.
521 case CK_ToUnion:
522 case CK_MatrixCast:
523 case CK_VectorSplat: {
524 QualType resultType = CastE->getType();
525 if (CastE->isGLValue())
526 resultType = getContext().getPointerType(resultType);
527 SVal result = svalBuilder.conjureSymbolVal(
528 /*symbolTag=*/nullptr, CastE, LCtx, resultType,
529 currBldrCtx->blockCount());
530 state = state->BindExpr(CastE, LCtx, result);
531 Bldr.generateNode(CastE, Pred, state);
532 continue;
533 }
534 }
535 }
536}
537
539 ExplodedNode *Pred,
540 ExplodedNodeSet &Dst) {
541 StmtNodeBuilder B(Pred, Dst, *currBldrCtx);
542
543 ProgramStateRef State = Pred->getState();
544 const LocationContext *LCtx = Pred->getLocationContext();
545
546 const Expr *Init = CL->getInitializer();
547 SVal V = State->getSVal(CL->getInitializer(), LCtx);
548
549 if (isa<CXXConstructExpr, CXXStdInitializerListExpr>(Init)) {
550 // No work needed. Just pass the value up to this expression.
551 } else {
552 assert(isa<InitListExpr>(Init));
553 Loc CLLoc = State->getLValue(CL, LCtx);
554 State = State->bindLoc(CLLoc, V, LCtx);
555
556 if (CL->isGLValue())
557 V = CLLoc;
558 }
559
560 B.generateNode(CL, Pred, State->BindExpr(CL, LCtx, V));
561}
562
564 ExplodedNodeSet &Dst) {
565 if (isa<TypedefNameDecl>(*DS->decl_begin())) {
566 // C99 6.7.7 "Any array size expressions associated with variable length
567 // array declarators are evaluated each time the declaration of the typedef
568 // name is reached in the order of execution."
569 // The checkers should know about typedef to be able to handle VLA size
570 // expressions.
571 ExplodedNodeSet DstPre;
572 getCheckerManager().runCheckersForPreStmt(DstPre, Pred, DS, *this);
573 getCheckerManager().runCheckersForPostStmt(Dst, DstPre, DS, *this);
574 return;
575 }
576
577 // Assumption: The CFG has one DeclStmt per Decl.
578 const VarDecl *VD = dyn_cast_or_null<VarDecl>(*DS->decl_begin());
579
580 if (!VD) {
581 //TODO:AZ: remove explicit insertion after refactoring is done.
582 Dst.insert(Pred);
583 return;
584 }
585
586 // FIXME: all pre/post visits should eventually be handled by ::Visit().
587 ExplodedNodeSet dstPreVisit;
588 getCheckerManager().runCheckersForPreStmt(dstPreVisit, Pred, DS, *this);
589
590 ExplodedNodeSet dstEvaluated;
591 StmtNodeBuilder B(dstPreVisit, dstEvaluated, *currBldrCtx);
592 for (ExplodedNodeSet::iterator I = dstPreVisit.begin(), E = dstPreVisit.end();
593 I!=E; ++I) {
594 ExplodedNode *N = *I;
595 ProgramStateRef state = N->getState();
596 const LocationContext *LC = N->getLocationContext();
597
598 // Decls without InitExpr are not initialized explicitly.
599 if (const Expr *InitEx = VD->getInit()) {
600
601 // Note in the state that the initialization has occurred.
602 ExplodedNode *UpdatedN = N;
603 SVal InitVal = state->getSVal(InitEx, LC);
604
605 assert(DS->isSingleDecl());
606 if (getObjectUnderConstruction(state, DS, LC)) {
607 state = finishObjectConstruction(state, DS, LC);
608 // We constructed the object directly in the variable.
609 // No need to bind anything.
610 B.generateNode(DS, UpdatedN, state);
611 } else {
612 // Recover some path-sensitivity if a scalar value evaluated to
613 // UnknownVal.
614 if (InitVal.isUnknown()) {
615 QualType Ty = InitEx->getType();
616 if (InitEx->isGLValue()) {
617 Ty = getContext().getPointerType(Ty);
618 }
619
620 InitVal = svalBuilder.conjureSymbolVal(nullptr, InitEx, LC, Ty,
621 currBldrCtx->blockCount());
622 }
623
624
625 B.takeNodes(UpdatedN);
626 ExplodedNodeSet Dst2;
627 evalBind(Dst2, DS, UpdatedN, state->getLValue(VD, LC), InitVal, true);
628 B.addNodes(Dst2);
629 }
630 }
631 else {
632 B.generateNode(DS, N, state);
633 }
634 }
635
637}
638
640 ExplodedNodeSet &Dst) {
641 // This method acts upon CFG elements for logical operators && and ||
642 // and attaches the value (true or false) to them as expressions.
643 // It doesn't produce any state splits.
644 // If we made it that far, we're past the point when we modeled the short
645 // circuit. It means that we should have precise knowledge about whether
646 // we've short-circuited. If we did, we already know the value we need to
647 // bind. If we didn't, the value of the RHS (casted to the boolean type)
648 // is the answer.
649 // Currently this method tries to figure out whether we've short-circuited
650 // by looking at the ExplodedGraph. This method is imperfect because there
651 // could inevitably have been merges that would have resulted in multiple
652 // potential path traversal histories. We bail out when we fail.
653 // Due to this ambiguity, a more reliable solution would have been to
654 // track the short circuit operation history path-sensitively until
655 // we evaluate the respective logical operator.
656 assert(B->getOpcode() == BO_LAnd ||
657 B->getOpcode() == BO_LOr);
658
659 StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx);
660 ProgramStateRef state = Pred->getState();
661
662 if (B->getType()->isVectorType()) {
663 // FIXME: We do not model vector arithmetic yet. When adding support for
664 // that, note that the CFG-based reasoning below does not apply, because
665 // logical operators on vectors are not short-circuit. Currently they are
666 // modeled as short-circuit in Clang CFG but this is incorrect.
667 // Do not set the value for the expression. It'd be UnknownVal by default.
668 Bldr.generateNode(B, Pred, state);
669 return;
670 }
671
672 ExplodedNode *N = Pred;
673 while (!N->getLocation().getAs<BlockEntrance>()) {
675 assert(P.getAs<PreStmt>()|| P.getAs<PreStmtPurgeDeadSymbols>());
676 (void) P;
677 if (N->pred_size() != 1) {
678 // We failed to track back where we came from.
679 Bldr.generateNode(B, Pred, state);
680 return;
681 }
682 N = *N->pred_begin();
683 }
684
685 if (N->pred_size() != 1) {
686 // We failed to track back where we came from.
687 Bldr.generateNode(B, Pred, state);
688 return;
689 }
690
691 N = *N->pred_begin();
693 SVal X;
694
695 // Determine the value of the expression by introspecting how we
696 // got this location in the CFG. This requires looking at the previous
697 // block we were in and what kind of control-flow transfer was involved.
698 const CFGBlock *SrcBlock = BE.getSrc();
699 // The only terminator (if there is one) that makes sense is a logical op.
700 CFGTerminator T = SrcBlock->getTerminator();
701 if (const BinaryOperator *Term = cast_or_null<BinaryOperator>(T.getStmt())) {
702 (void) Term;
703 assert(Term->isLogicalOp());
704 assert(SrcBlock->succ_size() == 2);
705 // Did we take the true or false branch?
706 unsigned constant = (*SrcBlock->succ_begin() == BE.getDst()) ? 1 : 0;
707 X = svalBuilder.makeIntVal(constant, B->getType());
708 }
709 else {
710 // If there is no terminator, by construction the last statement
711 // in SrcBlock is the value of the enclosing expression.
712 // However, we still need to constrain that value to be 0 or 1.
713 assert(!SrcBlock->empty());
714 CFGStmt Elem = SrcBlock->rbegin()->castAs<CFGStmt>();
715 const Expr *RHS = cast<Expr>(Elem.getStmt());
716 SVal RHSVal = N->getState()->getSVal(RHS, Pred->getLocationContext());
717
718 if (RHSVal.isUndef()) {
719 X = RHSVal;
720 } else {
721 // We evaluate "RHSVal != 0" expression which result in 0 if the value is
722 // known to be false, 1 if the value is known to be true and a new symbol
723 // when the assumption is unknown.
724 nonloc::ConcreteInt Zero(getBasicVals().getValue(0, B->getType()));
725 X = evalBinOp(N->getState(), BO_NE,
726 svalBuilder.evalCast(RHSVal, B->getType(), RHS->getType()),
727 Zero, B->getType());
728 }
729 }
730 Bldr.generateNode(B, Pred, state->BindExpr(B, Pred->getLocationContext(), X));
731}
732
734 ExplodedNode *Pred,
735 ExplodedNodeSet &Dst) {
736 StmtNodeBuilder B(Pred, Dst, *currBldrCtx);
737
738 ProgramStateRef state = Pred->getState();
739 const LocationContext *LCtx = Pred->getLocationContext();
741 unsigned NumInitElements = IE->getNumInits();
742
743 if (!IE->isGLValue() && !IE->isTransparent() &&
744 (T->isArrayType() || T->isRecordType() || T->isVectorType() ||
745 T->isAnyComplexType())) {
746 llvm::ImmutableList<SVal> vals = getBasicVals().getEmptySValList();
747
748 // Handle base case where the initializer has no elements.
749 // e.g: static int* myArray[] = {};
750 if (NumInitElements == 0) {
751 SVal V = svalBuilder.makeCompoundVal(T, vals);
752 B.generateNode(IE, Pred, state->BindExpr(IE, LCtx, V));
753 return;
754 }
755
756 for (const Stmt *S : llvm::reverse(*IE)) {
757 SVal V = state->getSVal(cast<Expr>(S), LCtx);
758 vals = getBasicVals().prependSVal(V, vals);
759 }
760
761 B.generateNode(IE, Pred,
762 state->BindExpr(IE, LCtx,
763 svalBuilder.makeCompoundVal(T, vals)));
764 return;
765 }
766
767 // Handle scalars: int{5} and int{} and GLvalues.
768 // Note, if the InitListExpr is a GLvalue, it means that there is an address
769 // representing it, so it must have a single init element.
770 assert(NumInitElements <= 1);
771
772 SVal V;
773 if (NumInitElements == 0)
775 else
776 V = state->getSVal(IE->getInit(0), LCtx);
777
778 B.generateNode(IE, Pred, state->BindExpr(IE, LCtx, V));
779}
780
782 const Expr *L,
783 const Expr *R,
784 ExplodedNode *Pred,
785 ExplodedNodeSet &Dst) {
786 assert(L && R);
787
788 StmtNodeBuilder B(Pred, Dst, *currBldrCtx);
789 ProgramStateRef state = Pred->getState();
790 const LocationContext *LCtx = Pred->getLocationContext();
791 const CFGBlock *SrcBlock = nullptr;
792
793 // Find the predecessor block.
794 ProgramStateRef SrcState = state;
795 for (const ExplodedNode *N = Pred ; N ; N = *N->pred_begin()) {
796 ProgramPoint PP = N->getLocation();
798 // If the state N has multiple predecessors P, it means that successors
799 // of P are all equivalent.
800 // In turn, that means that all nodes at P are equivalent in terms
801 // of observable behavior at N, and we can follow any of them.
802 // FIXME: a more robust solution which does not walk up the tree.
803 continue;
804 }
805 SrcBlock = PP.castAs<BlockEdge>().getSrc();
806 SrcState = N->getState();
807 break;
808 }
809
810 assert(SrcBlock && "missing function entry");
811
812 // Find the last expression in the predecessor block. That is the
813 // expression that is used for the value of the ternary expression.
814 bool hasValue = false;
815 SVal V;
816
817 for (CFGElement CE : llvm::reverse(*SrcBlock)) {
818 if (std::optional<CFGStmt> CS = CE.getAs<CFGStmt>()) {
819 const Expr *ValEx = cast<Expr>(CS->getStmt());
820 ValEx = ValEx->IgnoreParens();
821
822 // For GNU extension '?:' operator, the left hand side will be an
823 // OpaqueValueExpr, so get the underlying expression.
824 if (const OpaqueValueExpr *OpaqueEx = dyn_cast<OpaqueValueExpr>(L))
825 L = OpaqueEx->getSourceExpr();
826
827 // If the last expression in the predecessor block matches true or false
828 // subexpression, get its the value.
829 if (ValEx == L->IgnoreParens() || ValEx == R->IgnoreParens()) {
830 hasValue = true;
831 V = SrcState->getSVal(ValEx, LCtx);
832 }
833 break;
834 }
835 }
836
837 if (!hasValue)
838 V = svalBuilder.conjureSymbolVal(nullptr, Ex, LCtx,
839 currBldrCtx->blockCount());
840
841 // Generate a new node with the binding from the appropriate path.
842 B.generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V, true));
843}
844
847 ExplodedNode *Pred, ExplodedNodeSet &Dst) {
848 StmtNodeBuilder B(Pred, Dst, *currBldrCtx);
850 if (OOE->EvaluateAsInt(Result, getContext())) {
851 APSInt IV = Result.Val.getInt();
852 assert(IV.getBitWidth() == getContext().getTypeSize(OOE->getType()));
853 assert(OOE->getType()->castAs<BuiltinType>()->isInteger());
854 assert(IV.isSigned() == OOE->getType()->isSignedIntegerType());
855 SVal X = svalBuilder.makeIntVal(IV);
856 B.generateNode(OOE, Pred,
857 Pred->getState()->BindExpr(OOE, Pred->getLocationContext(),
858 X));
859 }
860 // FIXME: Handle the case where __builtin_offsetof is not a constant.
861}
862
863
866 ExplodedNode *Pred,
867 ExplodedNodeSet &Dst) {
868 // FIXME: Prechecks eventually go in ::Visit().
869 ExplodedNodeSet CheckedSet;
870 getCheckerManager().runCheckersForPreStmt(CheckedSet, Pred, Ex, *this);
871
872 ExplodedNodeSet EvalSet;
873 StmtNodeBuilder Bldr(CheckedSet, EvalSet, *currBldrCtx);
874
875 QualType T = Ex->getTypeOfArgument();
876
877 for (ExplodedNode *N : CheckedSet) {
878 if (Ex->getKind() == UETT_SizeOf) {
879 if (!T->isIncompleteType() && !T->isConstantSizeType()) {
880 assert(T->isVariableArrayType() && "Unknown non-constant-sized type.");
881
882 // FIXME: Add support for VLA type arguments and VLA expressions.
883 // When that happens, we should probably refactor VLASizeChecker's code.
884 continue;
885 } else if (T->getAs<ObjCObjectType>()) {
886 // Some code tries to take the sizeof an ObjCObjectType, relying that
887 // the compiler has laid out its representation. Just report Unknown
888 // for these.
889 continue;
890 }
891 }
892
894 CharUnits amt = CharUnits::fromQuantity(Value.getZExtValue());
895
896 ProgramStateRef state = N->getState();
897 state = state->BindExpr(
898 Ex, N->getLocationContext(),
899 svalBuilder.makeIntVal(amt.getQuantity(), Ex->getType()));
900 Bldr.generateNode(Ex, N, state);
901 }
902
903 getCheckerManager().runCheckersForPostStmt(Dst, EvalSet, Ex, *this);
904}
905
907 StmtNodeBuilder &Bldr) {
908 // FIXME: We can probably just have some magic in Environment::getSVal()
909 // that propagates values, instead of creating a new node here.
910 //
911 // Unary "+" is a no-op, similar to a parentheses. We still have places
912 // where it may be a block-level expression, so we need to
913 // generate an extra node that just propagates the value of the
914 // subexpression.
915 const Expr *Ex = U->getSubExpr()->IgnoreParens();
916 ProgramStateRef state = N->getState();
917 const LocationContext *LCtx = N->getLocationContext();
918 Bldr.generateNode(U, N, state->BindExpr(U, LCtx, state->getSVal(Ex, LCtx)));
919}
920
922 ExplodedNodeSet &Dst) {
923 // FIXME: Prechecks eventually go in ::Visit().
924 ExplodedNodeSet CheckedSet;
925 getCheckerManager().runCheckersForPreStmt(CheckedSet, Pred, U, *this);
926
927 ExplodedNodeSet EvalSet;
928 StmtNodeBuilder Bldr(CheckedSet, EvalSet, *currBldrCtx);
929
930 for (ExplodedNode *N : CheckedSet) {
931 switch (U->getOpcode()) {
932 default: {
933 Bldr.takeNodes(N);
934 ExplodedNodeSet Tmp;
936 Bldr.addNodes(Tmp);
937 break;
938 }
939 case UO_Real: {
940 const Expr *Ex = U->getSubExpr()->IgnoreParens();
941
942 // FIXME: We don't have complex SValues yet.
943 if (Ex->getType()->isAnyComplexType()) {
944 // Just report "Unknown."
945 break;
946 }
947
948 // For all other types, UO_Real is an identity operation.
949 assert (U->getType() == Ex->getType());
950 ProgramStateRef state = N->getState();
951 const LocationContext *LCtx = N->getLocationContext();
952 Bldr.generateNode(U, N,
953 state->BindExpr(U, LCtx, state->getSVal(Ex, LCtx)));
954 break;
955 }
956
957 case UO_Imag: {
958 const Expr *Ex = U->getSubExpr()->IgnoreParens();
959 // FIXME: We don't have complex SValues yet.
960 if (Ex->getType()->isAnyComplexType()) {
961 // Just report "Unknown."
962 break;
963 }
964 // For all other types, UO_Imag returns 0.
965 ProgramStateRef state = N->getState();
966 const LocationContext *LCtx = N->getLocationContext();
967 SVal X = svalBuilder.makeZeroVal(Ex->getType());
968 Bldr.generateNode(U, N, state->BindExpr(U, LCtx, X));
969 break;
970 }
971
972 case UO_AddrOf: {
973 // Process pointer-to-member address operation.
974 const Expr *Ex = U->getSubExpr()->IgnoreParens();
975 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Ex)) {
976 const ValueDecl *VD = DRE->getDecl();
977
978 if (isa<CXXMethodDecl, FieldDecl, IndirectFieldDecl>(VD)) {
979 ProgramStateRef State = N->getState();
980 const LocationContext *LCtx = N->getLocationContext();
981 SVal SV = svalBuilder.getMemberPointer(cast<NamedDecl>(VD));
982 Bldr.generateNode(U, N, State->BindExpr(U, LCtx, SV));
983 break;
984 }
985 }
986 // Explicitly proceed with default handler for this case cascade.
987 handleUOExtension(N, U, Bldr);
988 break;
989 }
990 case UO_Plus:
991 assert(!U->isGLValue());
992 [[fallthrough]];
993 case UO_Deref:
994 case UO_Extension: {
995 handleUOExtension(N, U, Bldr);
996 break;
997 }
998
999 case UO_LNot:
1000 case UO_Minus:
1001 case UO_Not: {
1002 assert (!U->isGLValue());
1003 const Expr *Ex = U->getSubExpr()->IgnoreParens();
1004 ProgramStateRef state = N->getState();
1005 const LocationContext *LCtx = N->getLocationContext();
1006
1007 // Get the value of the subexpression.
1008 SVal V = state->getSVal(Ex, LCtx);
1009
1010 if (V.isUnknownOrUndef()) {
1011 Bldr.generateNode(U, N, state->BindExpr(U, LCtx, V));
1012 break;
1013 }
1014
1015 switch (U->getOpcode()) {
1016 default:
1017 llvm_unreachable("Invalid Opcode.");
1018 case UO_Not:
1019 // FIXME: Do we need to handle promotions?
1020 state = state->BindExpr(
1021 U, LCtx, svalBuilder.evalComplement(V.castAs<NonLoc>()));
1022 break;
1023 case UO_Minus:
1024 // FIXME: Do we need to handle promotions?
1025 state = state->BindExpr(U, LCtx,
1026 svalBuilder.evalMinus(V.castAs<NonLoc>()));
1027 break;
1028 case UO_LNot:
1029 // C99 6.5.3.3: "The expression !E is equivalent to (0==E)."
1030 //
1031 // Note: technically we do "E == 0", but this is the same in the
1032 // transfer functions as "0 == E".
1033 SVal Result;
1034 if (std::optional<Loc> LV = V.getAs<Loc>()) {
1035 Loc X = svalBuilder.makeNullWithType(Ex->getType());
1036 Result = evalBinOp(state, BO_EQ, *LV, X, U->getType());
1037 } else if (Ex->getType()->isFloatingType()) {
1038 // FIXME: handle floating point types.
1039 Result = UnknownVal();
1040 } else {
1041 nonloc::ConcreteInt X(getBasicVals().getValue(0, Ex->getType()));
1042 Result = evalBinOp(state, BO_EQ, V.castAs<NonLoc>(), X, U->getType());
1043 }
1044
1045 state = state->BindExpr(U, LCtx, Result);
1046 break;
1047 }
1048 Bldr.generateNode(U, N, state);
1049 break;
1050 }
1051 }
1052 }
1053
1054 getCheckerManager().runCheckersForPostStmt(Dst, EvalSet, U, *this);
1055}
1056
1058 ExplodedNode *Pred,
1059 ExplodedNodeSet &Dst) {
1060 // Handle ++ and -- (both pre- and post-increment).
1061 assert (U->isIncrementDecrementOp());
1062 const Expr *Ex = U->getSubExpr()->IgnoreParens();
1063
1064 const LocationContext *LCtx = Pred->getLocationContext();
1065 ProgramStateRef state = Pred->getState();
1066 SVal loc = state->getSVal(Ex, LCtx);
1067
1068 // Perform a load.
1069 ExplodedNodeSet Tmp;
1070 evalLoad(Tmp, U, Ex, Pred, state, loc);
1071
1072 ExplodedNodeSet Dst2;
1073 StmtNodeBuilder Bldr(Tmp, Dst2, *currBldrCtx);
1074 for (ExplodedNode *N : Tmp) {
1075 state = N->getState();
1076 assert(LCtx == N->getLocationContext());
1077 SVal V2_untested = state->getSVal(Ex, LCtx);
1078
1079 // Propagate unknown and undefined values.
1080 if (V2_untested.isUnknownOrUndef()) {
1081 state = state->BindExpr(U, LCtx, V2_untested);
1082
1083 // Perform the store, so that the uninitialized value detection happens.
1084 Bldr.takeNodes(N);
1085 ExplodedNodeSet Dst3;
1086 evalStore(Dst3, U, Ex, N, state, loc, V2_untested);
1087 Bldr.addNodes(Dst3);
1088
1089 continue;
1090 }
1091 DefinedSVal V2 = V2_untested.castAs<DefinedSVal>();
1092
1093 // Handle all other values.
1094 BinaryOperator::Opcode Op = U->isIncrementOp() ? BO_Add : BO_Sub;
1095
1096 // If the UnaryOperator has non-location type, use its type to create the
1097 // constant value. If the UnaryOperator has location type, create the
1098 // constant with int type and pointer width.
1099 SVal RHS;
1100 SVal Result;
1101
1102 if (U->getType()->isAnyPointerType())
1103 RHS = svalBuilder.makeArrayIndex(1);
1104 else if (U->getType()->isIntegralOrEnumerationType())
1105 RHS = svalBuilder.makeIntVal(1, U->getType());
1106 else
1107 RHS = UnknownVal();
1108
1109 // The use of an operand of type bool with the ++ operators is deprecated
1110 // but valid until C++17. And if the operand of the ++ operator is of type
1111 // bool, it is set to true until C++17. Note that for '_Bool', it is also
1112 // set to true when it encounters ++ operator.
1113 if (U->getType()->isBooleanType() && U->isIncrementOp())
1114 Result = svalBuilder.makeTruthVal(true, U->getType());
1115 else
1116 Result = evalBinOp(state, Op, V2, RHS, U->getType());
1117
1118 // Conjure a new symbol if necessary to recover precision.
1119 if (Result.isUnknown()){
1120 DefinedOrUnknownSVal SymVal =
1121 svalBuilder.conjureSymbolVal(nullptr, U, LCtx,
1122 currBldrCtx->blockCount());
1123 Result = SymVal;
1124
1125 // If the value is a location, ++/-- should always preserve
1126 // non-nullness. Check if the original value was non-null, and if so
1127 // propagate that constraint.
1128 if (Loc::isLocType(U->getType())) {
1129 DefinedOrUnknownSVal Constraint =
1130 svalBuilder.evalEQ(state, V2,svalBuilder.makeZeroVal(U->getType()));
1131
1132 if (!state->assume(Constraint, true)) {
1133 // It isn't feasible for the original value to be null.
1134 // Propagate this constraint.
1135 Constraint = svalBuilder.evalEQ(state, SymVal,
1136 svalBuilder.makeZeroVal(U->getType()));
1137
1138 state = state->assume(Constraint, false);
1139 assert(state);
1140 }
1141 }
1142 }
1143
1144 // Since the lvalue-to-rvalue conversion is explicit in the AST,
1145 // we bind an l-value if the operator is prefix and an lvalue (in C++).
1146 if (U->isGLValue())
1147 state = state->BindExpr(U, LCtx, loc);
1148 else
1149 state = state->BindExpr(U, LCtx, U->isPostfix() ? V2 : Result);
1150
1151 // Perform the store.
1152 Bldr.takeNodes(N);
1153 ExplodedNodeSet Dst3;
1154 evalStore(Dst3, U, Ex, N, state, loc, Result);
1155 Bldr.addNodes(Dst3);
1156 }
1157 Dst.insert(Dst2);
1158}
#define V(N, I)
Definition: ASTContext.h:3233
StringRef P
llvm::APSInt APSInt
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
#define X(type, name)
Definition: Value.h:142
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:2527
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:3847
Expr * getLHS() const
Definition: Expr.h:3896
Expr * getRHS() const
Definition: Expr.h:3898
static bool isAdditiveOp(Opcode Opc)
Definition: Expr.h:3932
static bool isAssignmentOp(Opcode Opc)
Definition: Expr.h:3982
static bool isCompoundAssignmentOp(Opcode Opc)
Definition: Expr.h:3987
Opcode getOpcode() const
Definition: Expr.h:3891
Represents a block literal declaration, which is like an unnamed FunctionDecl.
Definition: Decl.h:4379
capture_const_iterator capture_begin() const
Definition: Decl.h:4508
capture_const_iterator capture_end() const
Definition: Decl.h:4509
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:6167
const BlockDecl * getBlockDecl() const
Definition: Expr.h:6179
This class is used for builtin types like 'int'.
Definition: Type.h:2682
bool isInteger() const
Definition: Type.h:2737
Represents a single basic block in a source-level CFG.
Definition: CFG.h:604
reverse_iterator rbegin()
Definition: CFG.h:908
bool empty() const
Definition: CFG.h:946
CFGTerminator getTerminator() const
Definition: CFG.h:1076
succ_iterator succ_begin()
Definition: CFG.h:983
unsigned succ_size() const
Definition: CFG.h:1001
Represents a top-level expression in a basic block.
Definition: CFG.h:55
T castAs() const
Convert to the specified CFGElement type, asserting that this CFGElement is of the desired type.
Definition: CFG.h:99
const Stmt * getStmt() const
Definition: CFG.h:138
Represents CFGBlock terminator statement.
Definition: CFG.h:531
Stmt * getStmt()
Definition: CFG.h:563
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
Definition: Expr.h:3502
CastKind getCastKind() const
Definition: Expr.h:3546
llvm::iterator_range< path_iterator > path()
Definition: Expr.h:3577
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:3432
const Expr * getInitializer() const
Definition: Expr.h:3455
A reference to a declared variable, function, enum, etc.
Definition: Expr.h:1242
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
Definition: Stmt.h:1320
bool isSingleDecl() const
isSingleDecl - This method returns true if this DeclStmt refers to a single Decl.
Definition: Stmt.h:1333
decl_iterator decl_begin()
Definition: Stmt.h:1374
ExplicitCastExpr - An explicit cast written in the source code.
Definition: Expr.h:3737
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:3068
QualType getType() const
Definition: Expr.h:142
Describes an C or C++ initializer list.
Definition: Expr.h:4843
bool isTransparent() const
Is this a transparent initializer list (that is, an InitListExpr that is purely syntactic,...
Definition: Expr.cpp:2445
unsigned getNumInits() const
Definition: Expr.h:4873
const Expr * getInit(unsigned Init) const
Definition: Expr.h:4889
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:6141
OffsetOfExpr - [C99 7.17] - This represents an expression of the form offsetof(record-type,...
Definition: Expr.h:2477
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
Definition: Expr.h:1150
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:2087
bool isRValueReferenceType() const
Definition: Type.h:7019
bool isConstantSizeType() const
Return true if this is not a variable sized type, according to the rules of C99 6....
Definition: Type.cpp:2293
bool isArrayType() const
Definition: Type.h:7065
const T * castAs() const
Member-template castAs<specific type>.
Definition: Type.h:7590
bool isReferenceType() const
Definition: Type.h:7011
bool isVariableArrayType() const
Definition: Type.h:7077
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
Definition: Type.h:7420
bool isLValueReferenceType() const
Definition: Type.h:7015
bool isAnyComplexType() const
Definition: Type.h:7097
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
Definition: Type.cpp:2303
bool isVectorType() const
Definition: Type.h:7101
bool isFloatingType() const
Definition: Type.cpp:2190
const T * getAs() const
Member-template getAs<specific type>'.
Definition: Type.h:7523
bool isRecordType() const
Definition: Type.h:7089
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand.
Definition: Expr.h:2580
QualType getTypeOfArgument() const
Gets the argument type, or the type of the argument expression, whichever is appropriate.
Definition: Expr.h:2649
UnaryExprOrTypeTrait getKind() const
Definition: Expr.h:2612
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Definition: Expr.h:2195
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition: Decl.h:703
Represents a variable declaration or definition.
Definition: Decl.h:915
const Expr * getInit() const
Definition: Decl.h:1327
llvm::ImmutableList< SVal > getEmptySValList()
llvm::ImmutableList< SVal > prependSVal(SVal X, llvm::ImmutableList< SVal > L)
BlockDataRegion - A region that represents a block instance.
Definition: MemRegion.h:673
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:427
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:609
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:603
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:420
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 handleUOExtension(ExplodedNode *N, const UnaryOperator *U, StmtNodeBuilder &Bldr)
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:285
void takeNodes(const ExplodedNodeSet &S)
Definition: CoreEngine.h:333
void addNodes(const ExplodedNodeSet &S)
Definition: CoreEngine.h:339
const ExplodedNodeSet & getResults()
Definition: CoreEngine.h:310
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'.
virtual SVal simplifySVal(ProgramStateRef State, SVal Val)=0
Simplify symbolic expressions within a given SVal.
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:73
bool isUndef() const
Definition: SVals.h:129
bool isZeroConstant() const
Definition: SVals.cpp:264
bool isUnknownOrUndef() const
Definition: SVals.h:133
bool isConstant() const
Definition: SVals.cpp:252
T castAs() const
Convert to the specified SVal type, asserting that this SVal is of the desired type.
Definition: SVals.h:100
bool isUnknown() const
Definition: SVals.h:125
This builder class is useful for generating nodes that resulted from visiting a statement.
Definition: CoreEngine.h:382
ExplodedNode * generateNode(const Stmt *S, ExplodedNode *Pred, ProgramStateRef St, const ProgramPointTag *tag=nullptr, ProgramPoint::Kind K=ProgramPoint::PostStmtKind)
Definition: CoreEngine.h:411
ExplodedNode * generateSink(const Stmt *S, ExplodedNode *Pred, ProgramStateRef St, const ProgramPointTag *tag=nullptr, ProgramPoint::Kind K=ProgramPoint::PostStmtKind)
Definition: CoreEngine.h:421
SVal evalDerivedToBase(SVal Derived, const CastExpr *Cast)
Evaluates a chain of derived-to-base casts through the path specified in Cast.
Definition: Store.cpp:252
std::optional< SVal > evalBaseToDerived(SVal Base, QualType DerivedPtrType)
Attempts to do a down cast.
Definition: Store.cpp:316
TypedValueRegion - An abstract class representing regions having a typed value.
Definition: MemRegion.h:530
const VarDecl * getDecl() const override=0
Value representing integer constant.
Definition: SVals.h:325
Value representing pointer-to-member.
Definition: SVals.h:437
@ 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:622
unsigned blockCount() const
Returns the number of times the current basic block has been visited on the exploded graph path.
Definition: CoreEngine.h:222