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