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