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 
19 using namespace clang;
20 using namespace ento;
21 using 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 
282 void 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 
638  getCheckerManager().runCheckersForPostStmt(Dst, B.getResults(), DS, *this);
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>()) {
676  ProgramPoint P = N->getLocation();
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();
694  BlockEdge BE = N->getLocation().castAs<BlockEdge>();
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();
799  if (PP.getAs<PreStmtPurgeDeadSymbols>() || PP.getAs<BlockEntrance>()) {
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);
851  Expr::EvalResult Result;
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 
877  QualType T = Ex->getTypeOfArgument();
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:3299
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
LineState State
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:2589
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:3892
static bool isAdditiveOp(Opcode Opc)
Definition: Expr.h:3977
static bool isAssignmentOp(Opcode Opc)
Definition: Expr.h:4027
static bool isCompoundAssignmentOp(Opcode Opc)
Definition: Expr.h:4032
Opcode getOpcode() const
Definition: Expr.h:3936
Expr * getRHS() const
Definition: Expr.h:3943
Expr * getLHS() const
Definition: Expr.h:3941
Represents a block literal declaration, which is like an unnamed FunctionDecl.
Definition: Decl.h:4497
capture_const_iterator capture_begin() const
Definition: Decl.h:4626
capture_const_iterator capture_end() const
Definition: Decl.h:4627
const CFGBlock * getDst() const
Definition: ProgramPoint.h:510
const CFGBlock * getSrc() const
Definition: ProgramPoint.h:506
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
Definition: Expr.h:6214
const BlockDecl * getBlockDecl() const
Definition: Expr.h:6226
This class is used for builtin types like 'int'.
Definition: Type.h:2989
bool isInteger() const
Definition: Type.h:3048
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:3535
CastKind getCastKind() const
Definition: Expr.h:3579
llvm::iterator_range< path_iterator > path()
Path through the class hierarchy taken by casts between base and derived classes (see implementation ...
Definition: Expr.h:3622
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:3465
const Expr * getInitializer() const
Definition: Expr.h:3488
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:1497
bool isSingleDecl() const
isSingleDecl - This method returns true if this DeclStmt refers to a single Decl.
Definition: Stmt.h:1510
decl_iterator decl_begin()
Definition: Stmt.h:1551
ExplicitCastExpr - An explicit cast written in the source code.
Definition: Expr.h:3782
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:3107
QualType getType() const
Definition: Expr.h:142
Describes an C or C++ initializer list.
Definition: Expr.h:4888
bool isTransparent() const
Is this a transparent initializer list (that is, an InitListExpr that is purely syntactic,...
Definition: Expr.cpp:2484
unsigned getNumInits() const
Definition: Expr.h:4918
const Expr * getInit(unsigned Init) const
Definition: Expr.h:4934
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:6766
OffsetOfExpr - [C99 7.17] - This represents an expression of the form offsetof(record-type,...
Definition: Expr.h:2517
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
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
T castAs() const
Convert to the specified ProgramPoint type, asserting that this ProgramPoint is of the desired type.
Definition: ProgramPoint.h:137
A (possibly-)qualified type.
Definition: Type.h:940
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:2145
bool isRValueReferenceType() const
Definition: Type.h:7644
bool isConstantSizeType() const
Return true if this is not a variable sized type, according to the rules of C99 6....
Definition: Type.cpp:2351
bool isArrayType() const
Definition: Type.h:7690
const T * castAs() const
Member-template castAs<specific type>.
Definition: Type.h:8227
bool isReferenceType() const
Definition: Type.h:7636
bool isVariableArrayType() const
Definition: Type.h:7702
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
Definition: Type.h:8054
bool isLValueReferenceType() const
Definition: Type.h:7640
bool isAnyComplexType() const
Definition: Type.h:7726
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
Definition: Type.cpp:2361
bool isVectorType() const
Definition: Type.h:7730
bool isFloatingType() const
Definition: Type.cpp:2248
const T * getAs() const
Member-template getAs<specific type>'.
Definition: Type.h:8160
bool isRecordType() const
Definition: Type.h:7718
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand.
Definition: Expr.h:2620
QualType getTypeOfArgument() const
Gets the argument type, or the type of the argument expression, whichever is appropriate.
Definition: Expr.h:2689
UnaryExprOrTypeTrait getKind() const
Definition: Expr.h:2652
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Definition: Expr.h:2235
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition: Decl.h:707
Represents a variable declaration or definition.
Definition: Decl.h:919
const Expr * getInit() const
Definition: Decl.h:1356
llvm::ImmutableList< SVal > prependSVal(SVal X, llvm::ImmutableList< SVal > L)
llvm::ImmutableList< SVal > getEmptySValList()
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
const LocationContext * getLocationContext() const
pred_iterator pred_begin()
ProgramPoint getLocation() const
getLocation - Returns the edge associated with the given node.
unsigned pred_size() const
BasicValueFactory & getBasicVals()
Definition: ExprEngine.h:419
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).
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
CheckerManager & getCheckerManager() const
Definition: ExprEngine.h:204
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).
SValBuilder & getSValBuilder()
Definition: ExprEngine.h:208
void VisitInitListExpr(const InitListExpr *E, ExplodedNode *Pred, ExplodedNodeSet &Dst)
void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Ex, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitUnaryExprOrTypeTraitExpr - Transfer function for sizeof.
ASTContext & getContext() const
getContext - Return the ASTContext associated with this analysis.
Definition: ExprEngine.h:196
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)
StoreManager & getStoreManager()
Definition: ExprEngine.h:412
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: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 * generateSink(const Stmt *S, ExplodedNode *Pred, ProgramStateRef St, const ProgramPointTag *tag=nullptr, ProgramPoint::Kind K=ProgramPoint::PostStmtKind)
Definition: CoreEngine.h:421
ExplodedNode * generateNode(const Stmt *S, ExplodedNode *Pred, ProgramStateRef St, const ProgramPointTag *tag=nullptr, ProgramPoint::Kind K=ProgramPoint::PostStmtKind)
Definition: CoreEngine.h:411
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
const FunctionProtoType * T
@ Other
Other implicit parameter.
EvalResult is a struct with detailed info about an evaluated expression.
Definition: Expr.h:642