clang 23.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
24 ExplodedNode *Pred,
25 ExplodedNodeSet &Dst) {
26 const StackFrame *SF = Pred->getStackFrame();
27
28 Expr *LHS = B->getLHS()->IgnoreParens();
29 Expr *RHS = B->getRHS()->IgnoreParens();
30
31 // FIXME: Prechecks eventually go in ::Visit().
32 ExplodedNodeSet CheckedSet;
33 ExplodedNodeSet Tmp2;
34 getCheckerManager().runCheckersForPreStmt(CheckedSet, Pred, B, *this);
35
36 // With both the LHS and RHS evaluated, process the operation itself.
37 for (ExplodedNode *N : CheckedSet) {
38 ProgramStateRef State = N->getState();
39 SVal LeftV = State->getSVal(LHS, SF);
40 SVal RightV = State->getSVal(RHS, SF);
41
43
44 if (Op == BO_Assign) {
45 if (RightV.isUnknown()) {
46 unsigned Count = getNumVisitedCurrent();
47 RightV = svalBuilder.conjureSymbolVal(nullptr, getCFGElementRef(), SF,
48 Count);
49 }
50 // Simulate the effects of a "store": bind the value of the RHS
51 // to the L-Value represented by the LHS.
52 SVal ExprVal = B->isGLValue() ? LeftV : RightV;
53 evalStore(Tmp2, B, LHS, N, State->BindExpr(B, SF, ExprVal), LeftV,
54 RightV);
55 continue;
56 }
57
58 if (!B->isAssignmentOp()) {
59 if (B->isAdditiveOp()) {
60 // Ensure that if `p` is a pointer and `i` is an integer with Unknown
61 // value, then `p+i`, `i+p` and `p-i` are evaluated to element regions
62 // (with a symbolic offset) instead of Unknown.
63 auto ConjureIfNeeded = [this, SF](SVal &V, SVal Other, QualType VTy) {
64 if (isa<Loc>(Other) && VTy->isIntegralOrEnumerationType() &&
65 V.isUnknown()) {
66 V = svalBuilder.conjureSymbolVal(getCFGElementRef(), SF, VTy,
68 }
69 };
70 ConjureIfNeeded(RightV, LeftV, RHS->getType());
71 ConjureIfNeeded(LeftV, RightV, LHS->getType());
72 }
73
74 // Although we don't yet model pointers-to-members, we do need to make
75 // sure that the members of temporaries have a valid 'this' pointer for
76 // other checks.
77 if (B->getOpcode() == BO_PtrMemD)
78 State = createTemporaryRegionIfNeeded(State, SF, LHS);
79
80 // Process non-assignments except commas or short-circuited
81 // logical expressions (LAnd and LOr).
82 SVal Result = evalBinOp(State, Op, LeftV, RightV, B->getType());
83 if (!Result.isUnknown()) {
84 State = State->BindExpr(B, SF, Result);
85 } else {
86 // If we cannot evaluate the operation escape the operands.
87 State = escapeValues(State, LeftV, PSK_EscapeOther);
88 State = escapeValues(State, RightV, PSK_EscapeOther);
89 }
90
91 Tmp2.insert(Engine.makePostStmtNode(B, State, N));
92 continue;
93 }
94
95 assert (B->isCompoundAssignmentOp());
96
97 switch (Op) {
98 default:
99 llvm_unreachable("Invalid opcode for compound assignment.");
100 case BO_MulAssign: Op = BO_Mul; break;
101 case BO_DivAssign: Op = BO_Div; break;
102 case BO_RemAssign: Op = BO_Rem; break;
103 case BO_AddAssign: Op = BO_Add; break;
104 case BO_SubAssign: Op = BO_Sub; break;
105 case BO_ShlAssign: Op = BO_Shl; break;
106 case BO_ShrAssign: Op = BO_Shr; break;
107 case BO_AndAssign: Op = BO_And; break;
108 case BO_XorAssign: Op = BO_Xor; break;
109 case BO_OrAssign: Op = BO_Or; break;
110 }
111
112 // Perform a load (the LHS). This performs the checks for
113 // null dereferences, and so on.
114 ExplodedNodeSet Tmp;
115 evalLoad(Tmp, B, LHS, N, State, LeftV);
116
117 for (ExplodedNode *N : Tmp) {
118 State = N->getState();
119 SVal V = State->getSVal(LHS, SF);
120
121 // Determine the relevant types.
122 const ASTContext &ACtx = getContext();
123 const auto *CAOpB = cast<CompoundAssignOperator>(B);
124 QualType CTy = ACtx.getCanonicalType(CAOpB->getComputationResultType());
125 QualType CLHSTy = ACtx.getCanonicalType(CAOpB->getComputationLHSType());
126 QualType LTy = ACtx.getCanonicalType(LHS->getType());
127
128 // Promote LHS.
129 V = svalBuilder.evalCast(V, CLHSTy, LTy);
130
131 // Compute the result of the operation.
132 SVal Result = svalBuilder.evalCast(evalBinOp(State, Op, V, RightV, CTy),
133 B->getType(), CTy);
134
135 SVal StoredInLeftV;
136
137 if (Result.isUnknown()) {
138 // The symbolic value is actually for the type of the left-hand side
139 // expression, not the computation type, as this is the value the
140 // LValue on the LHS will bind to.
141 StoredInLeftV = svalBuilder.conjureSymbolVal(
142 /*symbolTag=*/nullptr, getCFGElementRef(), SF, LTy,
144 // However, we need to convert the symbol to the computation type.
145 Result = svalBuilder.evalCast(StoredInLeftV, CTy, LTy);
146 } else {
147 // The left-hand side may bind to a different value then the
148 // computation type.
149 StoredInLeftV = svalBuilder.evalCast(Result, LTy, CTy);
150 }
151
152 // In C++, assignment and compound assignment operators return an
153 // lvalue.
154 if (B->isGLValue())
155 State = State->BindExpr(B, SF, LeftV);
156 else
157 State = State->BindExpr(B, SF, Result);
158
159 evalStore(Tmp2, B, LHS, N, State, LeftV, StoredInLeftV);
160 }
161 }
162
163 // FIXME: postvisits eventually go in ::Visit()
164 getCheckerManager().runCheckersForPostStmt(Dst, Tmp2, B, *this);
165}
166
168 ExplodedNodeSet &Dst) {
169
171
172 const BlockDecl *BD = BE->getBlockDecl();
173 // Get the value of the block itself.
174 SVal V = svalBuilder.getBlockPointer(BD, T, Pred->getStackFrame(),
176
177 ProgramStateRef State = Pred->getState();
178
179 // If we created a new MemRegion for the block, we should explicitly bind
180 // the captured variables.
181 if (const BlockDataRegion *BDR =
182 dyn_cast_or_null<BlockDataRegion>(V.getAsRegion())) {
183
184 auto ReferencedVars = BDR->referenced_vars();
185 auto CI = BD->capture_begin();
186 auto CE = BD->capture_end();
187 for (auto Var : ReferencedVars) {
188 const VarRegion *capturedR = Var.getCapturedRegion();
189 const TypedValueRegion *originalR = Var.getOriginalRegion();
190
191 // If the capture had a copy expression, use the result of evaluating
192 // that expression, otherwise use the original value.
193 // We rely on the invariant that the block declaration's capture variables
194 // are a prefix of the BlockDataRegion's referenced vars (which may include
195 // referenced globals, etc.) to enable fast lookup of the capture for a
196 // given referenced var.
197 const Expr *copyExpr = nullptr;
198 if (CI != CE) {
199 assert(CI->getVariable() == capturedR->getDecl());
200 copyExpr = CI->getCopyExpr();
201 CI++;
202 }
203
204 if (capturedR != originalR) {
205 SVal originalV;
206 const StackFrame *SF = Pred->getStackFrame();
207 if (copyExpr) {
208 originalV = State->getSVal(copyExpr, SF);
209 } else {
210 originalV = State->getSVal(loc::MemRegionVal(originalR));
211 }
212 State = State->bindLoc(loc::MemRegionVal(capturedR), originalV, SF);
213 }
214 }
215 }
216
217 ExplodedNodeSet Tmp;
218 NodeBuilder Bldr(Pred, Tmp, *currBldrCtx);
219 Bldr.generateNode(BE, Pred, State->BindExpr(BE, Pred->getStackFrame(), V),
221
222 // FIXME: Move all post/pre visits to ::Visit().
223 getCheckerManager().runCheckersForPostStmt(Dst, Tmp, BE, *this);
224}
225
228 const StackFrame *SF, QualType T, QualType ExTy,
229 const CastExpr *CastE, NodeBuilder &Bldr,
230 ExplodedNode *Pred) {
231 if (T->isLValueReferenceType()) {
232 assert(!CastE->getType()->isLValueReferenceType());
233 ExTy = getContext().getLValueReferenceType(ExTy);
234 } else if (T->isRValueReferenceType()) {
235 assert(!CastE->getType()->isRValueReferenceType());
236 ExTy = getContext().getRValueReferenceType(ExTy);
237 }
238 // Delegate to SValBuilder to process.
239 SVal OrigV = state->getSVal(Ex, SF);
240 SVal SimplifiedOrigV = svalBuilder.simplifySVal(state, OrigV);
241 SVal V = svalBuilder.evalCast(SimplifiedOrigV, T, ExTy);
242 // Negate the result if we're treating the boolean as a signed i1
243 if (CastE->getCastKind() == CK_BooleanToSignedIntegral && V.isValid())
244 V = svalBuilder.evalMinus(V.castAs<NonLoc>());
245
246 state = state->BindExpr(CastE, SF, V);
247 if (V.isUnknown() && !OrigV.isUnknown()) {
248 state = escapeValues(state, OrigV, PSK_EscapeOther);
249 }
250 Bldr.generateNode(CastE, Pred, state);
251
252 return state;
253}
254
255void ExprEngine::VisitCast(const CastExpr *CastE, const Expr *Ex,
256 ExplodedNode *Pred, ExplodedNodeSet &Dst) {
257
258 ExplodedNodeSet DstPreStmt;
259 getCheckerManager().runCheckersForPreStmt(DstPreStmt, Pred, CastE, *this);
260
261 if (CastE->getCastKind() == CK_LValueToRValue) {
262 for (ExplodedNode *Node : DstPreStmt) {
263 ProgramStateRef State = Node->getState();
264 const StackFrame *SF = Node->getStackFrame();
265 evalLoad(Dst, CastE, CastE, Node, State, State->getSVal(Ex, SF));
266 }
267 return;
268 }
269 if (CastE->getCastKind() == CK_LValueToRValueBitCast) {
270 // Handle `__builtin_bit_cast`:
271 ExplodedNodeSet DstEvalLoc;
272
273 // Simulate the lvalue-to-rvalue conversion on `Ex`:
274 for (ExplodedNode *Node : DstPreStmt) {
275 ProgramStateRef State = Node->getState();
276 const StackFrame *SF = Node->getStackFrame();
277 evalLocation(DstEvalLoc, CastE, Ex, Node, State, State->getSVal(Ex, SF),
278 true);
279 }
280 // Simulate the operation that actually casts the original value to a new
281 // value of the destination type :
282 NodeBuilder Bldr(DstEvalLoc, Dst, *currBldrCtx);
283
284 for (ExplodedNode *Node : DstEvalLoc) {
285 ProgramStateRef State = Node->getState();
286 const StackFrame *SF = Node->getStackFrame();
287 // Although `Ex` is an lvalue, it could have `Loc::ConcreteInt` kind
288 // (e.g., `(int *)123456`). In such cases, there is no MemRegion
289 // available and we can't get the value to be casted.
290 SVal CastedV = UnknownVal();
291
292 if (const MemRegion *MR = State->getSVal(Ex, SF).getAsRegion()) {
293 SVal OrigV = State->getSVal(MR);
294 CastedV = svalBuilder.evalCast(svalBuilder.simplifySVal(State, OrigV),
295 CastE->getType(), Ex->getType());
296 }
297 State = State->BindExpr(CastE, SF, CastedV);
298 Bldr.generateNode(CastE, Node, State);
299 }
300 return;
301 }
302
303 // All other casts.
304 QualType T = CastE->getType();
305 QualType ExTy = Ex->getType();
306
307 if (const ExplicitCastExpr *ExCast=dyn_cast_or_null<ExplicitCastExpr>(CastE))
308 T = ExCast->getTypeAsWritten();
309
310 NodeBuilder Bldr(DstPreStmt, Dst, *currBldrCtx);
311 for (ExplodedNode *Pred : DstPreStmt) {
312 ProgramStateRef state = Pred->getState();
313 const StackFrame *SF = Pred->getStackFrame();
314
315 switch (CastE->getCastKind()) {
316 case CK_LValueToRValue:
317 case CK_LValueToRValueBitCast:
318 llvm_unreachable("LValueToRValue casts handled earlier.");
319 case CK_ToVoid:
320 continue;
321 // The analyzer doesn't do anything special with these casts,
322 // since it understands retain/release semantics already.
323 case CK_ARCProduceObject:
324 case CK_ARCConsumeObject:
325 case CK_ARCReclaimReturnedObject:
326 case CK_ARCExtendBlockObject: // Fall-through.
327 case CK_CopyAndAutoreleaseBlockObject:
328 // The analyser can ignore atomic casts for now, although some future
329 // checkers may want to make certain that you're not modifying the same
330 // value through atomic and nonatomic pointers.
331 case CK_AtomicToNonAtomic:
332 case CK_NonAtomicToAtomic:
333 // True no-ops.
334 case CK_NoOp:
335 case CK_ConstructorConversion:
336 case CK_UserDefinedConversion:
337 case CK_FunctionToPointerDecay:
338 case CK_BuiltinFnToFnPtr:
339 case CK_HLSLArrayRValue: {
340 // Copy the SVal of Ex to CastE.
341 ProgramStateRef state = Pred->getState();
342 const StackFrame *SF = Pred->getStackFrame();
343 SVal V = state->getSVal(Ex, SF);
344 state = state->BindExpr(CastE, SF, V);
345 Bldr.generateNode(CastE, Pred, state);
346 continue;
347 }
348 case CK_MemberPointerToBoolean:
349 case CK_PointerToBoolean: {
350 SVal V = state->getSVal(Ex, SF);
351 auto PTMSV = V.getAs<nonloc::PointerToMember>();
352 if (PTMSV)
353 V = svalBuilder.makeTruthVal(!PTMSV->isNullMemberPointer(), ExTy);
354 if (V.isUndef() || PTMSV) {
355 state = state->BindExpr(CastE, SF, V);
356 Bldr.generateNode(CastE, Pred, state);
357 continue;
358 }
359 // Explicitly proceed with default handler for this case cascade.
360 state = handleLValueBitCast(state, Ex, SF, T, ExTy, CastE, Bldr, Pred);
361 continue;
362 }
363 case CK_Dependent:
364 case CK_ArrayToPointerDecay:
365 case CK_BitCast:
366 case CK_AddressSpaceConversion:
367 case CK_BooleanToSignedIntegral:
368 case CK_IntegralToPointer:
369 case CK_PointerToIntegral: {
370 SVal V = state->getSVal(Ex, SF);
372 state = state->BindExpr(CastE, SF, UnknownVal());
373 Bldr.generateNode(CastE, Pred, state);
374 continue;
375 }
376 // Explicitly proceed with default handler for this case cascade.
377 state = handleLValueBitCast(state, Ex, SF, T, ExTy, CastE, Bldr, Pred);
378 continue;
379 }
380 case CK_IntegralToBoolean:
381 case CK_IntegralToFloating:
382 case CK_FloatingToIntegral:
383 case CK_FloatingToBoolean:
384 case CK_FloatingCast:
385 case CK_FloatingRealToComplex:
386 case CK_FloatingComplexToReal:
387 case CK_FloatingComplexToBoolean:
388 case CK_FloatingComplexCast:
389 case CK_FloatingComplexToIntegralComplex:
390 case CK_IntegralRealToComplex:
391 case CK_IntegralComplexToReal:
392 case CK_IntegralComplexToBoolean:
393 case CK_IntegralComplexCast:
394 case CK_IntegralComplexToFloatingComplex:
395 case CK_CPointerToObjCPointerCast:
396 case CK_BlockPointerToObjCPointerCast:
397 case CK_AnyPointerToBlockPointerCast:
398 case CK_ObjCObjectLValueCast:
399 case CK_ZeroToOCLOpaqueType:
400 case CK_IntToOCLSampler:
401 case CK_LValueBitCast:
402 case CK_FloatingToFixedPoint:
403 case CK_FixedPointToFloating:
404 case CK_FixedPointCast:
405 case CK_FixedPointToBoolean:
406 case CK_FixedPointToIntegral:
407 case CK_IntegralToFixedPoint: {
408 state = handleLValueBitCast(state, Ex, SF, T, ExTy, CastE, Bldr, Pred);
409 continue;
410 }
411 case CK_IntegralCast: {
412 // Delegate to SValBuilder to process.
413 SVal V = state->getSVal(Ex, SF);
414 if (AMgr.options.ShouldSupportSymbolicIntegerCasts)
415 V = svalBuilder.evalCast(V, T, ExTy);
416 else
417 V = svalBuilder.evalIntegralCast(state, V, T, ExTy);
418 state = state->BindExpr(CastE, SF, V);
419 Bldr.generateNode(CastE, Pred, state);
420 continue;
421 }
422 case CK_DerivedToBase:
423 case CK_UncheckedDerivedToBase: {
424 // For DerivedToBase cast, delegate to the store manager.
425 SVal val = state->getSVal(Ex, SF);
426 val = getStoreManager().evalDerivedToBase(val, CastE);
427 state = state->BindExpr(CastE, SF, val);
428 Bldr.generateNode(CastE, Pred, state);
429 continue;
430 }
431 // Handle C++ dyn_cast.
432 case CK_Dynamic: {
433 SVal val = state->getSVal(Ex, SF);
434
435 // Compute the type of the result.
436 QualType resultType = CastE->getType();
437 if (CastE->isGLValue())
438 resultType = getContext().getPointerType(resultType);
439
440 bool Failed = true;
441
442 // Check if the value being cast does not evaluates to 0.
443 if (!val.isZeroConstant())
444 if (std::optional<SVal> V =
445 StateMgr.getStoreManager().evalBaseToDerived(val, T)) {
446 val = *V;
447 Failed = false;
448 }
449
450 if (Failed) {
451 if (T->isReferenceType()) {
452 // A bad_cast exception is thrown if input value is a reference.
453 // Currently, we model this, by generating a sink.
454 Bldr.generateSink(CastE, Pred, state);
455 continue;
456 } else {
457 // If the cast fails on a pointer, bind to 0.
458 state = state->BindExpr(CastE, SF,
459 svalBuilder.makeNullWithType(resultType));
460 }
461 } else {
462 // If we don't know if the cast succeeded, conjure a new symbol.
463 if (val.isUnknown()) {
464 DefinedOrUnknownSVal NewSym = svalBuilder.conjureSymbolVal(
465 /*symbolTag=*/nullptr, getCFGElementRef(), SF, resultType,
467 state = state->BindExpr(CastE, SF, NewSym);
468 } else
469 // Else, bind to the derived region value.
470 state = state->BindExpr(CastE, SF, val);
471 }
472 Bldr.generateNode(CastE, Pred, state);
473 continue;
474 }
475 case CK_BaseToDerived: {
476 SVal val = state->getSVal(Ex, SF);
477 QualType resultType = CastE->getType();
478 if (CastE->isGLValue())
479 resultType = getContext().getPointerType(resultType);
480
481 if (!val.isConstant()) {
482 std::optional<SVal> V = getStoreManager().evalBaseToDerived(val, T);
483 val = V ? *V : UnknownVal();
484 }
485
486 // Failed to cast or the result is unknown, fall back to conservative.
487 if (val.isUnknown()) {
488 val = svalBuilder.conjureSymbolVal(
489 /*symbolTag=*/nullptr, getCFGElementRef(), SF, resultType,
491 }
492 state = state->BindExpr(CastE, SF, val);
493 Bldr.generateNode(CastE, Pred, state);
494 continue;
495 }
496 case CK_NullToPointer: {
497 SVal V = svalBuilder.makeNullWithType(CastE->getType());
498 state = state->BindExpr(CastE, SF, V);
499 Bldr.generateNode(CastE, Pred, state);
500 continue;
501 }
502 case CK_NullToMemberPointer: {
503 SVal V = svalBuilder.getMemberPointer(nullptr);
504 state = state->BindExpr(CastE, SF, V);
505 Bldr.generateNode(CastE, Pred, state);
506 continue;
507 }
508 case CK_DerivedToBaseMemberPointer:
509 case CK_BaseToDerivedMemberPointer:
510 case CK_ReinterpretMemberPointer: {
511 SVal V = state->getSVal(Ex, SF);
512 if (auto PTMSV = V.getAs<nonloc::PointerToMember>()) {
513 SVal CastedPTMSV =
514 svalBuilder.makePointerToMember(getBasicVals().accumCXXBase(
515 CastE->path(), *PTMSV, CastE->getCastKind()));
516 state = state->BindExpr(CastE, SF, CastedPTMSV);
517 Bldr.generateNode(CastE, Pred, state);
518 continue;
519 }
520 // Explicitly proceed with default handler for this case cascade.
521 }
522 [[fallthrough]];
523 // Various C++ casts that are not handled yet.
524 case CK_ToUnion:
525 case CK_MatrixCast:
526 case CK_VectorSplat:
527 case CK_HLSLElementwiseCast:
528 case CK_HLSLAggregateSplatCast:
529 case CK_HLSLMatrixTruncation:
530 case CK_HLSLVectorTruncation: {
531 QualType resultType = CastE->getType();
532 if (CastE->isGLValue())
533 resultType = getContext().getPointerType(resultType);
534 SVal result = svalBuilder.conjureSymbolVal(
535 /*symbolTag=*/nullptr, getCFGElementRef(), SF, resultType,
537 state = state->BindExpr(CastE, SF, result);
538 Bldr.generateNode(CastE, Pred, state);
539 continue;
540 }
541 }
542 }
543}
544
546 ExplodedNode *Pred,
547 ExplodedNodeSet &Dst) {
548 NodeBuilder B(Pred, Dst, *currBldrCtx);
549
550 ProgramStateRef State = Pred->getState();
551 const StackFrame *SF = Pred->getStackFrame();
552
553 const Expr *Init = CL->getInitializer();
554 SVal V = State->getSVal(CL->getInitializer(), SF);
555
557 // No work needed. Just pass the value up to this expression.
558 } else {
559 assert(isa<InitListExpr>(Init));
560 Loc CLLoc = State->getLValue(CL, SF);
561 State = State->bindLoc(CLLoc, V, SF);
562
563 if (CL->isGLValue())
564 V = CLLoc;
565 }
566
567 B.generateNode(CL, Pred, State->BindExpr(CL, SF, V));
568}
569
571 ExplodedNodeSet &Dst) {
572 if (isa<TypedefNameDecl>(*DS->decl_begin())) {
573 // C99 6.7.7 "Any array size expressions associated with variable length
574 // array declarators are evaluated each time the declaration of the typedef
575 // name is reached in the order of execution."
576 // The checkers should know about typedef to be able to handle VLA size
577 // expressions.
578 ExplodedNodeSet DstPre;
579 getCheckerManager().runCheckersForPreStmt(DstPre, Pred, DS, *this);
580 getCheckerManager().runCheckersForPostStmt(Dst, DstPre, DS, *this);
581 return;
582 }
583
584 // Assumption: The CFG has one DeclStmt per Decl.
585 const VarDecl *VD = dyn_cast_or_null<VarDecl>(*DS->decl_begin());
586
587 if (!VD) {
588 //TODO:AZ: remove explicit insertion after refactoring is done.
589 Dst.insert(Pred);
590 return;
591 }
592
593 // FIXME: all pre/post visits should eventually be handled by ::Visit().
594 ExplodedNodeSet dstPreVisit;
595 getCheckerManager().runCheckersForPreStmt(dstPreVisit, Pred, DS, *this);
596
597 ExplodedNodeSet dstEvaluated;
598 NodeBuilder B(dstPreVisit, dstEvaluated, *currBldrCtx);
599 for (ExplodedNodeSet::iterator I = dstPreVisit.begin(), E = dstPreVisit.end();
600 I!=E; ++I) {
601 ExplodedNode *N = *I;
602 ProgramStateRef state = N->getState();
603 const StackFrame *SF = N->getStackFrame();
604
605 // Decls without InitExpr are not initialized explicitly.
606 if (const Expr *InitEx = VD->getInit()) {
607
608 // Note in the state that the initialization has occurred.
609 ExplodedNode *UpdatedN = N;
610 SVal InitVal = state->getSVal(InitEx, SF);
611
612 assert(DS->isSingleDecl());
613 if (getObjectUnderConstruction(state, DS, SF)) {
614 state = finishObjectConstruction(state, DS, SF);
615 // We constructed the object directly in the variable.
616 // No need to bind anything.
617 B.generateNode(DS, UpdatedN, state);
618 } else {
619 // Recover some path-sensitivity if a scalar value evaluated to
620 // UnknownVal.
621 if (InitVal.isUnknown()) {
622 QualType Ty = InitEx->getType();
623 if (InitEx->isGLValue()) {
624 Ty = getContext().getPointerType(Ty);
625 }
626
627 InitVal = svalBuilder.conjureSymbolVal(
628 /*symbolTag=*/nullptr, getCFGElementRef(), SF, Ty,
630 }
631
632
633 B.takeNodes(UpdatedN);
634 ExplodedNodeSet Dst2;
635 evalBind(Dst2, DS, UpdatedN, state->getLValue(VD, SF), InitVal, true);
636 B.addNodes(Dst2);
637 }
638 }
639 else {
640 B.generateNode(DS, N, state);
641 }
642 }
643
645}
646
648 ExplodedNodeSet &Dst) {
649 // This method acts upon CFG elements for logical operators && and ||
650 // and attaches the value (true or false) to them as expressions.
651 // It doesn't produce any state splits.
652 // If we made it that far, we're past the point when we modeled the short
653 // circuit. It means that we should have precise knowledge about whether
654 // we've short-circuited. If we did, we already know the value we need to
655 // bind. If we didn't, the value of the RHS (casted to the boolean type)
656 // is the answer.
657 // Currently this method tries to figure out whether we've short-circuited
658 // by looking at the ExplodedGraph. This method is imperfect because there
659 // could inevitably have been merges that would have resulted in multiple
660 // potential path traversal histories. We bail out when we fail.
661 // Due to this ambiguity, a more reliable solution would have been to
662 // track the short circuit operation history path-sensitively until
663 // we evaluate the respective logical operator.
664 assert(B->getOpcode() == BO_LAnd ||
665 B->getOpcode() == BO_LOr);
666
667 NodeBuilder Bldr(Pred, Dst, *currBldrCtx);
668 ProgramStateRef state = Pred->getState();
669
670 if (B->getType()->isVectorType()) {
671 // FIXME: We do not model vector arithmetic yet. When adding support for
672 // that, note that the CFG-based reasoning below does not apply, because
673 // logical operators on vectors are not short-circuit. Currently they are
674 // modeled as short-circuit in Clang CFG but this is incorrect.
675 // Do not set the value for the expression. It'd be UnknownVal by default.
676 Bldr.generateNode(B, Pred, state);
677 return;
678 }
679
680 ExplodedNode *N = Pred;
681 while (!N->getLocation().getAs<BlockEdge>()) {
682 ProgramPoint P = N->getLocation();
683 assert(P.getAs<PreStmt>() || P.getAs<PreStmtPurgeDeadSymbols>() ||
684 P.getAs<BlockEntrance>());
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
701 SVal X;
702
703 // Determine the value of the expression by introspecting how we
704 // got this location in the CFG. This requires looking at the previous
705 // block we were in and what kind of control-flow transfer was involved.
706 const CFGBlock *SrcBlock = BE.getSrc();
707 // The only terminator (if there is one) that makes sense is a logical op.
708 CFGTerminator T = SrcBlock->getTerminator();
709 if (const BinaryOperator *Term = cast_or_null<BinaryOperator>(T.getStmt())) {
710 (void) Term;
711 assert(Term->isLogicalOp());
712 assert(SrcBlock->succ_size() == 2);
713 // Did we take the true or false branch?
714 unsigned constant = (*SrcBlock->succ_begin() == BE.getDst()) ? 1 : 0;
715 X = svalBuilder.makeIntVal(constant, B->getType());
716 }
717 else {
718 // If there is no terminator, by construction the last statement
719 // in SrcBlock is the value of the enclosing expression.
720 // However, we still need to constrain that value to be 0 or 1.
721 assert(!SrcBlock->empty());
722 CFGStmt Elem = SrcBlock->rbegin()->castAs<CFGStmt>();
723 const Expr *RHS = cast<Expr>(Elem.getStmt());
724 SVal RHSVal = N->getState()->getSVal(RHS, Pred->getStackFrame());
725
726 if (RHSVal.isUndef()) {
727 X = RHSVal;
728 } else {
729 // We evaluate "RHSVal != 0" expression which result in 0 if the value is
730 // known to be false, 1 if the value is known to be true and a new symbol
731 // when the assumption is unknown.
732 nonloc::ConcreteInt Zero(getBasicVals().getValue(0, B->getType()));
733 X = evalBinOp(N->getState(), BO_NE,
734 svalBuilder.evalCast(RHSVal, B->getType(), RHS->getType()),
735 Zero, B->getType());
736 }
737 }
738 Bldr.generateNode(B, Pred, state->BindExpr(B, Pred->getStackFrame(), X));
739}
740
742 const Expr *L,
743 const Expr *R,
744 ExplodedNode *Pred,
745 ExplodedNodeSet &Dst) {
746 assert(L && R);
747
748 NodeBuilder B(Pred, Dst, *currBldrCtx);
749 ProgramStateRef state = Pred->getState();
750 const StackFrame *SF = Pred->getStackFrame();
751 const CFGBlock *SrcBlock = nullptr;
752
753 // Find the predecessor block.
754 ProgramStateRef SrcState = state;
755 for (const ExplodedNode *N = Pred ; N ; N = *N->pred_begin()) {
756 auto Edge = N->getLocationAs<BlockEdge>();
757 if (!Edge.has_value()) {
758 // If the state N has multiple predecessors P, it means that successors
759 // of P are all equivalent.
760 // In turn, that means that all nodes at P are equivalent in terms
761 // of observable behavior at N, and we can follow any of them.
762 // FIXME: a more robust solution which does not walk up the tree.
763 continue;
764 }
765 SrcBlock = Edge->getSrc();
766 SrcState = N->getState();
767 break;
768 }
769
770 assert(SrcBlock && "missing function entry");
771
772 // Find the last expression in the predecessor block. That is the
773 // expression that is used for the value of the ternary expression.
774 bool hasValue = false;
775 SVal V;
776
777 for (CFGElement CE : llvm::reverse(*SrcBlock)) {
778 if (std::optional<CFGStmt> CS = CE.getAs<CFGStmt>()) {
779 const Expr *ValEx = cast<Expr>(CS->getStmt());
780 ValEx = ValEx->IgnoreParens();
781
782 // For GNU extension '?:' operator, the left hand side will be an
783 // OpaqueValueExpr, so get the underlying expression.
784 if (const OpaqueValueExpr *OpaqueEx = dyn_cast<OpaqueValueExpr>(L))
785 L = OpaqueEx->getSourceExpr();
786
787 // If the last expression in the predecessor block matches true or false
788 // subexpression, get its the value.
789 if (ValEx == L->IgnoreParens() || ValEx == R->IgnoreParens()) {
790 hasValue = true;
791 V = SrcState->getSVal(ValEx, SF);
792 }
793 break;
794 }
795 }
796
797 if (!hasValue)
798 V = svalBuilder.conjureSymbolVal(nullptr, getCFGElementRef(), SF,
800
801 // Generate a new node with the binding from the appropriate path.
802 B.generateNode(Ex, Pred, state->BindExpr(Ex, SF, V, true));
803}
804
807 ExplodedNode *Pred, ExplodedNodeSet &Dst) {
808 NodeBuilder B(Pred, Dst, *currBldrCtx);
810 if (OOE->EvaluateAsInt(Result, getContext())) {
811 APSInt IV = Result.Val.getInt();
812 assert(IV.getBitWidth() == getContext().getTypeSize(OOE->getType()));
813 assert(OOE->getType()->castAs<BuiltinType>()->isInteger());
814 assert(IV.isSigned() == OOE->getType()->isSignedIntegerType());
815 SVal X = svalBuilder.makeIntVal(IV);
816 B.generateNode(OOE, Pred,
817 Pred->getState()->BindExpr(OOE, Pred->getStackFrame(), X));
818 }
819 // FIXME: Handle the case where __builtin_offsetof is not a constant.
820}
821
822
825 ExplodedNode *Pred,
826 ExplodedNodeSet &Dst) {
827 // FIXME: Prechecks eventually go in ::Visit().
828 ExplodedNodeSet CheckedSet;
829 getCheckerManager().runCheckersForPreStmt(CheckedSet, Pred, Ex, *this);
830
831 ExplodedNodeSet EvalSet;
832 NodeBuilder Bldr(CheckedSet, EvalSet, *currBldrCtx);
833
834 QualType T = Ex->getTypeOfArgument();
835
836 for (ExplodedNode *N : CheckedSet) {
837 if (Ex->getKind() == UETT_SizeOf || Ex->getKind() == UETT_DataSizeOf ||
838 Ex->getKind() == UETT_CountOf) {
839 if (!T->isIncompleteType() && !T->isConstantSizeType()) {
840 assert(T->isVariableArrayType() && "Unknown non-constant-sized type.");
841
842 // FIXME: Add support for VLA type arguments and VLA expressions.
843 // When that happens, we should probably refactor VLASizeChecker's code.
844 continue;
845 } else if (T->getAs<ObjCObjectType>()) {
846 // Some code tries to take the sizeof an ObjCObjectType, relying that
847 // the compiler has laid out its representation. Just report Unknown
848 // for these.
849 continue;
850 }
851 }
852
853 APSInt Value = Ex->EvaluateKnownConstInt(getContext());
854 CharUnits amt = CharUnits::fromQuantity(Value.getZExtValue());
855
856 ProgramStateRef state = N->getState();
857 state = state->BindExpr(
858 Ex, N->getStackFrame(),
859 svalBuilder.makeIntVal(amt.getQuantity(), Ex->getType()));
860 Bldr.generateNode(Ex, N, state);
861 }
862
863 getCheckerManager().runCheckersForPostStmt(Dst, EvalSet, Ex, *this);
864}
865
867 NodeBuilder &Bldr) {
868 // FIXME: We can probably just have some magic in Environment::getSVal()
869 // that propagates values, instead of creating a new node here.
870 //
871 // Unary "+" is a no-op, similar to a parentheses. We still have places
872 // where it may be a block-level expression, so we need to
873 // generate an extra node that just propagates the value of the
874 // subexpression.
875 const Expr *Ex = U->getSubExpr()->IgnoreParens();
876 ProgramStateRef state = N->getState();
877 const StackFrame *SF = N->getStackFrame();
878 Bldr.generateNode(U, N, state->BindExpr(U, SF, state->getSVal(Ex, SF)));
879}
880
882 ExplodedNodeSet &Dst) {
883 // FIXME: Prechecks eventually go in ::Visit().
884 ExplodedNodeSet CheckedSet;
885 getCheckerManager().runCheckersForPreStmt(CheckedSet, Pred, U, *this);
886
887 ExplodedNodeSet EvalSet;
888 NodeBuilder Bldr(CheckedSet, EvalSet, *currBldrCtx);
889
890 for (ExplodedNode *N : CheckedSet) {
891 switch (U->getOpcode()) {
892 default: {
893 Bldr.takeNodes(N);
894 ExplodedNodeSet Tmp;
896 Bldr.addNodes(Tmp);
897 break;
898 }
899 case UO_Real: {
900 const Expr *Ex = U->getSubExpr()->IgnoreParens();
901
902 // FIXME: We don't have complex SValues yet.
903 if (Ex->getType()->isAnyComplexType()) {
904 // Just report "Unknown."
905 break;
906 }
907
908 // For all other types, UO_Real is an identity operation.
909 assert (U->getType() == Ex->getType());
910 ProgramStateRef state = N->getState();
911 const StackFrame *SF = N->getStackFrame();
912 Bldr.generateNode(U, N, state->BindExpr(U, SF, state->getSVal(Ex, SF)));
913 break;
914 }
915
916 case UO_Imag: {
917 const Expr *Ex = U->getSubExpr()->IgnoreParens();
918 // FIXME: We don't have complex SValues yet.
919 if (Ex->getType()->isAnyComplexType()) {
920 // Just report "Unknown."
921 break;
922 }
923 // For all other types, UO_Imag returns 0.
924 ProgramStateRef state = N->getState();
925 const StackFrame *SF = N->getStackFrame();
926 SVal X = svalBuilder.makeZeroVal(Ex->getType());
927 Bldr.generateNode(U, N, state->BindExpr(U, SF, X));
928 break;
929 }
930
931 case UO_AddrOf: {
932 // Process pointer-to-member address operation.
933 const Expr *Ex = U->getSubExpr()->IgnoreParens();
934 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Ex)) {
935 const ValueDecl *VD = DRE->getDecl();
936
938 ProgramStateRef State = N->getState();
939 const StackFrame *SF = N->getStackFrame();
940 SVal SV = svalBuilder.getMemberPointer(cast<NamedDecl>(VD));
941 Bldr.generateNode(U, N, State->BindExpr(U, SF, SV));
942 break;
943 }
944 }
945 // Explicitly proceed with default handler for this case cascade.
946 handleUOExtension(N, U, Bldr);
947 break;
948 }
949 case UO_Plus:
950 assert(!U->isGLValue());
951 [[fallthrough]];
952 case UO_Deref:
953 case UO_Extension: {
954 handleUOExtension(N, U, Bldr);
955 break;
956 }
957
958 case UO_LNot:
959 case UO_Minus:
960 case UO_Not: {
961 assert (!U->isGLValue());
962 const Expr *Ex = U->getSubExpr()->IgnoreParens();
963 ProgramStateRef state = N->getState();
964 const StackFrame *SF = N->getStackFrame();
965
966 // Get the value of the subexpression.
967 SVal V = state->getSVal(Ex, SF);
968
969 if (V.isUnknownOrUndef()) {
970 Bldr.generateNode(U, N, state->BindExpr(U, SF, V));
971 break;
972 }
973
974 switch (U->getOpcode()) {
975 default:
976 llvm_unreachable("Invalid Opcode.");
977 case UO_Not:
978 // FIXME: Do we need to handle promotions?
979 state = state->BindExpr(
980 U, SF, svalBuilder.evalComplement(V.castAs<NonLoc>()));
981 break;
982 case UO_Minus:
983 // FIXME: Do we need to handle promotions?
984 state =
985 state->BindExpr(U, SF, svalBuilder.evalMinus(V.castAs<NonLoc>()));
986 break;
987 case UO_LNot:
988 // C99 6.5.3.3: "The expression !E is equivalent to (0==E)."
989 //
990 // Note: technically we do "E == 0", but this is the same in the
991 // transfer functions as "0 == E".
992 SVal Result;
993 if (std::optional<Loc> LV = V.getAs<Loc>()) {
994 Loc X = svalBuilder.makeNullWithType(Ex->getType());
995 Result = evalBinOp(state, BO_EQ, *LV, X, U->getType());
996 } else if (Ex->getType()->isFloatingType()) {
997 // FIXME: handle floating point types.
998 Result = UnknownVal();
999 } else {
1000 nonloc::ConcreteInt X(getBasicVals().getValue(0, Ex->getType()));
1001 Result = evalBinOp(state, BO_EQ, V.castAs<NonLoc>(), X, U->getType());
1002 }
1003
1004 state = state->BindExpr(U, SF, Result);
1005 break;
1006 }
1007 Bldr.generateNode(U, N, state);
1008 break;
1009 }
1010 }
1011 }
1012
1013 getCheckerManager().runCheckersForPostStmt(Dst, EvalSet, U, *this);
1014}
1015
1017 ExplodedNode *Pred,
1018 ExplodedNodeSet &Dst) {
1019 // Handle ++ and -- (both pre- and post-increment).
1020 assert (U->isIncrementDecrementOp());
1021 const Expr *Ex = U->getSubExpr()->IgnoreParens();
1022
1023 const StackFrame *SF = Pred->getStackFrame();
1024 ProgramStateRef state = Pred->getState();
1025 SVal loc = state->getSVal(Ex, SF);
1026
1027 // Perform a load.
1028 ExplodedNodeSet Tmp;
1029 evalLoad(Tmp, U, Ex, Pred, state, loc);
1030
1031 ExplodedNodeSet Dst2;
1032 NodeBuilder Bldr(Tmp, Dst2, *currBldrCtx);
1033 for (ExplodedNode *N : Tmp) {
1034 state = N->getState();
1035 assert(SF == N->getStackFrame());
1036 SVal V2_untested = state->getSVal(Ex, SF);
1037
1038 // Propagate unknown and undefined values.
1039 if (V2_untested.isUnknownOrUndef()) {
1040 state = state->BindExpr(U, SF, V2_untested);
1041
1042 // Perform the store, so that the uninitialized value detection happens.
1043 Bldr.takeNodes(N);
1044 ExplodedNodeSet Dst3;
1045 evalStore(Dst3, U, Ex, N, state, loc, V2_untested);
1046 Bldr.addNodes(Dst3);
1047
1048 continue;
1049 }
1050 DefinedSVal V2 = V2_untested.castAs<DefinedSVal>();
1051
1052 // Handle all other values.
1053 BinaryOperator::Opcode Op = U->isIncrementOp() ? BO_Add : BO_Sub;
1054
1055 // If the UnaryOperator has non-location type, use its type to create the
1056 // constant value. If the UnaryOperator has location type, create the
1057 // constant with int type and pointer width.
1058 SVal RHS;
1059 SVal Result;
1060
1061 if (U->getType()->isAnyPointerType())
1062 RHS = svalBuilder.makeArrayIndex(1);
1063 else if (U->getType()->isIntegralOrEnumerationType())
1064 RHS = svalBuilder.makeIntVal(1, U->getType());
1065 else
1066 RHS = UnknownVal();
1067
1068 // The use of an operand of type bool with the ++ operators is deprecated
1069 // but valid until C++17. And if the operand of the ++ operator is of type
1070 // bool, it is set to true until C++17. Note that for '_Bool', it is also
1071 // set to true when it encounters ++ operator.
1072 if (U->getType()->isBooleanType() && U->isIncrementOp())
1073 Result = svalBuilder.makeTruthVal(true, U->getType());
1074 else
1075 Result = evalBinOp(state, Op, V2, RHS, U->getType());
1076
1077 // Conjure a new symbol if necessary to recover precision.
1078 if (Result.isUnknown()){
1079 DefinedOrUnknownSVal SymVal = svalBuilder.conjureSymbolVal(
1080 /*symbolTag=*/nullptr, getCFGElementRef(), SF,
1082 Result = SymVal;
1083
1084 // If the value is a location, ++/-- should always preserve
1085 // non-nullness. Check if the original value was non-null, and if so
1086 // propagate that constraint.
1087 if (Loc::isLocType(U->getType())) {
1088 DefinedOrUnknownSVal Constraint =
1089 svalBuilder.evalEQ(state, V2,svalBuilder.makeZeroVal(U->getType()));
1090
1091 if (!state->assume(Constraint, true)) {
1092 // It isn't feasible for the original value to be null.
1093 // Propagate this constraint.
1094 Constraint = svalBuilder.evalEQ(state, SymVal,
1095 svalBuilder.makeZeroVal(U->getType()));
1096
1097 state = state->assume(Constraint, false);
1098 assert(state);
1099 }
1100 }
1101 }
1102
1103 // Since the lvalue-to-rvalue conversion is explicit in the AST,
1104 // we bind an l-value if the operator is prefix and an lvalue (in C++).
1105 if (U->isGLValue())
1106 state = state->BindExpr(U, SF, loc);
1107 else
1108 state = state->BindExpr(U, SF, U->isPostfix() ? V2 : Result);
1109
1110 // Perform the store.
1111 Bldr.takeNodes(N);
1112 ExplodedNodeSet Dst3;
1113 evalStore(Dst3, U, Ex, N, state, loc, Result);
1114 Bldr.addNodes(Dst3);
1115 }
1116 Dst.insert(Dst2);
1117}
#define V(N, I)
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the clang::Expr interface and subclasses for C++ expressions.
#define X(type, name)
Definition Value.h:97
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:223
QualType getRValueReferenceType(QualType T) const
Return the uniqued reference to the type for an rvalue reference to the specified type.
static CanQualType getCanonicalType(QualType T)
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
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:4044
Expr * getLHS() const
Definition Expr.h:4094
Expr * getRHS() const
Definition Expr.h:4096
static bool isAdditiveOp(Opcode Opc)
Definition Expr.h:4130
static bool isAssignmentOp(Opcode Opc)
Definition Expr.h:4180
static bool isCompoundAssignmentOp(Opcode Opc)
Definition Expr.h:4185
Opcode getOpcode() const
Definition Expr.h:4089
BinaryOperatorKind Opcode
Definition Expr.h:4049
Represents a block literal declaration, which is like an unnamed FunctionDecl.
Definition Decl.h:4707
capture_const_iterator capture_begin() const
Definition Decl.h:4836
capture_const_iterator capture_end() const
Definition Decl.h:4837
const CFGBlock * getSrc() const
const CFGBlock * getDst() const
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
Definition Expr.h:6675
const BlockDecl * getBlockDecl() const
Definition Expr.h:6687
This class is used for builtin types like 'int'.
Definition TypeBase.h:3228
bool isInteger() const
Definition TypeBase.h:3289
Represents a single basic block in a source-level CFG.
Definition CFG.h:652
reverse_iterator rbegin()
Definition CFG.h:962
bool empty() const
Definition CFG.h:1000
CFGTerminator getTerminator() const
Definition CFG.h:1132
succ_iterator succ_begin()
Definition CFG.h:1037
unsigned succ_size() const
Definition CFG.h:1055
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:103
const Stmt * getStmt() const
Definition CFG.h:143
Represents CFGBlock terminator statement.
Definition CFG.h:579
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
Definition Expr.h:3682
CastKind getCastKind() const
Definition Expr.h:3726
llvm::iterator_range< path_iterator > path()
Path through the class hierarchy taken by casts between base and derived classes (see implementation ...
Definition Expr.h:3769
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:3611
A reference to a declared variable, function, enum, etc.
Definition Expr.h:1276
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
Definition Stmt.h:1641
bool isSingleDecl() const
isSingleDecl - This method returns true if this DeclStmt refers to a single Decl.
Definition Stmt.h:1654
decl_iterator decl_begin()
Definition Stmt.h:1695
ExplicitCastExpr - An explicit cast written in the source code.
Definition Expr.h:3934
This represents one expression.
Definition Expr.h:112
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:287
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx) 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:3095
QualType getType() const
Definition Expr.h:144
OffsetOfExpr - [C99 7.17] - This represents an expression of the form offsetof(record-type,...
Definition Expr.h:2533
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
Definition Expr.h:1184
Represents a point after we ran remove dead bindings BEFORE processing the given statement.
T castAs() const
Convert to the specified ProgramPoint type, asserting that this ProgramPoint is of the desired type.
std::optional< T > getAs() const
Convert to the specified ProgramPoint type, returning std::nullopt if this ProgramPoint is not of the...
A (possibly-)qualified type.
Definition TypeBase.h:937
It represents a stack frame of the call stack.
bool isSignedIntegerType() const
Return true if this is an integer type that is signed, according to C99 6.2.5p4 [char,...
Definition Type.cpp:2270
bool isRValueReferenceType() const
Definition TypeBase.h:8716
const T * castAs() const
Member-template castAs<specific type>.
Definition TypeBase.h:9344
bool isLValueReferenceType() const
Definition TypeBase.h:8712
bool isAnyComplexType() const
Definition TypeBase.h:8819
bool isVectorType() const
Definition TypeBase.h:8823
bool isFloatingType() const
Definition Type.cpp:2393
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand.
Definition Expr.h:2631
QualType getTypeOfArgument() const
Gets the argument type, or the type of the argument expression, whichever is appropriate.
Definition Expr.h:2700
UnaryExprOrTypeTrait getKind() const
Definition Expr.h:2663
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Definition Expr.h:2250
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition Decl.h:712
Represents a variable declaration or definition.
Definition Decl.h:932
const Expr * getInit() const
Definition Decl.h:1389
BlockDataRegion - A region that represents a block instance.
Definition MemRegion.h:705
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.
ExplodedNodeSet is a set of ExplodedNode * elements with the invariant that its elements cannot be nu...
void insert(ExplodedNode *N)
const ProgramStateRef & getState() const
ProgramPoint getLocation() const
getLocation - Returns the edge associated with the given node.
unsigned pred_size() const
const StackFrame * getStackFrame() const
void VisitBinaryOperator(const BinaryOperator *B, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitBinaryOperator - Transfer function logic for binary operators.
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:492
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:688
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 StackFrame *SF, QualType T, QualType ExTy, const CastExpr *CastE, NodeBuilder &Bldr, ExplodedNode *Pred)
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:214
StoreManager & getStoreManager()
Definition ExprEngine.h:479
ConstCFGElementRef getCFGElementRef() const
Definition ExprEngine.h:290
void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Ex, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitUnaryExprOrTypeTraitExpr - Transfer function for sizeof.
ProgramStateRef escapeValues(ProgramStateRef State, ArrayRef< SVal > Vs, PointerEscapeKind K, const CallEvent *Call=nullptr) const
A simple wrapper when you only need to notify checkers of pointer-escape of some values.
CheckerManager & getCheckerManager() const
Definition ExprEngine.h:223
static std::optional< SVal > getObjectUnderConstruction(ProgramStateRef State, const ConstructionContextItem &Item, const StackFrame *SF)
By looking at a certain item that may be potentially part of an object's ConstructionContext,...
unsigned getNumVisitedCurrent() const
Definition ExprEngine.h:299
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.
void handleUOExtension(ExplodedNode *N, const UnaryOperator *U, NodeBuilder &Bldr)
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:268
MemRegion - The root abstract class for all memory regions.
Definition MemRegion.h:97
This is the simplest builder which generates nodes in the ExplodedGraph.
Definition CoreEngine.h:265
void takeNodes(const ExplodedNodeSet &S)
Definition CoreEngine.h:330
ExplodedNode * generateNode(const ProgramPoint &PP, ProgramStateRef State, ExplodedNode *Pred, bool MarkAsSink=false)
Generates a node in the ExplodedGraph.
ExplodedNode * generateSink(const ProgramPoint &PP, ProgramStateRef State, ExplodedNode *Pred)
Generates a sink in the ExplodedGraph.
Definition CoreEngine.h:300
void addNodes(const ExplodedNodeSet &S)
Definition CoreEngine.h:336
const ExplodedNodeSet & getResults() const
Definition CoreEngine.h:326
SVal - This represents a symbolic expression, which can be either an L-value or an R-value.
Definition SVals.h:57
bool isUndef() const
Definition SVals.h:113
bool isZeroConstant() const
Definition SVals.cpp:257
bool isUnknownOrUndef() const
Definition SVals.h:115
bool isConstant() const
Definition SVals.cpp:245
T castAs() const
Convert to the specified SVal type, asserting that this SVal is of the desired type.
Definition SVals.h:84
bool isUnknown() const
Definition SVals.h:111
SVal evalDerivedToBase(SVal Derived, const CastExpr *Cast)
Evaluates a chain of derived-to-base casts through the path specified in Cast.
Definition Store.cpp:254
std::optional< SVal > evalBaseToDerived(SVal Base, QualType DerivedPtrType)
Attempts to do a down cast.
Definition Store.cpp:318
TypedValueRegion - An abstract class representing regions having a typed value.
Definition MemRegion.h:562
const VarDecl * getDecl() const override=0
Value representing integer constant.
Definition SVals.h:306
Value representing pointer-to-member.
Definition SVals.h:440
Definition SPIR.cpp:35
@ PSK_EscapeOther
The reason for pointer escape is unknown.
IntrusiveRefCntPtr< const ProgramState > ProgramStateRef
The JSON file list parser is used to communicate input to InstallAPI.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
bool isa(CodeGen::Address addr)
Definition Address.h:330
@ Result
The result type of a method or function.
Definition TypeBase.h:905
U cast(CodeGen::Address addr)
Definition Address.h:327
@ Other
Other implicit parameter.
Definition Decl.h:1772
EvalResult is a struct with detailed info about an evaluated expression.
Definition Expr.h:652