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 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 // Self-assignment initialization in variable declaration,
594 // i.e., `int x = x;`,
595 // is a C idiom to suppress warnings of unused variables.
596 // This filter will not match variables of C++ record types, but will match
597 // C++ references. Allow references continuing here to make the undefined
598 // value checker report self-assignments of C++ references.
599 if (const Expr *EI = VD->getInit()) {
600 // Ignore InitListExpr if exists.
601 if (const auto *IL = dyn_cast<InitListExpr>(EI);
602 IL && IL->getNumInits() == 1)
603 EI = IL->getInit(0);
604
605 // Ignore parentheses and implict casts.
606 if (const auto *DR = dyn_cast<DeclRefExpr>(EI->IgnoreParenImpCasts())) {
607 if (VD == DR->getDecl() && !VD->getType()->isReferenceType()) {
608 Dst.insert(Pred);
609 return;
610 }
611 }
612 }
613
614 // FIXME: all pre/post visits should eventually be handled by ::Visit().
615 ExplodedNodeSet dstPreVisit;
616 getCheckerManager().runCheckersForPreStmt(dstPreVisit, Pred, DS, *this);
617
618 ExplodedNodeSet dstEvaluated;
619 NodeBuilder B(dstPreVisit, dstEvaluated, *currBldrCtx);
620 for (ExplodedNodeSet::iterator I = dstPreVisit.begin(), E = dstPreVisit.end();
621 I!=E; ++I) {
622 ExplodedNode *N = *I;
623 ProgramStateRef state = N->getState();
624 const StackFrame *SF = N->getStackFrame();
625
626 // Decls without InitExpr are not initialized explicitly.
627 if (const Expr *InitEx = VD->getInit()) {
628
629 // Note in the state that the initialization has occurred.
630 ExplodedNode *UpdatedN = N;
631 SVal InitVal = state->getSVal(InitEx, SF);
632
633 assert(DS->isSingleDecl());
634 if (getObjectUnderConstruction(state, DS, SF)) {
635 state = finishObjectConstruction(state, DS, SF);
636 // We constructed the object directly in the variable.
637 // No need to bind anything.
638 B.generateNode(DS, UpdatedN, state);
639 } else {
640 // Recover some path-sensitivity if a scalar value evaluated to
641 // UnknownVal.
642 if (InitVal.isUnknown()) {
643 QualType Ty = InitEx->getType();
644 if (InitEx->isGLValue()) {
645 Ty = getContext().getPointerType(Ty);
646 }
647
648 InitVal = svalBuilder.conjureSymbolVal(
649 /*symbolTag=*/nullptr, getCFGElementRef(), SF, Ty,
651 }
652
653
654 B.takeNodes(UpdatedN);
655 ExplodedNodeSet Dst2;
656 evalBind(Dst2, DS, UpdatedN, state->getLValue(VD, SF), InitVal, true);
657 B.addNodes(Dst2);
658 }
659 }
660 else {
661 B.generateNode(DS, N, state);
662 }
663 }
664
666}
667
669 ExplodedNodeSet &Dst) {
670 // This method acts upon CFG elements for logical operators && and ||
671 // and attaches the value (true or false) to them as expressions.
672 // It doesn't produce any state splits.
673 // If we made it that far, we're past the point when we modeled the short
674 // circuit. It means that we should have precise knowledge about whether
675 // we've short-circuited. If we did, we already know the value we need to
676 // bind. If we didn't, the value of the RHS (casted to the boolean type)
677 // is the answer.
678 // Currently this method tries to figure out whether we've short-circuited
679 // by looking at the ExplodedGraph. This method is imperfect because there
680 // could inevitably have been merges that would have resulted in multiple
681 // potential path traversal histories. We bail out when we fail.
682 // Due to this ambiguity, a more reliable solution would have been to
683 // track the short circuit operation history path-sensitively until
684 // we evaluate the respective logical operator.
685 assert(B->getOpcode() == BO_LAnd ||
686 B->getOpcode() == BO_LOr);
687
688 NodeBuilder Bldr(Pred, Dst, *currBldrCtx);
689 ProgramStateRef state = Pred->getState();
690
691 if (B->getType()->isVectorType()) {
692 // FIXME: We do not model vector arithmetic yet. When adding support for
693 // that, note that the CFG-based reasoning below does not apply, because
694 // logical operators on vectors are not short-circuit. Currently they are
695 // modeled as short-circuit in Clang CFG but this is incorrect.
696 // Do not set the value for the expression. It'd be UnknownVal by default.
697 Bldr.generateNode(B, Pred, state);
698 return;
699 }
700
701 ExplodedNode *N = Pred;
702 while (!N->getLocation().getAs<BlockEdge>()) {
703 ProgramPoint P = N->getLocation();
704 assert(P.getAs<PreStmt>() || P.getAs<PreStmtPurgeDeadSymbols>() ||
705 P.getAs<BlockEntrance>());
706 (void) P;
707 if (N->pred_size() != 1) {
708 // We failed to track back where we came from.
709 Bldr.generateNode(B, Pred, state);
710 return;
711 }
712 N = *N->pred_begin();
713 }
714
715 if (N->pred_size() != 1) {
716 // We failed to track back where we came from.
717 Bldr.generateNode(B, Pred, state);
718 return;
719 }
720
722 SVal X;
723
724 // Determine the value of the expression by introspecting how we
725 // got this location in the CFG. This requires looking at the previous
726 // block we were in and what kind of control-flow transfer was involved.
727 const CFGBlock *SrcBlock = BE.getSrc();
728 // The only terminator (if there is one) that makes sense is a logical op.
729 CFGTerminator T = SrcBlock->getTerminator();
730 if (const BinaryOperator *Term = cast_or_null<BinaryOperator>(T.getStmt())) {
731 (void) Term;
732 assert(Term->isLogicalOp());
733 assert(SrcBlock->succ_size() == 2);
734 // Did we take the true or false branch?
735 unsigned constant = (*SrcBlock->succ_begin() == BE.getDst()) ? 1 : 0;
736 X = svalBuilder.makeIntVal(constant, B->getType());
737 }
738 else {
739 // If there is no terminator, by construction the last statement
740 // in SrcBlock is the value of the enclosing expression.
741 // However, we still need to constrain that value to be 0 or 1.
742 assert(!SrcBlock->empty());
743 CFGStmt Elem = SrcBlock->rbegin()->castAs<CFGStmt>();
744 const Expr *RHS = cast<Expr>(Elem.getStmt());
745 SVal RHSVal = N->getState()->getSVal(RHS, Pred->getStackFrame());
746
747 if (RHSVal.isUndef()) {
748 X = RHSVal;
749 } else {
750 // We evaluate "RHSVal != 0" expression which result in 0 if the value is
751 // known to be false, 1 if the value is known to be true and a new symbol
752 // when the assumption is unknown.
753 nonloc::ConcreteInt Zero(getBasicVals().getValue(0, B->getType()));
754 X = evalBinOp(N->getState(), BO_NE,
755 svalBuilder.evalCast(RHSVal, B->getType(), RHS->getType()),
756 Zero, B->getType());
757 }
758 }
759 Bldr.generateNode(B, Pred, state->BindExpr(B, Pred->getStackFrame(), X));
760}
761
763 const Expr *L,
764 const Expr *R,
765 ExplodedNode *Pred,
766 ExplodedNodeSet &Dst) {
767 assert(L && R);
768
769 NodeBuilder B(Pred, Dst, *currBldrCtx);
770 ProgramStateRef state = Pred->getState();
771 const StackFrame *SF = Pred->getStackFrame();
772 const CFGBlock *SrcBlock = nullptr;
773
774 // Find the predecessor block.
775 ProgramStateRef SrcState = state;
776 for (const ExplodedNode *N = Pred ; N ; N = *N->pred_begin()) {
777 auto Edge = N->getLocationAs<BlockEdge>();
778 if (!Edge.has_value()) {
779 // If the state N has multiple predecessors P, it means that successors
780 // of P are all equivalent.
781 // In turn, that means that all nodes at P are equivalent in terms
782 // of observable behavior at N, and we can follow any of them.
783 // FIXME: a more robust solution which does not walk up the tree.
784 continue;
785 }
786 SrcBlock = Edge->getSrc();
787 SrcState = N->getState();
788 break;
789 }
790
791 assert(SrcBlock && "missing function entry");
792
793 // Find the last expression in the predecessor block. That is the
794 // expression that is used for the value of the ternary expression.
795 bool hasValue = false;
796 SVal V;
797
798 for (CFGElement CE : llvm::reverse(*SrcBlock)) {
799 if (std::optional<CFGStmt> CS = CE.getAs<CFGStmt>()) {
800 const Expr *ValEx = cast<Expr>(CS->getStmt());
801 ValEx = ValEx->IgnoreParens();
802
803 // For GNU extension '?:' operator, the left hand side will be an
804 // OpaqueValueExpr, so get the underlying expression.
805 if (const OpaqueValueExpr *OpaqueEx = dyn_cast<OpaqueValueExpr>(L))
806 L = OpaqueEx->getSourceExpr();
807
808 // If the last expression in the predecessor block matches true or false
809 // subexpression, get its the value.
810 if (ValEx == L->IgnoreParens() || ValEx == R->IgnoreParens()) {
811 hasValue = true;
812 V = SrcState->getSVal(ValEx, SF);
813 }
814 break;
815 }
816 }
817
818 if (!hasValue)
819 V = svalBuilder.conjureSymbolVal(nullptr, getCFGElementRef(), SF,
821
822 // Generate a new node with the binding from the appropriate path.
823 B.generateNode(Ex, Pred, state->BindExpr(Ex, SF, V, true));
824}
825
828 ExplodedNode *Pred, ExplodedNodeSet &Dst) {
829 NodeBuilder B(Pred, Dst, *currBldrCtx);
831 if (OOE->EvaluateAsInt(Result, getContext())) {
832 APSInt IV = Result.Val.getInt();
833 assert(IV.getBitWidth() == getContext().getTypeSize(OOE->getType()));
834 assert(OOE->getType()->castAs<BuiltinType>()->isInteger());
835 assert(IV.isSigned() == OOE->getType()->isSignedIntegerType());
836 SVal X = svalBuilder.makeIntVal(IV);
837 B.generateNode(OOE, Pred,
838 Pred->getState()->BindExpr(OOE, Pred->getStackFrame(), X));
839 }
840 // FIXME: Handle the case where __builtin_offsetof is not a constant.
841}
842
843
846 ExplodedNode *Pred,
847 ExplodedNodeSet &Dst) {
848 // FIXME: Prechecks eventually go in ::Visit().
849 ExplodedNodeSet CheckedSet;
850 getCheckerManager().runCheckersForPreStmt(CheckedSet, Pred, Ex, *this);
851
852 ExplodedNodeSet EvalSet;
853 NodeBuilder Bldr(CheckedSet, EvalSet, *currBldrCtx);
854
855 QualType T = Ex->getTypeOfArgument();
856
857 for (ExplodedNode *N : CheckedSet) {
858 if (Ex->getKind() == UETT_SizeOf || Ex->getKind() == UETT_DataSizeOf ||
859 Ex->getKind() == UETT_CountOf) {
860 if (!T->isIncompleteType() && !T->isConstantSizeType()) {
861 assert(T->isVariableArrayType() && "Unknown non-constant-sized type.");
862
863 // FIXME: Add support for VLA type arguments and VLA expressions.
864 // When that happens, we should probably refactor VLASizeChecker's code.
865 continue;
866 } else if (T->getAs<ObjCObjectType>()) {
867 // Some code tries to take the sizeof an ObjCObjectType, relying that
868 // the compiler has laid out its representation. Just report Unknown
869 // for these.
870 continue;
871 }
872 }
873
874 APSInt Value = Ex->EvaluateKnownConstInt(getContext());
875 CharUnits amt = CharUnits::fromQuantity(Value.getZExtValue());
876
877 ProgramStateRef state = N->getState();
878 state = state->BindExpr(
879 Ex, N->getStackFrame(),
880 svalBuilder.makeIntVal(amt.getQuantity(), Ex->getType()));
881 Bldr.generateNode(Ex, N, state);
882 }
883
884 getCheckerManager().runCheckersForPostStmt(Dst, EvalSet, Ex, *this);
885}
886
888 NodeBuilder &Bldr) {
889 // FIXME: We can probably just have some magic in Environment::getSVal()
890 // that propagates values, instead of creating a new node here.
891 //
892 // Unary "+" is a no-op, similar to a parentheses. We still have places
893 // where it may be a block-level expression, so we need to
894 // generate an extra node that just propagates the value of the
895 // subexpression.
896 const Expr *Ex = U->getSubExpr()->IgnoreParens();
897 ProgramStateRef state = N->getState();
898 const StackFrame *SF = N->getStackFrame();
899 Bldr.generateNode(U, N, state->BindExpr(U, SF, state->getSVal(Ex, SF)));
900}
901
903 ExplodedNodeSet &Dst) {
904 // FIXME: Prechecks eventually go in ::Visit().
905 ExplodedNodeSet CheckedSet;
906 getCheckerManager().runCheckersForPreStmt(CheckedSet, Pred, U, *this);
907
908 ExplodedNodeSet EvalSet;
909 NodeBuilder Bldr(CheckedSet, EvalSet, *currBldrCtx);
910
911 for (ExplodedNode *N : CheckedSet) {
912 switch (U->getOpcode()) {
913 default: {
914 Bldr.takeNodes(N);
915 ExplodedNodeSet Tmp;
917 Bldr.addNodes(Tmp);
918 break;
919 }
920 case UO_Real: {
921 const Expr *Ex = U->getSubExpr()->IgnoreParens();
922
923 // FIXME: We don't have complex SValues yet.
924 if (Ex->getType()->isAnyComplexType()) {
925 // Just report "Unknown."
926 break;
927 }
928
929 // For all other types, UO_Real is an identity operation.
930 assert (U->getType() == Ex->getType());
931 ProgramStateRef state = N->getState();
932 const StackFrame *SF = N->getStackFrame();
933 Bldr.generateNode(U, N, state->BindExpr(U, SF, state->getSVal(Ex, SF)));
934 break;
935 }
936
937 case UO_Imag: {
938 const Expr *Ex = U->getSubExpr()->IgnoreParens();
939 // FIXME: We don't have complex SValues yet.
940 if (Ex->getType()->isAnyComplexType()) {
941 // Just report "Unknown."
942 break;
943 }
944 // For all other types, UO_Imag returns 0.
945 ProgramStateRef state = N->getState();
946 const StackFrame *SF = N->getStackFrame();
947 SVal X = svalBuilder.makeZeroVal(Ex->getType());
948 Bldr.generateNode(U, N, state->BindExpr(U, SF, X));
949 break;
950 }
951
952 case UO_AddrOf: {
953 // Process pointer-to-member address operation.
954 const Expr *Ex = U->getSubExpr()->IgnoreParens();
955 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Ex)) {
956 const ValueDecl *VD = DRE->getDecl();
957
959 ProgramStateRef State = N->getState();
960 const StackFrame *SF = N->getStackFrame();
961 SVal SV = svalBuilder.getMemberPointer(cast<NamedDecl>(VD));
962 Bldr.generateNode(U, N, State->BindExpr(U, SF, SV));
963 break;
964 }
965 }
966 // Explicitly proceed with default handler for this case cascade.
967 handleUOExtension(N, U, Bldr);
968 break;
969 }
970 case UO_Plus:
971 assert(!U->isGLValue());
972 [[fallthrough]];
973 case UO_Deref:
974 case UO_Extension: {
975 handleUOExtension(N, U, Bldr);
976 break;
977 }
978
979 case UO_LNot:
980 case UO_Minus:
981 case UO_Not: {
982 assert (!U->isGLValue());
983 const Expr *Ex = U->getSubExpr()->IgnoreParens();
984 ProgramStateRef state = N->getState();
985 const StackFrame *SF = N->getStackFrame();
986
987 // Get the value of the subexpression.
988 SVal V = state->getSVal(Ex, SF);
989
990 if (V.isUnknownOrUndef()) {
991 Bldr.generateNode(U, N, state->BindExpr(U, SF, V));
992 break;
993 }
994
995 switch (U->getOpcode()) {
996 default:
997 llvm_unreachable("Invalid Opcode.");
998 case UO_Not:
999 // FIXME: Do we need to handle promotions?
1000 state = state->BindExpr(
1001 U, SF, svalBuilder.evalComplement(V.castAs<NonLoc>()));
1002 break;
1003 case UO_Minus:
1004 // FIXME: Do we need to handle promotions?
1005 state =
1006 state->BindExpr(U, SF, svalBuilder.evalMinus(V.castAs<NonLoc>()));
1007 break;
1008 case UO_LNot:
1009 // C99 6.5.3.3: "The expression !E is equivalent to (0==E)."
1010 //
1011 // Note: technically we do "E == 0", but this is the same in the
1012 // transfer functions as "0 == E".
1013 SVal Result;
1014 if (std::optional<Loc> LV = V.getAs<Loc>()) {
1015 Loc X = svalBuilder.makeNullWithType(Ex->getType());
1016 Result = evalBinOp(state, BO_EQ, *LV, X, U->getType());
1017 } else if (Ex->getType()->isFloatingType()) {
1018 // FIXME: handle floating point types.
1019 Result = UnknownVal();
1020 } else {
1021 nonloc::ConcreteInt X(getBasicVals().getValue(0, Ex->getType()));
1022 Result = evalBinOp(state, BO_EQ, V.castAs<NonLoc>(), X, U->getType());
1023 }
1024
1025 state = state->BindExpr(U, SF, Result);
1026 break;
1027 }
1028 Bldr.generateNode(U, N, state);
1029 break;
1030 }
1031 }
1032 }
1033
1034 getCheckerManager().runCheckersForPostStmt(Dst, EvalSet, U, *this);
1035}
1036
1038 ExplodedNode *Pred,
1039 ExplodedNodeSet &Dst) {
1040 // Handle ++ and -- (both pre- and post-increment).
1041 assert (U->isIncrementDecrementOp());
1042 const Expr *Ex = U->getSubExpr()->IgnoreParens();
1043
1044 const StackFrame *SF = Pred->getStackFrame();
1045 ProgramStateRef state = Pred->getState();
1046 SVal loc = state->getSVal(Ex, SF);
1047
1048 // Perform a load.
1049 ExplodedNodeSet Tmp;
1050 evalLoad(Tmp, U, Ex, Pred, state, loc);
1051
1052 ExplodedNodeSet Dst2;
1053 NodeBuilder Bldr(Tmp, Dst2, *currBldrCtx);
1054 for (ExplodedNode *N : Tmp) {
1055 state = N->getState();
1056 assert(SF == N->getStackFrame());
1057 SVal V2_untested = state->getSVal(Ex, SF);
1058
1059 // Propagate unknown and undefined values.
1060 if (V2_untested.isUnknownOrUndef()) {
1061 state = state->BindExpr(U, SF, V2_untested);
1062
1063 // Perform the store, so that the uninitialized value detection happens.
1064 Bldr.takeNodes(N);
1065 ExplodedNodeSet Dst3;
1066 evalStore(Dst3, U, Ex, N, state, loc, V2_untested);
1067 Bldr.addNodes(Dst3);
1068
1069 continue;
1070 }
1071 DefinedSVal V2 = V2_untested.castAs<DefinedSVal>();
1072
1073 // Handle all other values.
1074 BinaryOperator::Opcode Op = U->isIncrementOp() ? BO_Add : BO_Sub;
1075
1076 // If the UnaryOperator has non-location type, use its type to create the
1077 // constant value. If the UnaryOperator has location type, create the
1078 // constant with int type and pointer width.
1079 SVal RHS;
1080 SVal Result;
1081
1082 if (U->getType()->isAnyPointerType())
1083 RHS = svalBuilder.makeArrayIndex(1);
1084 else if (U->getType()->isIntegralOrEnumerationType())
1085 RHS = svalBuilder.makeIntVal(1, U->getType());
1086 else
1087 RHS = UnknownVal();
1088
1089 // The use of an operand of type bool with the ++ operators is deprecated
1090 // but valid until C++17. And if the operand of the ++ operator is of type
1091 // bool, it is set to true until C++17. Note that for '_Bool', it is also
1092 // set to true when it encounters ++ operator.
1093 if (U->getType()->isBooleanType() && U->isIncrementOp())
1094 Result = svalBuilder.makeTruthVal(true, U->getType());
1095 else
1096 Result = evalBinOp(state, Op, V2, RHS, U->getType());
1097
1098 // Conjure a new symbol if necessary to recover precision.
1099 if (Result.isUnknown()){
1100 DefinedOrUnknownSVal SymVal = svalBuilder.conjureSymbolVal(
1101 /*symbolTag=*/nullptr, getCFGElementRef(), SF,
1103 Result = SymVal;
1104
1105 // If the value is a location, ++/-- should always preserve
1106 // non-nullness. Check if the original value was non-null, and if so
1107 // propagate that constraint.
1108 if (Loc::isLocType(U->getType())) {
1109 DefinedOrUnknownSVal Constraint =
1110 svalBuilder.evalEQ(state, V2,svalBuilder.makeZeroVal(U->getType()));
1111
1112 if (!state->assume(Constraint, true)) {
1113 // It isn't feasible for the original value to be null.
1114 // Propagate this constraint.
1115 Constraint = svalBuilder.evalEQ(state, SymVal,
1116 svalBuilder.makeZeroVal(U->getType()));
1117
1118 state = state->assume(Constraint, false);
1119 assert(state);
1120 }
1121 }
1122 }
1123
1124 // Since the lvalue-to-rvalue conversion is explicit in the AST,
1125 // we bind an l-value if the operator is prefix and an lvalue (in C++).
1126 if (U->isGLValue())
1127 state = state->BindExpr(U, SF, loc);
1128 else
1129 state = state->BindExpr(U, SF, U->isPostfix() ? V2 : Result);
1130
1131 // Perform the store.
1132 Bldr.takeNodes(N);
1133 ExplodedNodeSet Dst3;
1134 evalStore(Dst3, U, Ex, N, state, loc, Result);
1135 Bldr.addNodes(Dst3);
1136 }
1137 Dst.insert(Dst2);
1138}
#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: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 isReferenceType() const
Definition TypeBase.h:8708
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
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: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:1774
EvalResult is a struct with detailed info about an evaluated expression.
Definition Expr.h:652