clang 24.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 ExplodedNode *N = Engine.makeNodeWithBinding(Pred, BE, V, State,
219
220 // FIXME: Move all post/pre visits to ::Visit().
221 getCheckerManager().runCheckersForPostStmt(Dst, N, BE, *this);
222}
223
226 const StackFrame *SF, QualType T, QualType ExTy,
227 const CastExpr *CastE, NodeBuilder &Bldr,
228 ExplodedNode *Pred) {
229 if (T->isLValueReferenceType()) {
230 assert(!CastE->getType()->isLValueReferenceType());
231 ExTy = getContext().getLValueReferenceType(ExTy);
232 } else if (T->isRValueReferenceType()) {
233 assert(!CastE->getType()->isRValueReferenceType());
234 ExTy = getContext().getRValueReferenceType(ExTy);
235 }
236 // Delegate to SValBuilder to process.
237 SVal OrigV = state->getSVal(Ex, SF);
238 SVal SimplifiedOrigV = svalBuilder.simplifySVal(state, OrigV);
239 SVal V = svalBuilder.evalCast(SimplifiedOrigV, T, ExTy);
240 // Negate the result if we're treating the boolean as a signed i1
241 if (CastE->getCastKind() == CK_BooleanToSignedIntegral && V.isValid())
242 V = svalBuilder.evalMinus(V.castAs<NonLoc>());
243
244 state = state->BindExpr(CastE, SF, V);
245 if (V.isUnknown() && !OrigV.isUnknown()) {
246 state = escapeValues(state, OrigV, PSK_EscapeOther);
247 }
248 Bldr.generateNode(CastE, Pred, state);
249
250 return state;
251}
252
253void ExprEngine::VisitCast(const CastExpr *CastE, const Expr *Ex,
254 ExplodedNode *Pred, ExplodedNodeSet &Dst) {
255
256 ExplodedNodeSet DstPreStmt;
257 getCheckerManager().runCheckersForPreStmt(DstPreStmt, Pred, CastE, *this);
258
259 if (CastE->getCastKind() == CK_LValueToRValue) {
260 for (ExplodedNode *Node : DstPreStmt) {
261 ProgramStateRef State = Node->getState();
262 const StackFrame *SF = Node->getStackFrame();
263 evalLoad(Dst, CastE, CastE, Node, State, State->getSVal(Ex, SF));
264 }
265 return;
266 }
267 if (CastE->getCastKind() == CK_LValueToRValueBitCast) {
268 // Handle `__builtin_bit_cast`:
269 ExplodedNodeSet DstEvalLoc;
270
271 // Simulate the lvalue-to-rvalue conversion on `Ex`:
272 for (ExplodedNode *Node : DstPreStmt) {
273 ProgramStateRef State = Node->getState();
274 const StackFrame *SF = Node->getStackFrame();
275 evalLocation(DstEvalLoc, CastE, Ex, Node, State, State->getSVal(Ex, SF),
276 true);
277 }
278 // Simulate the operation that actually casts the original value to a new
279 // value of the destination type :
280 NodeBuilder Bldr(DstEvalLoc, Dst, *currBldrCtx);
281
282 for (ExplodedNode *Node : DstEvalLoc) {
283 ProgramStateRef State = Node->getState();
284 const StackFrame *SF = Node->getStackFrame();
285 // Although `Ex` is an lvalue, it could have `Loc::ConcreteInt` kind
286 // (e.g., `(int *)123456`). In such cases, there is no MemRegion
287 // available and we can't get the value to be casted.
288 SVal CastedV = UnknownVal();
289
290 if (const MemRegion *MR = State->getSVal(Ex, SF).getAsRegion()) {
291 SVal OrigV = State->getSVal(MR);
292 CastedV = svalBuilder.evalCast(svalBuilder.simplifySVal(State, OrigV),
293 CastE->getType(), Ex->getType());
294 }
295 State = State->BindExpr(CastE, SF, CastedV);
296 Bldr.generateNode(CastE, Node, State);
297 }
298 return;
299 }
300
301 // All other casts.
302 QualType T = CastE->getType();
303 QualType ExTy = Ex->getType();
304
305 if (const ExplicitCastExpr *ExCast=dyn_cast_or_null<ExplicitCastExpr>(CastE))
306 T = ExCast->getTypeAsWritten();
307
308 NodeBuilder Bldr(DstPreStmt, Dst, *currBldrCtx);
309 for (ExplodedNode *Pred : DstPreStmt) {
310 ProgramStateRef state = Pred->getState();
311 const StackFrame *SF = Pred->getStackFrame();
312
313 switch (CastE->getCastKind()) {
314 case CK_LValueToRValue:
315 case CK_LValueToRValueBitCast:
316 llvm_unreachable("LValueToRValue casts handled earlier.");
317 case CK_ToVoid:
318 continue;
319 // The analyzer doesn't do anything special with these casts,
320 // since it understands retain/release semantics already.
321 case CK_ARCProduceObject:
322 case CK_ARCConsumeObject:
323 case CK_ARCReclaimReturnedObject:
324 case CK_ARCExtendBlockObject: // Fall-through.
325 case CK_CopyAndAutoreleaseBlockObject:
326 // The analyser can ignore atomic casts for now, although some future
327 // checkers may want to make certain that you're not modifying the same
328 // value through atomic and nonatomic pointers.
329 case CK_AtomicToNonAtomic:
330 case CK_NonAtomicToAtomic:
331 // True no-ops.
332 case CK_NoOp:
333 case CK_ConstructorConversion:
334 case CK_UserDefinedConversion:
335 case CK_FunctionToPointerDecay:
336 case CK_BuiltinFnToFnPtr:
337 case CK_HLSLArrayRValue: {
338 // Copy the SVal of Ex to CastE.
339 ProgramStateRef state = Pred->getState();
340 const StackFrame *SF = Pred->getStackFrame();
341 SVal V = state->getSVal(Ex, SF);
342 state = state->BindExpr(CastE, SF, V);
343 Bldr.generateNode(CastE, Pred, state);
344 continue;
345 }
346 case CK_MemberPointerToBoolean:
347 case CK_PointerToBoolean: {
348 SVal V = state->getSVal(Ex, SF);
349 auto PTMSV = V.getAs<nonloc::PointerToMember>();
350 if (PTMSV)
351 V = svalBuilder.makeTruthVal(!PTMSV->isNullMemberPointer(), ExTy);
352 if (V.isUndef() || PTMSV) {
353 state = state->BindExpr(CastE, SF, V);
354 Bldr.generateNode(CastE, Pred, state);
355 continue;
356 }
357 // Explicitly proceed with default handler for this case cascade.
358 state = handleLValueBitCast(state, Ex, SF, T, ExTy, CastE, Bldr, Pred);
359 continue;
360 }
361 case CK_Dependent:
362 case CK_ArrayToPointerDecay:
363 case CK_BitCast:
364 case CK_AddressSpaceConversion:
365 case CK_BooleanToSignedIntegral:
366 case CK_IntegralToPointer:
367 case CK_PointerToIntegral: {
368 SVal V = state->getSVal(Ex, SF);
370 state = state->BindExpr(CastE, SF, UnknownVal());
371 Bldr.generateNode(CastE, Pred, state);
372 continue;
373 }
374 // Explicitly proceed with default handler for this case cascade.
375 state = handleLValueBitCast(state, Ex, SF, T, ExTy, CastE, Bldr, Pred);
376 continue;
377 }
378 case CK_IntegralToBoolean:
379 case CK_IntegralToFloating:
380 case CK_FloatingToIntegral:
381 case CK_FloatingToBoolean:
382 case CK_FloatingCast:
383 case CK_FloatingRealToComplex:
384 case CK_FloatingComplexToReal:
385 case CK_FloatingComplexToBoolean:
386 case CK_FloatingComplexCast:
387 case CK_FloatingComplexToIntegralComplex:
388 case CK_IntegralRealToComplex:
389 case CK_IntegralComplexToReal:
390 case CK_IntegralComplexToBoolean:
391 case CK_IntegralComplexCast:
392 case CK_IntegralComplexToFloatingComplex:
393 case CK_CPointerToObjCPointerCast:
394 case CK_BlockPointerToObjCPointerCast:
395 case CK_AnyPointerToBlockPointerCast:
396 case CK_ObjCObjectLValueCast:
397 case CK_ZeroToOCLOpaqueType:
398 case CK_IntToOCLSampler:
399 case CK_LValueBitCast:
400 case CK_FloatingToFixedPoint:
401 case CK_FixedPointToFloating:
402 case CK_FixedPointCast:
403 case CK_FixedPointToBoolean:
404 case CK_FixedPointToIntegral:
405 case CK_IntegralToFixedPoint: {
406 state = handleLValueBitCast(state, Ex, SF, T, ExTy, CastE, Bldr, Pred);
407 continue;
408 }
409 case CK_IntegralCast: {
410 // Delegate to SValBuilder to process.
411 SVal V = state->getSVal(Ex, SF);
412 if (AMgr.options.analyzerSymbolicIntegerCasts())
413 V = svalBuilder.evalCast(V, T, ExTy);
414 else
415 V = svalBuilder.evalIntegralCast(state, V, T, ExTy);
416 state = state->BindExpr(CastE, SF, V);
417 Bldr.generateNode(CastE, Pred, state);
418 continue;
419 }
420 case CK_DerivedToBase:
421 case CK_UncheckedDerivedToBase: {
422 // For DerivedToBase cast, delegate to the store manager.
423 SVal val = state->getSVal(Ex, SF);
424 val = getStoreManager().evalDerivedToBase(val, CastE);
425 state = state->BindExpr(CastE, SF, val);
426 Bldr.generateNode(CastE, Pred, state);
427 continue;
428 }
429 // Handle C++ dyn_cast.
430 case CK_Dynamic: {
431 SVal val = state->getSVal(Ex, SF);
432
433 // Compute the type of the result.
434 QualType resultType = CastE->getType();
435 if (CastE->isGLValue())
436 resultType = getContext().getPointerType(resultType);
437
438 bool Failed = true;
439
440 // Check if the value being cast does not evaluates to 0.
441 if (!val.isZeroConstant())
442 if (std::optional<SVal> V =
443 StateMgr.getStoreManager().evalBaseToDerived(val, T)) {
444 val = *V;
445 Failed = false;
446 }
447
448 if (Failed) {
449 if (T->isReferenceType()) {
450 // A bad_cast exception is thrown if input value is a reference.
451 // Currently, we model this, by generating a sink.
452 Bldr.generateSink(CastE, Pred, state);
453 continue;
454 } else {
455 // If the cast fails on a pointer, bind to 0.
456 state = state->BindExpr(CastE, SF,
457 svalBuilder.makeNullWithType(resultType));
458 }
459 } else {
460 // If we don't know if the cast succeeded, conjure a new symbol.
461 if (val.isUnknown()) {
462 DefinedOrUnknownSVal NewSym = svalBuilder.conjureSymbolVal(
463 /*symbolTag=*/nullptr, getCFGElementRef(), SF, resultType,
465 state = state->BindExpr(CastE, SF, NewSym);
466 } else
467 // Else, bind to the derived region value.
468 state = state->BindExpr(CastE, SF, val);
469 }
470 Bldr.generateNode(CastE, Pred, state);
471 continue;
472 }
473 case CK_BaseToDerived: {
474 SVal val = state->getSVal(Ex, SF);
475 QualType resultType = CastE->getType();
476 if (CastE->isGLValue())
477 resultType = getContext().getPointerType(resultType);
478
479 if (!val.isConstant()) {
480 std::optional<SVal> V = getStoreManager().evalBaseToDerived(val, T);
481 val = V ? *V : UnknownVal();
482 }
483
484 // Failed to cast or the result is unknown, fall back to conservative.
485 if (val.isUnknown()) {
486 val = svalBuilder.conjureSymbolVal(
487 /*symbolTag=*/nullptr, getCFGElementRef(), SF, resultType,
489 }
490 state = state->BindExpr(CastE, SF, val);
491 Bldr.generateNode(CastE, Pred, state);
492 continue;
493 }
494 case CK_NullToPointer: {
495 SVal V = svalBuilder.makeNullWithType(CastE->getType());
496 state = state->BindExpr(CastE, SF, V);
497 Bldr.generateNode(CastE, Pred, state);
498 continue;
499 }
500 case CK_NullToMemberPointer: {
501 SVal V = svalBuilder.getMemberPointer(nullptr);
502 state = state->BindExpr(CastE, SF, V);
503 Bldr.generateNode(CastE, Pred, state);
504 continue;
505 }
506 case CK_DerivedToBaseMemberPointer:
507 case CK_BaseToDerivedMemberPointer:
508 case CK_ReinterpretMemberPointer: {
509 SVal V = state->getSVal(Ex, SF);
510 if (auto PTMSV = V.getAs<nonloc::PointerToMember>()) {
511 SVal CastedPTMSV =
512 svalBuilder.makePointerToMember(getBasicVals().accumCXXBase(
513 CastE->path(), *PTMSV, CastE->getCastKind()));
514 state = state->BindExpr(CastE, SF, CastedPTMSV);
515 Bldr.generateNode(CastE, Pred, state);
516 continue;
517 }
518 // Explicitly proceed with default handler for this case cascade.
519 }
520 [[fallthrough]];
521 // Various C++ casts that are not handled yet.
522 case CK_ToUnion:
523 case CK_MatrixCast:
524 case CK_VectorSplat:
525 case CK_HLSLElementwiseCast:
526 case CK_HLSLAggregateSplatCast:
527 case CK_HLSLMatrixTruncation:
528 case CK_HLSLVectorTruncation: {
529 QualType resultType = CastE->getType();
530 if (CastE->isGLValue())
531 resultType = getContext().getPointerType(resultType);
532 SVal result = svalBuilder.conjureSymbolVal(
533 /*symbolTag=*/nullptr, getCFGElementRef(), SF, resultType,
535 state = state->BindExpr(CastE, SF, result);
536 Bldr.generateNode(CastE, Pred, state);
537 continue;
538 }
539 }
540 }
541}
542
544 ExplodedNode *Pred,
545 ExplodedNodeSet &Dst) {
546 NodeBuilder B(Pred, Dst, *currBldrCtx);
547
548 ProgramStateRef State = Pred->getState();
549 const StackFrame *SF = Pred->getStackFrame();
550
551 const Expr *Init = CL->getInitializer();
552 SVal V = State->getSVal(CL->getInitializer(), SF);
553
555 // No work needed. Just pass the value up to this expression.
556 } else {
557 assert(isa<InitListExpr>(Init));
558 Loc CLLoc = State->getLValue(CL, SF);
559 State = State->bindLoc(CLLoc, V, SF);
560
561 if (CL->isGLValue())
562 V = CLLoc;
563 }
564
565 B.generateNode(CL, Pred, State->BindExpr(CL, SF, V));
566}
567
569 ExplodedNodeSet &Dst) {
570 if (isa<TypedefNameDecl>(*DS->decl_begin())) {
571 // C99 6.7.7 "Any array size expressions associated with variable length
572 // array declarators are evaluated each time the declaration of the typedef
573 // name is reached in the order of execution."
574 // The checkers should know about typedef to be able to handle VLA size
575 // expressions.
576 ExplodedNodeSet DstPre;
577 getCheckerManager().runCheckersForPreStmt(DstPre, Pred, DS, *this);
578 getCheckerManager().runCheckersForPostStmt(Dst, DstPre, DS, *this);
579 return;
580 }
581
582 // Assumption: The CFG has one DeclStmt per Decl.
583 const VarDecl *VD = dyn_cast_or_null<VarDecl>(*DS->decl_begin());
584
585 if (!VD) {
586 //TODO:AZ: remove explicit insertion after refactoring is done.
587 Dst.insert(Pred);
588 return;
589 }
590
591 // Self-assignment initialization in variable declaration,
592 // i.e., `int x = x;`,
593 // is a C idiom to suppress warnings of unused variables.
594 // This filter will not match variables of C++ record types, but will match
595 // C++ references. Allow references continuing here to make the undefined
596 // value checker report self-assignments of C++ references.
597 if (const Expr *EI = VD->getInit()) {
598 // Ignore InitListExpr if exists.
599 if (const auto *IL = dyn_cast<InitListExpr>(EI);
600 IL && IL->getNumInits() == 1)
601 EI = IL->getInit(0);
602
603 // Ignore parentheses and implict casts.
604 if (const auto *DR = dyn_cast<DeclRefExpr>(EI->IgnoreParenImpCasts())) {
605 if (VD == DR->getDecl() && !VD->getType()->isReferenceType()) {
606 Dst.insert(Pred);
607 return;
608 }
609 }
610 }
611
612 // FIXME: all pre/post visits should eventually be handled by ::Visit().
613 ExplodedNodeSet dstPreVisit;
614 getCheckerManager().runCheckersForPreStmt(dstPreVisit, Pred, DS, *this);
615
616 ExplodedNodeSet dstEvaluated;
617 NodeBuilder B(dstPreVisit, dstEvaluated, *currBldrCtx);
618 for (ExplodedNodeSet::iterator I = dstPreVisit.begin(), E = dstPreVisit.end();
619 I!=E; ++I) {
620 ExplodedNode *N = *I;
621 ProgramStateRef state = N->getState();
622 const StackFrame *SF = N->getStackFrame();
623
624 // Decls without InitExpr are not initialized explicitly.
625 if (const Expr *InitEx = VD->getInit()) {
626
627 // Note in the state that the initialization has occurred.
628 ExplodedNode *UpdatedN = N;
629 SVal InitVal = state->getSVal(InitEx, SF);
630
631 assert(DS->isSingleDecl());
632 if (getObjectUnderConstruction(state, DS, SF)) {
633 state = finishObjectConstruction(state, DS, SF);
634 // We constructed the object directly in the variable.
635 // No need to bind anything.
636 B.generateNode(DS, UpdatedN, state);
637 } else {
638 // Recover some path-sensitivity if a scalar value evaluated to
639 // UnknownVal.
640 if (InitVal.isUnknown()) {
641 QualType Ty = InitEx->getType();
642 if (InitEx->isGLValue()) {
643 Ty = getContext().getPointerType(Ty);
644 }
645
646 InitVal = svalBuilder.conjureSymbolVal(
647 /*symbolTag=*/nullptr, getCFGElementRef(), SF, Ty,
649 }
650
651
652 B.takeNodes(UpdatedN);
653 ExplodedNodeSet Dst2;
654 evalBind(Dst2, DS, UpdatedN, state->getLValue(VD, SF), InitVal, true);
655 B.addNodes(Dst2);
656 }
657 }
658 else {
659 B.generateNode(DS, N, state);
660 }
661 }
662
664}
665
667 ExplodedNodeSet &Dst) {
668 // This method acts upon CFG elements for logical operators && and ||
669 // and attaches the value (true or false) to them as expressions.
670 // It doesn't produce any state splits.
671 // If we made it that far, we're past the point when we modeled the short
672 // circuit. It means that we should have precise knowledge about whether
673 // we've short-circuited. If we did, we already know the value we need to
674 // bind. If we didn't, the value of the RHS (casted to the boolean type)
675 // is the answer.
676 // Currently this method tries to figure out whether we've short-circuited
677 // by looking at the ExplodedGraph. This method is imperfect because there
678 // could inevitably have been merges that would have resulted in multiple
679 // potential path traversal histories. We bail out when we fail.
680 // Due to this ambiguity, a more reliable solution would have been to
681 // track the short circuit operation history path-sensitively until
682 // we evaluate the respective logical operator.
683 assert(B->getOpcode() == BO_LAnd ||
684 B->getOpcode() == BO_LOr);
685
686 NodeBuilder Bldr(Pred, Dst, *currBldrCtx);
687 ProgramStateRef state = Pred->getState();
688
689 if (B->getType()->isVectorType()) {
690 // FIXME: We do not model vector arithmetic yet. When adding support for
691 // that, note that the CFG-based reasoning below does not apply, because
692 // logical operators on vectors are not short-circuit. Currently they are
693 // modeled as short-circuit in Clang CFG but this is incorrect.
694 // Do not set the value for the expression. It'd be UnknownVal by default.
695 Bldr.generateNode(B, Pred, state);
696 return;
697 }
698
699 ExplodedNode *N = Pred;
700 while (!N->getLocation().getAs<BlockEdge>()) {
701 ProgramPoint P = N->getLocation();
702 assert(P.getAs<PreStmt>() || P.getAs<PreStmtPurgeDeadSymbols>() ||
703 P.getAs<BlockEntrance>());
704 (void) P;
705 if (N->pred_size() != 1) {
706 // We failed to track back where we came from.
707 Bldr.generateNode(B, Pred, state);
708 return;
709 }
710 N = *N->pred_begin();
711 }
712
713 if (N->pred_size() != 1) {
714 // We failed to track back where we came from.
715 Bldr.generateNode(B, Pred, state);
716 return;
717 }
718
720 SVal X;
721
722 // Determine the value of the expression by introspecting how we
723 // got this location in the CFG. This requires looking at the previous
724 // block we were in and what kind of control-flow transfer was involved.
725 const CFGBlock *SrcBlock = BE.getSrc();
726 // The only terminator (if there is one) that makes sense is a logical op.
727 CFGTerminator T = SrcBlock->getTerminator();
728 if (const BinaryOperator *Term = cast_or_null<BinaryOperator>(T.getStmt())) {
729 (void) Term;
730 assert(Term->isLogicalOp());
731 assert(SrcBlock->succ_size() == 2);
732 // Did we take the true or false branch?
733 unsigned constant = (*SrcBlock->succ_begin() == BE.getDst()) ? 1 : 0;
734 X = svalBuilder.makeIntVal(constant, B->getType());
735 }
736 else {
737 // If there is no terminator, by construction the last statement
738 // in SrcBlock is the value of the enclosing expression.
739 // However, we still need to constrain that value to be 0 or 1.
740 assert(!SrcBlock->empty());
741 CFGStmt Elem = SrcBlock->rbegin()->castAs<CFGStmt>();
742 const Expr *RHS = cast<Expr>(Elem.getStmt());
743 SVal RHSVal = N->getState()->getSVal(RHS, Pred->getStackFrame());
744
745 if (RHSVal.isUndef()) {
746 X = RHSVal;
747 } else {
748 // We evaluate "RHSVal != 0" expression which result in 0 if the value is
749 // known to be false, 1 if the value is known to be true and a new symbol
750 // when the assumption is unknown.
751 X = evalBinOp(N->getState(), BO_NE, RHSVal,
752 svalBuilder.makeZeroVal(RHS->getType()), B->getType());
753 }
754 }
755 Bldr.generateNode(B, Pred, state->BindExpr(B, Pred->getStackFrame(), X));
756}
757
759 const Expr *L,
760 const Expr *R,
761 ExplodedNode *Pred,
762 ExplodedNodeSet &Dst) {
763 assert(L && R);
764
765 NodeBuilder B(Pred, Dst, *currBldrCtx);
766 ProgramStateRef state = Pred->getState();
767 const StackFrame *SF = Pred->getStackFrame();
768 const CFGBlock *SrcBlock = nullptr;
769
770 // Find the predecessor block.
771 ProgramStateRef SrcState = state;
772 for (const ExplodedNode *N = Pred ; N ; N = *N->pred_begin()) {
773 auto Edge = N->getLocationAs<BlockEdge>();
774 if (!Edge.has_value()) {
775 // If the state N has multiple predecessors P, it means that successors
776 // of P are all equivalent.
777 // In turn, that means that all nodes at P are equivalent in terms
778 // of observable behavior at N, and we can follow any of them.
779 // FIXME: a more robust solution which does not walk up the tree.
780 continue;
781 }
782 SrcBlock = Edge->getSrc();
783 SrcState = N->getState();
784 break;
785 }
786
787 assert(SrcBlock && "missing function entry");
788
789 // Find the last expression in the predecessor block. That is the
790 // expression that is used for the value of the ternary expression.
791 bool hasValue = false;
792 SVal V;
793
794 for (CFGElement CE : llvm::reverse(*SrcBlock)) {
795 if (std::optional<CFGStmt> CS = CE.getAs<CFGStmt>()) {
796 const Expr *ValEx = cast<Expr>(CS->getStmt());
797 ValEx = ValEx->IgnoreParens();
798
799 // For GNU extension '?:' operator, the left hand side will be an
800 // OpaqueValueExpr, so get the underlying expression.
801 if (const OpaqueValueExpr *OpaqueEx = dyn_cast<OpaqueValueExpr>(L))
802 L = OpaqueEx->getSourceExpr();
803
804 // If the last expression in the predecessor block matches true or false
805 // subexpression, get its the value.
806 if (ValEx == L->IgnoreParens() || ValEx == R->IgnoreParens()) {
807 hasValue = true;
808 V = SrcState->getSVal(ValEx, SF);
809 }
810 break;
811 }
812 }
813
814 if (!hasValue)
815 V = svalBuilder.conjureSymbolVal(nullptr, getCFGElementRef(), SF,
817
818 // Generate a new node with the binding from the appropriate path.
819 B.generateNode(Ex, Pred, state->BindExpr(Ex, SF, V, true));
820}
821
824 ExplodedNode *Pred, ExplodedNodeSet &Dst) {
825 NodeBuilder B(Pred, Dst, *currBldrCtx);
827 if (OOE->EvaluateAsInt(Result, getContext())) {
828 APSInt IV = Result.Val.getInt();
829 assert(IV.getBitWidth() == getContext().getTypeSize(OOE->getType()));
830 assert(OOE->getType()->castAs<BuiltinType>()->isInteger());
831 assert(IV.isSigned() == OOE->getType()->isSignedIntegerType());
832 SVal X = svalBuilder.makeIntVal(IV);
833 B.generateNode(OOE, Pred,
834 Pred->getState()->BindExpr(OOE, Pred->getStackFrame(), X));
835 }
836 // FIXME: Handle the case where __builtin_offsetof is not a constant.
837}
838
839
842 ExplodedNode *Pred,
843 ExplodedNodeSet &Dst) {
844 // FIXME: Prechecks eventually go in ::Visit().
845 ExplodedNodeSet CheckedSet;
846 getCheckerManager().runCheckersForPreStmt(CheckedSet, Pred, Ex, *this);
847
848 ExplodedNodeSet EvalSet;
849 NodeBuilder Bldr(CheckedSet, EvalSet, *currBldrCtx);
850
852
853 for (ExplodedNode *N : CheckedSet) {
854 if (Ex->getKind() == UETT_SizeOf || Ex->getKind() == UETT_DataSizeOf ||
855 Ex->getKind() == UETT_CountOf) {
856 if (!T->isIncompleteType() && !T->isConstantSizeType()) {
857 assert(T->isVariableArrayType() && "Unknown non-constant-sized type.");
858
859 // FIXME: Add support for VLA type arguments and VLA expressions.
860 // When that happens, we should probably refactor VLASizeChecker's code.
861 continue;
862 } else if (T->getAs<ObjCObjectType>()) {
863 // Some code tries to take the sizeof an ObjCObjectType, relying that
864 // the compiler has laid out its representation. Just report Unknown
865 // for these.
866 continue;
867 }
868 }
869
870 APSInt Value = Ex->EvaluateKnownConstInt(getContext());
871 CharUnits amt = CharUnits::fromQuantity(Value.getZExtValue());
872
873 ProgramStateRef state = N->getState();
874 state = state->BindExpr(
875 Ex, N->getStackFrame(),
876 svalBuilder.makeIntVal(amt.getQuantity(), Ex->getType()));
877 Bldr.generateNode(Ex, N, state);
878 }
879
880 getCheckerManager().runCheckersForPostStmt(Dst, EvalSet, Ex, *this);
881}
882
884 ExplodedNodeSet &Dst) {
885 // FIXME: Prechecks eventually go in ::Visit().
886 ExplodedNodeSet CheckedSet;
887 getCheckerManager().runCheckersForPreStmt(CheckedSet, Pred, U, *this);
888
889 ExplodedNodeSet EvalSet;
890
891 // Lambda for handling the case when the operand is returned unchanged.
892 auto MakeNodeForIdentityOp = [U, &Engine = Engine](ExplodedNode *N) {
893 const Expr *Ex = U->getSubExpr()->IgnoreParens();
894 SVal SV = N->getState()->getSVal(Ex, N->getStackFrame());
895 return Engine.makeNodeWithBinding(N, U, SV);
896 };
897
898 for (ExplodedNode *N : CheckedSet) {
899 switch (U->getOpcode()) {
900 default: {
901 ExplodedNodeSet Tmp;
903 EvalSet.insert(Tmp);
904 break;
905 }
906 case UO_Real: {
907 const Expr *Ex = U->getSubExpr()->IgnoreParens();
908
909 // FIXME: We don't have complex SValues yet.
910 if (Ex->getType()->isAnyComplexType()) {
911 // Just report "Unknown."
912 EvalSet.insert(N);
913 break;
914 }
915
916 // For all other types, UO_Real is an identity operation.
917 assert (U->getType() == Ex->getType());
918 EvalSet.insert(MakeNodeForIdentityOp(N));
919 break;
920 }
921
922 case UO_Imag: {
923 const Expr *Ex = U->getSubExpr()->IgnoreParens();
924 // FIXME: We don't have complex SValues yet.
925 if (Ex->getType()->isAnyComplexType()) {
926 // Just report "Unknown."
927 EvalSet.insert(N);
928 break;
929 }
930 // For all other types, UO_Imag returns 0.
931 SVal X = svalBuilder.makeZeroVal(Ex->getType());
932 EvalSet.insert(Engine.makeNodeWithBinding(N, U, X));
933 break;
934 }
935
936 case UO_AddrOf: {
937 // Process pointer-to-member address operation.
938 const Expr *Ex = U->getSubExpr()->IgnoreParens();
939 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Ex)) {
940 const ValueDecl *VD = DRE->getDecl();
941
943 SVal SV = svalBuilder.getMemberPointer(cast<NamedDecl>(VD));
944 EvalSet.insert(Engine.makeNodeWithBinding(N, U, SV));
945 break;
946 }
947 }
948 // Explicitly proceed with default handler for this case cascade.
949 EvalSet.insert(MakeNodeForIdentityOp(N));
950 break;
951 }
952 case UO_Plus:
953 assert(!U->isGLValue());
954 [[fallthrough]];
955 case UO_Deref:
956 case UO_Extension: {
957 EvalSet.insert(MakeNodeForIdentityOp(N));
958 break;
959 }
960
961 case UO_LNot:
962 case UO_Minus:
963 case UO_Not: {
964 assert (!U->isGLValue());
965 const Expr *Ex = U->getSubExpr()->IgnoreParens();
966 ProgramStateRef state = N->getState();
967 const StackFrame *SF = N->getStackFrame();
968
969 // Get the value of the subexpression.
970 SVal V = state->getSVal(Ex, SF);
971
972 if (V.isUnknownOrUndef()) {
973 EvalSet.insert(Engine.makeNodeWithBinding(N, U, V));
974 break;
975 }
976
977 switch (U->getOpcode()) {
978 default:
979 llvm_unreachable("Invalid Opcode.");
980 case UO_Not:
981 // FIXME: Do we need to handle promotions?
982 state = state->BindExpr(
983 U, SF, svalBuilder.evalComplement(V.castAs<NonLoc>()));
984 break;
985 case UO_Minus:
986 // FIXME: Do we need to handle promotions?
987 state =
988 state->BindExpr(U, SF, svalBuilder.evalMinus(V.castAs<NonLoc>()));
989 break;
990 case UO_LNot:
991 // C99 6.5.3.3: "The expression !E is equivalent to (0==E)."
992 //
993 // Note: technically we do "E == 0", but this is the same in the
994 // transfer functions as "0 == E".
995 SVal Result;
996 if (std::optional<Loc> LV = V.getAs<Loc>()) {
997 Loc X = svalBuilder.makeNullWithType(Ex->getType());
998 Result = evalBinOp(state, BO_EQ, *LV, X, U->getType());
999 } else if (Ex->getType()->isFloatingType()) {
1000 // FIXME: handle floating point types.
1001 Result = UnknownVal();
1002 } else {
1003 nonloc::ConcreteInt X(getBasicVals().getValue(0, Ex->getType()));
1004 Result = evalBinOp(state, BO_EQ, V.castAs<NonLoc>(), X, U->getType());
1005 }
1006
1007 state = state->BindExpr(U, SF, Result);
1008 break;
1009 }
1010 EvalSet.insert(Engine.makePostStmtNode(U, state, N));
1011 break;
1012 }
1013 }
1014 }
1015
1016 getCheckerManager().runCheckersForPostStmt(Dst, EvalSet, U, *this);
1017}
1018
1020 ExplodedNode *Pred,
1021 ExplodedNodeSet &Dst) {
1022 // Handle ++ and -- (both pre- and post-increment).
1023 assert (U->isIncrementDecrementOp());
1024 const Expr *Ex = U->getSubExpr()->IgnoreParens();
1025
1026 const StackFrame *SF = Pred->getStackFrame();
1027 ProgramStateRef state = Pred->getState();
1028 SVal loc = state->getSVal(Ex, SF);
1029
1030 // Perform a load.
1031 ExplodedNodeSet Tmp;
1032 evalLoad(Tmp, U, Ex, Pred, state, loc);
1033
1034 ExplodedNodeSet Dst2;
1035 NodeBuilder Bldr(Tmp, Dst2, *currBldrCtx);
1036 for (ExplodedNode *N : Tmp) {
1037 state = N->getState();
1038 assert(SF == N->getStackFrame());
1039 SVal V2_untested = state->getSVal(Ex, SF);
1040
1041 // Propagate unknown and undefined values.
1042 if (V2_untested.isUnknownOrUndef()) {
1043 state = state->BindExpr(U, SF, V2_untested);
1044
1045 // Perform the store, so that the uninitialized value detection happens.
1046 Bldr.takeNodes(N);
1047 ExplodedNodeSet Dst3;
1048 evalStore(Dst3, U, Ex, N, state, loc, V2_untested);
1049 Bldr.addNodes(Dst3);
1050
1051 continue;
1052 }
1053 DefinedSVal V2 = V2_untested.castAs<DefinedSVal>();
1054
1055 // Handle all other values.
1056 BinaryOperator::Opcode Op = U->isIncrementOp() ? BO_Add : BO_Sub;
1057
1058 // If the UnaryOperator has non-location type, use its type to create the
1059 // constant value. If the UnaryOperator has location type, create the
1060 // constant with int type and pointer width.
1061 SVal RHS;
1062 SVal Result;
1063
1064 if (U->getType()->isAnyPointerType())
1065 RHS = svalBuilder.makeArrayIndex(1);
1066 else if (U->getType()->isIntegralOrEnumerationType())
1067 RHS = svalBuilder.makeIntVal(1, U->getType());
1068 else
1069 RHS = UnknownVal();
1070
1071 // The use of an operand of type bool with the ++ operators is deprecated
1072 // but valid until C++17. And if the operand of the ++ operator is of type
1073 // bool, it is set to true until C++17. Note that for '_Bool', it is also
1074 // set to true when it encounters ++ operator.
1075 if (U->getType()->isBooleanType() && U->isIncrementOp())
1076 Result = svalBuilder.makeTruthVal(true, U->getType());
1077 else
1078 Result = evalBinOp(state, Op, V2, RHS, U->getType());
1079
1080 // Conjure a new symbol if necessary to recover precision.
1081 if (Result.isUnknown()){
1082 DefinedOrUnknownSVal SymVal = svalBuilder.conjureSymbolVal(
1083 /*symbolTag=*/nullptr, getCFGElementRef(), SF,
1085 Result = SymVal;
1086
1087 // If the value is a location, ++/-- should always preserve
1088 // non-nullness. Check if the original value was non-null, and if so
1089 // propagate that constraint.
1090 if (Loc::isLocType(U->getType())) {
1091 DefinedOrUnknownSVal Constraint =
1092 svalBuilder.evalEQ(state, V2,svalBuilder.makeZeroVal(U->getType()));
1093
1094 if (!state->assume(Constraint, true)) {
1095 // It isn't feasible for the original value to be null.
1096 // Propagate this constraint.
1097 Constraint = svalBuilder.evalEQ(state, SymVal,
1098 svalBuilder.makeZeroVal(U->getType()));
1099
1100 state = state->assume(Constraint, false);
1101 assert(state);
1102 }
1103 }
1104 }
1105
1106 // Since the lvalue-to-rvalue conversion is explicit in the AST,
1107 // we bind an l-value if the operator is prefix and an lvalue (in C++).
1108 if (U->isGLValue())
1109 state = state->BindExpr(U, SF, loc);
1110 else
1111 state = state->BindExpr(U, SF, U->isPostfix() ? V2 : Result);
1112
1113 // Perform the store.
1114 Bldr.takeNodes(N);
1115 ExplodedNodeSet Dst3;
1116 evalStore(Dst3, U, Ex, N, state, loc, Result);
1117 Bldr.addNodes(Dst3);
1118 }
1119 Dst.insert(Dst2);
1120}
#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:4716
capture_const_iterator capture_begin() const
Definition Decl.h:4845
capture_const_iterator capture_end() const
Definition Decl.h:4846
const CFGBlock * getSrc() const
const CFGBlock * getDst() const
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
Definition Expr.h:6684
const BlockDecl * getBlockDecl() const
Definition Expr.h:6696
This class is used for builtin types like 'int'.
Definition TypeBase.h:3229
bool isInteger() const
Definition TypeBase.h:3290
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:1640
bool isSingleDecl() const
isSingleDecl - This method returns true if this DeclStmt refers to a single Decl.
Definition Stmt.h:1653
decl_iterator decl_begin()
Definition Stmt.h:1694
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:3097
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:938
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:8758
const T * castAs() const
Member-template castAs<specific type>.
Definition TypeBase.h:9386
bool isReferenceType() const
Definition TypeBase.h:8750
bool isLValueReferenceType() const
Definition TypeBase.h:8754
bool isAnyComplexType() const
Definition TypeBase.h:8861
bool isVectorType() const
Definition TypeBase.h:8865
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
QualType getType() const
Definition Decl.h:723
Represents a variable declaration or definition.
Definition Decl.h:932
const Expr * getInit() const
Definition Decl.h:1391
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:685
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 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:906
const FunctionProtoType * T
U cast(CodeGen::Address addr)
Definition Address.h:327
@ Other
Other implicit parameter.
Definition Decl.h:1774
EvalResult is a struct with detailed info about an evaluated expression.
Definition Expr.h:652