1226586Sdim//=-- ExprEngineC.cpp - ExprEngine support for C expressions ----*- C++ -*-===//
2226586Sdim//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6226586Sdim//
7226586Sdim//===----------------------------------------------------------------------===//
8226586Sdim//
9226586Sdim//  This file defines ExprEngine's support for C expressions.
10226586Sdim//
11226586Sdim//===----------------------------------------------------------------------===//
12226586Sdim
13249423Sdim#include "clang/AST/ExprCXX.h"
14314564Sdim#include "clang/AST/DeclCXX.h"
15226586Sdim#include "clang/StaticAnalyzer/Core/CheckerManager.h"
16226586Sdim#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
17226586Sdim
18226586Sdimusing namespace clang;
19226586Sdimusing namespace ento;
20226586Sdimusing llvm::APSInt;
21226586Sdim
22341825Sdim/// Optionally conjure and return a symbol for offset when processing
23327952Sdim/// an expression \p Expression.
24327952Sdim/// If \p Other is a location, conjure a symbol for \p Symbol
25327952Sdim/// (offset) if it is unknown so that memory arithmetic always
26327952Sdim/// results in an ElementRegion.
27327952Sdim/// \p Count The number of times the current basic block was visited.
28327952Sdimstatic SVal conjureOffsetSymbolOnLocation(
29327952Sdim    SVal Symbol, SVal Other, Expr* Expression, SValBuilder &svalBuilder,
30327952Sdim    unsigned Count, const LocationContext *LCtx) {
31327952Sdim  QualType Ty = Expression->getType();
32327952Sdim  if (Other.getAs<Loc>() &&
33327952Sdim      Ty->isIntegralOrEnumerationType() &&
34327952Sdim      Symbol.isUnknown()) {
35327952Sdim    return svalBuilder.conjureSymbolVal(Expression, LCtx, Ty, Count);
36327952Sdim  }
37327952Sdim  return Symbol;
38327952Sdim}
39327952Sdim
40226586Sdimvoid ExprEngine::VisitBinaryOperator(const BinaryOperator* B,
41226586Sdim                                     ExplodedNode *Pred,
42226586Sdim                                     ExplodedNodeSet &Dst) {
43226586Sdim
44226586Sdim  Expr *LHS = B->getLHS()->IgnoreParens();
45226586Sdim  Expr *RHS = B->getRHS()->IgnoreParens();
46296417Sdim
47226586Sdim  // FIXME: Prechecks eventually go in ::Visit().
48226586Sdim  ExplodedNodeSet CheckedSet;
49226586Sdim  ExplodedNodeSet Tmp2;
50226586Sdim  getCheckerManager().runCheckersForPreStmt(CheckedSet, Pred, B, *this);
51296417Sdim
52288943Sdim  // With both the LHS and RHS evaluated, process the operation itself.
53226586Sdim  for (ExplodedNodeSet::iterator it=CheckedSet.begin(), ei=CheckedSet.end();
54226586Sdim         it != ei; ++it) {
55296417Sdim
56234353Sdim    ProgramStateRef state = (*it)->getState();
57234353Sdim    const LocationContext *LCtx = (*it)->getLocationContext();
58234353Sdim    SVal LeftV = state->getSVal(LHS, LCtx);
59234353Sdim    SVal RightV = state->getSVal(RHS, LCtx);
60296417Sdim
61226586Sdim    BinaryOperator::Opcode Op = B->getOpcode();
62296417Sdim
63226586Sdim    if (Op == BO_Assign) {
64226586Sdim      // EXPERIMENTAL: "Conjured" symbols.
65226586Sdim      // FIXME: Handle structs.
66234353Sdim      if (RightV.isUnknown()) {
67243830Sdim        unsigned Count = currBldrCtx->blockCount();
68276479Sdim        RightV = svalBuilder.conjureSymbolVal(nullptr, B->getRHS(), LCtx,
69276479Sdim                                              Count);
70226586Sdim      }
71226586Sdim      // Simulate the effects of a "store":  bind the value of the RHS
72226586Sdim      // to the L-Value represented by the LHS.
73239462Sdim      SVal ExprVal = B->isGLValue() ? LeftV : RightV;
74234353Sdim      evalStore(Tmp2, B, LHS, *it, state->BindExpr(B, LCtx, ExprVal),
75234353Sdim                LeftV, RightV);
76226586Sdim      continue;
77226586Sdim    }
78296417Sdim
79226586Sdim    if (!B->isAssignmentOp()) {
80243830Sdim      StmtNodeBuilder Bldr(*it, Tmp2, *currBldrCtx);
81239462Sdim
82239462Sdim      if (B->isAdditiveOp()) {
83239462Sdim        // TODO: This can be removed after we enable history tracking with
84239462Sdim        // SymSymExpr.
85243830Sdim        unsigned Count = currBldrCtx->blockCount();
86327952Sdim        RightV = conjureOffsetSymbolOnLocation(
87327952Sdim            RightV, LeftV, RHS, svalBuilder, Count, LCtx);
88327952Sdim        LeftV = conjureOffsetSymbolOnLocation(
89327952Sdim            LeftV, RightV, LHS, svalBuilder, Count, LCtx);
90239462Sdim      }
91239462Sdim
92276479Sdim      // Although we don't yet model pointers-to-members, we do need to make
93276479Sdim      // sure that the members of temporaries have a valid 'this' pointer for
94276479Sdim      // other checks.
95276479Sdim      if (B->getOpcode() == BO_PtrMemD)
96276479Sdim        state = createTemporaryRegionIfNeeded(state, LCtx, LHS);
97276479Sdim
98226586Sdim      // Process non-assignments except commas or short-circuited
99226586Sdim      // logical expressions (LAnd and LOr).
100296417Sdim      SVal Result = evalBinOp(state, Op, LeftV, RightV, B->getType());
101327952Sdim      if (!Result.isUnknown()) {
102327952Sdim        state = state->BindExpr(B, LCtx, Result);
103353358Sdim      } else {
104353358Sdim        // If we cannot evaluate the operation escape the operands.
105360784Sdim        state = escapeValues(state, LeftV, PSK_EscapeOther);
106360784Sdim        state = escapeValues(state, RightV, PSK_EscapeOther);
107296417Sdim      }
108226586Sdim
109234353Sdim      Bldr.generateNode(B, *it, state);
110226586Sdim      continue;
111226586Sdim    }
112296417Sdim
113226586Sdim    assert (B->isCompoundAssignmentOp());
114296417Sdim
115226586Sdim    switch (Op) {
116226586Sdim      default:
117226586Sdim        llvm_unreachable("Invalid opcode for compound assignment.");
118226586Sdim      case BO_MulAssign: Op = BO_Mul; break;
119226586Sdim      case BO_DivAssign: Op = BO_Div; break;
120226586Sdim      case BO_RemAssign: Op = BO_Rem; break;
121226586Sdim      case BO_AddAssign: Op = BO_Add; break;
122226586Sdim      case BO_SubAssign: Op = BO_Sub; break;
123226586Sdim      case BO_ShlAssign: Op = BO_Shl; break;
124226586Sdim      case BO_ShrAssign: Op = BO_Shr; break;
125226586Sdim      case BO_AndAssign: Op = BO_And; break;
126226586Sdim      case BO_XorAssign: Op = BO_Xor; break;
127226586Sdim      case BO_OrAssign:  Op = BO_Or;  break;
128226586Sdim    }
129296417Sdim
130226586Sdim    // Perform a load (the LHS).  This performs the checks for
131226586Sdim    // null dereferences, and so on.
132226586Sdim    ExplodedNodeSet Tmp;
133226586Sdim    SVal location = LeftV;
134234353Sdim    evalLoad(Tmp, B, LHS, *it, state, location);
135296417Sdim
136226586Sdim    for (ExplodedNodeSet::iterator I = Tmp.begin(), E = Tmp.end(); I != E;
137226586Sdim         ++I) {
138226586Sdim
139226586Sdim      state = (*I)->getState();
140234353Sdim      const LocationContext *LCtx = (*I)->getLocationContext();
141234353Sdim      SVal V = state->getSVal(LHS, LCtx);
142296417Sdim
143226586Sdim      // Get the computation type.
144226586Sdim      QualType CTy =
145226586Sdim        cast<CompoundAssignOperator>(B)->getComputationResultType();
146226586Sdim      CTy = getContext().getCanonicalType(CTy);
147296417Sdim
148226586Sdim      QualType CLHSTy =
149226586Sdim        cast<CompoundAssignOperator>(B)->getComputationLHSType();
150226586Sdim      CLHSTy = getContext().getCanonicalType(CLHSTy);
151296417Sdim
152226586Sdim      QualType LTy = getContext().getCanonicalType(LHS->getType());
153296417Sdim
154226586Sdim      // Promote LHS.
155226586Sdim      V = svalBuilder.evalCast(V, CLHSTy, LTy);
156296417Sdim
157226586Sdim      // Compute the result of the operation.
158226586Sdim      SVal Result = svalBuilder.evalCast(evalBinOp(state, Op, V, RightV, CTy),
159226586Sdim                                         B->getType(), CTy);
160296417Sdim
161226586Sdim      // EXPERIMENTAL: "Conjured" symbols.
162226586Sdim      // FIXME: Handle structs.
163296417Sdim
164226586Sdim      SVal LHSVal;
165296417Sdim
166234353Sdim      if (Result.isUnknown()) {
167226586Sdim        // The symbolic value is actually for the type of the left-hand side
168226586Sdim        // expression, not the computation type, as this is the value the
169226586Sdim        // LValue on the LHS will bind to.
170276479Sdim        LHSVal = svalBuilder.conjureSymbolVal(nullptr, B->getRHS(), LCtx, LTy,
171243830Sdim                                              currBldrCtx->blockCount());
172226586Sdim        // However, we need to convert the symbol to the computation type.
173226586Sdim        Result = svalBuilder.evalCast(LHSVal, CTy, LTy);
174226586Sdim      }
175226586Sdim      else {
176226586Sdim        // The left-hand side may bind to a different value then the
177226586Sdim        // computation type.
178226586Sdim        LHSVal = svalBuilder.evalCast(Result, LTy, CTy);
179226586Sdim      }
180296417Sdim
181296417Sdim      // In C++, assignment and compound assignment operators return an
182226586Sdim      // lvalue.
183239462Sdim      if (B->isGLValue())
184234353Sdim        state = state->BindExpr(B, LCtx, location);
185226586Sdim      else
186234353Sdim        state = state->BindExpr(B, LCtx, Result);
187296417Sdim
188226586Sdim      evalStore(Tmp2, B, LHS, *I, state, location, LHSVal);
189226586Sdim    }
190226586Sdim  }
191296417Sdim
192226586Sdim  // FIXME: postvisits eventually go in ::Visit()
193226586Sdim  getCheckerManager().runCheckersForPostStmt(Dst, Tmp2, B, *this);
194226586Sdim}
195226586Sdim
196226586Sdimvoid ExprEngine::VisitBlockExpr(const BlockExpr *BE, ExplodedNode *Pred,
197226586Sdim                                ExplodedNodeSet &Dst) {
198296417Sdim
199226586Sdim  CanQualType T = getContext().getCanonicalType(BE->getType());
200239462Sdim
201296417Sdim  const BlockDecl *BD = BE->getBlockDecl();
202239462Sdim  // Get the value of the block itself.
203296417Sdim  SVal V = svalBuilder.getBlockPointer(BD, T,
204261991Sdim                                       Pred->getLocationContext(),
205261991Sdim                                       currBldrCtx->blockCount());
206296417Sdim
207239462Sdim  ProgramStateRef State = Pred->getState();
208296417Sdim
209239462Sdim  // If we created a new MemRegion for the block, we should explicitly bind
210239462Sdim  // the captured variables.
211239462Sdim  if (const BlockDataRegion *BDR =
212239462Sdim      dyn_cast_or_null<BlockDataRegion>(V.getAsRegion())) {
213296417Sdim
214239462Sdim    BlockDataRegion::referenced_vars_iterator I = BDR->referenced_vars_begin(),
215239462Sdim                                              E = BDR->referenced_vars_end();
216296417Sdim
217296417Sdim    auto CI = BD->capture_begin();
218296417Sdim    auto CE = BD->capture_end();
219239462Sdim    for (; I != E; ++I) {
220296417Sdim      const VarRegion *capturedR = I.getCapturedRegion();
221296417Sdim      const VarRegion *originalR = I.getOriginalRegion();
222296417Sdim
223296417Sdim      // If the capture had a copy expression, use the result of evaluating
224296417Sdim      // that expression, otherwise use the original value.
225296417Sdim      // We rely on the invariant that the block declaration's capture variables
226296417Sdim      // are a prefix of the BlockDataRegion's referenced vars (which may include
227296417Sdim      // referenced globals, etc.) to enable fast lookup of the capture for a
228296417Sdim      // given referenced var.
229296417Sdim      const Expr *copyExpr = nullptr;
230296417Sdim      if (CI != CE) {
231296417Sdim        assert(CI->getVariable() == capturedR->getDecl());
232296417Sdim        copyExpr = CI->getCopyExpr();
233296417Sdim        CI++;
234296417Sdim      }
235296417Sdim
236239462Sdim      if (capturedR != originalR) {
237296417Sdim        SVal originalV;
238321369Sdim        const LocationContext *LCtx = Pred->getLocationContext();
239296417Sdim        if (copyExpr) {
240321369Sdim          originalV = State->getSVal(copyExpr, LCtx);
241296417Sdim        } else {
242296417Sdim          originalV = State->getSVal(loc::MemRegionVal(originalR));
243296417Sdim        }
244321369Sdim        State = State->bindLoc(loc::MemRegionVal(capturedR), originalV, LCtx);
245239462Sdim      }
246239462Sdim    }
247239462Sdim  }
248296417Sdim
249226586Sdim  ExplodedNodeSet Tmp;
250243830Sdim  StmtNodeBuilder Bldr(Pred, Tmp, *currBldrCtx);
251234353Sdim  Bldr.generateNode(BE, Pred,
252239462Sdim                    State->BindExpr(BE, Pred->getLocationContext(), V),
253276479Sdim                    nullptr, ProgramPoint::PostLValueKind);
254276479Sdim
255226586Sdim  // FIXME: Move all post/pre visits to ::Visit().
256226586Sdim  getCheckerManager().runCheckersForPostStmt(Dst, Tmp, BE, *this);
257226586Sdim}
258226586Sdim
259314564SdimProgramStateRef ExprEngine::handleLValueBitCast(
260314564Sdim    ProgramStateRef state, const Expr* Ex, const LocationContext* LCtx,
261314564Sdim    QualType T, QualType ExTy, const CastExpr* CastE, StmtNodeBuilder& Bldr,
262314564Sdim    ExplodedNode* Pred) {
263341825Sdim  if (T->isLValueReferenceType()) {
264341825Sdim    assert(!CastE->getType()->isLValueReferenceType());
265341825Sdim    ExTy = getContext().getLValueReferenceType(ExTy);
266341825Sdim  } else if (T->isRValueReferenceType()) {
267341825Sdim    assert(!CastE->getType()->isRValueReferenceType());
268341825Sdim    ExTy = getContext().getRValueReferenceType(ExTy);
269341825Sdim  }
270314564Sdim  // Delegate to SValBuilder to process.
271341825Sdim  SVal OrigV = state->getSVal(Ex, LCtx);
272341825Sdim  SVal V = svalBuilder.evalCast(OrigV, T, ExTy);
273314564Sdim  // Negate the result if we're treating the boolean as a signed i1
274314564Sdim  if (CastE->getCastKind() == CK_BooleanToSignedIntegral)
275314564Sdim    V = evalMinus(V);
276314564Sdim  state = state->BindExpr(CastE, LCtx, V);
277341825Sdim  if (V.isUnknown() && !OrigV.isUnknown()) {
278360784Sdim    state = escapeValues(state, OrigV, PSK_EscapeOther);
279341825Sdim  }
280314564Sdim  Bldr.generateNode(CastE, Pred, state);
281314564Sdim
282314564Sdim  return state;
283314564Sdim}
284314564Sdim
285314564SdimProgramStateRef ExprEngine::handleLVectorSplat(
286314564Sdim    ProgramStateRef state, const LocationContext* LCtx, const CastExpr* CastE,
287314564Sdim    StmtNodeBuilder &Bldr, ExplodedNode* Pred) {
288314564Sdim  // Recover some path sensitivity by conjuring a new value.
289314564Sdim  QualType resultType = CastE->getType();
290314564Sdim  if (CastE->isGLValue())
291314564Sdim    resultType = getContext().getPointerType(resultType);
292314564Sdim  SVal result = svalBuilder.conjureSymbolVal(nullptr, CastE, LCtx,
293314564Sdim                                             resultType,
294314564Sdim                                             currBldrCtx->blockCount());
295314564Sdim  state = state->BindExpr(CastE, LCtx, result);
296314564Sdim  Bldr.generateNode(CastE, Pred, state);
297314564Sdim
298314564Sdim  return state;
299314564Sdim}
300314564Sdim
301296417Sdimvoid ExprEngine::VisitCast(const CastExpr *CastE, const Expr *Ex,
302226586Sdim                           ExplodedNode *Pred, ExplodedNodeSet &Dst) {
303296417Sdim
304226586Sdim  ExplodedNodeSet dstPreStmt;
305226586Sdim  getCheckerManager().runCheckersForPreStmt(dstPreStmt, Pred, CastE, *this);
306296417Sdim
307234353Sdim  if (CastE->getCastKind() == CK_LValueToRValue) {
308226586Sdim    for (ExplodedNodeSet::iterator I = dstPreStmt.begin(), E = dstPreStmt.end();
309226586Sdim         I!=E; ++I) {
310226586Sdim      ExplodedNode *subExprNode = *I;
311234353Sdim      ProgramStateRef state = subExprNode->getState();
312234353Sdim      const LocationContext *LCtx = subExprNode->getLocationContext();
313234353Sdim      evalLoad(Dst, CastE, CastE, subExprNode, state, state->getSVal(Ex, LCtx));
314226586Sdim    }
315226586Sdim    return;
316226586Sdim  }
317296417Sdim
318296417Sdim  // All other casts.
319226586Sdim  QualType T = CastE->getType();
320226586Sdim  QualType ExTy = Ex->getType();
321296417Sdim
322226586Sdim  if (const ExplicitCastExpr *ExCast=dyn_cast_or_null<ExplicitCastExpr>(CastE))
323226586Sdim    T = ExCast->getTypeAsWritten();
324296417Sdim
325243830Sdim  StmtNodeBuilder Bldr(dstPreStmt, Dst, *currBldrCtx);
326226586Sdim  for (ExplodedNodeSet::iterator I = dstPreStmt.begin(), E = dstPreStmt.end();
327226586Sdim       I != E; ++I) {
328296417Sdim
329226586Sdim    Pred = *I;
330243830Sdim    ProgramStateRef state = Pred->getState();
331243830Sdim    const LocationContext *LCtx = Pred->getLocationContext();
332243830Sdim
333226586Sdim    switch (CastE->getCastKind()) {
334226586Sdim      case CK_LValueToRValue:
335226586Sdim        llvm_unreachable("LValueToRValue casts handled earlier.");
336226586Sdim      case CK_ToVoid:
337226586Sdim        continue;
338226586Sdim        // The analyzer doesn't do anything special with these casts,
339226586Sdim        // since it understands retain/release semantics already.
340226586Sdim      case CK_ARCProduceObject:
341226586Sdim      case CK_ARCConsumeObject:
342226586Sdim      case CK_ARCReclaimReturnedObject:
343226586Sdim      case CK_ARCExtendBlockObject: // Fall-through.
344234353Sdim      case CK_CopyAndAutoreleaseBlockObject:
345234353Sdim        // The analyser can ignore atomic casts for now, although some future
346234353Sdim        // checkers may want to make certain that you're not modifying the same
347234353Sdim        // value through atomic and nonatomic pointers.
348234353Sdim      case CK_AtomicToNonAtomic:
349234353Sdim      case CK_NonAtomicToAtomic:
350226586Sdim        // True no-ops.
351226586Sdim      case CK_NoOp:
352243830Sdim      case CK_ConstructorConversion:
353243830Sdim      case CK_UserDefinedConversion:
354243830Sdim      case CK_FunctionToPointerDecay:
355243830Sdim      case CK_BuiltinFnToFnPtr: {
356226586Sdim        // Copy the SVal of Ex to CastE.
357234353Sdim        ProgramStateRef state = Pred->getState();
358234353Sdim        const LocationContext *LCtx = Pred->getLocationContext();
359234353Sdim        SVal V = state->getSVal(Ex, LCtx);
360234353Sdim        state = state->BindExpr(CastE, LCtx, V);
361234353Sdim        Bldr.generateNode(CastE, Pred, state);
362226586Sdim        continue;
363226586Sdim      }
364243830Sdim      case CK_MemberPointerToBoolean:
365314564Sdim      case CK_PointerToBoolean: {
366314564Sdim        SVal V = state->getSVal(Ex, LCtx);
367314564Sdim        auto PTMSV = V.getAs<nonloc::PointerToMember>();
368314564Sdim        if (PTMSV)
369314564Sdim          V = svalBuilder.makeTruthVal(!PTMSV->isNullMemberPointer(), ExTy);
370314564Sdim        if (V.isUndef() || PTMSV) {
371314564Sdim          state = state->BindExpr(CastE, LCtx, V);
372314564Sdim          Bldr.generateNode(CastE, Pred, state);
373314564Sdim          continue;
374314564Sdim        }
375314564Sdim        // Explicitly proceed with default handler for this case cascade.
376314564Sdim        state =
377314564Sdim            handleLValueBitCast(state, Ex, LCtx, T, ExTy, CastE, Bldr, Pred);
378314564Sdim        continue;
379314564Sdim      }
380226586Sdim      case CK_Dependent:
381226586Sdim      case CK_ArrayToPointerDecay:
382226586Sdim      case CK_BitCast:
383353358Sdim      case CK_LValueToRValueBitCast:
384276479Sdim      case CK_AddressSpaceConversion:
385296417Sdim      case CK_BooleanToSignedIntegral:
386226586Sdim      case CK_IntegralToPointer:
387314564Sdim      case CK_PointerToIntegral: {
388314564Sdim        SVal V = state->getSVal(Ex, LCtx);
389314564Sdim        if (V.getAs<nonloc::PointerToMember>()) {
390314564Sdim          state = state->BindExpr(CastE, LCtx, UnknownVal());
391314564Sdim          Bldr.generateNode(CastE, Pred, state);
392314564Sdim          continue;
393314564Sdim        }
394314564Sdim        // Explicitly proceed with default handler for this case cascade.
395314564Sdim        state =
396314564Sdim            handleLValueBitCast(state, Ex, LCtx, T, ExTy, CastE, Bldr, Pred);
397314564Sdim        continue;
398314564Sdim      }
399226586Sdim      case CK_IntegralToBoolean:
400226586Sdim      case CK_IntegralToFloating:
401226586Sdim      case CK_FloatingToIntegral:
402226586Sdim      case CK_FloatingToBoolean:
403226586Sdim      case CK_FloatingCast:
404226586Sdim      case CK_FloatingRealToComplex:
405226586Sdim      case CK_FloatingComplexToReal:
406226586Sdim      case CK_FloatingComplexToBoolean:
407226586Sdim      case CK_FloatingComplexCast:
408226586Sdim      case CK_FloatingComplexToIntegralComplex:
409226586Sdim      case CK_IntegralRealToComplex:
410226586Sdim      case CK_IntegralComplexToReal:
411226586Sdim      case CK_IntegralComplexToBoolean:
412226586Sdim      case CK_IntegralComplexCast:
413226586Sdim      case CK_IntegralComplexToFloatingComplex:
414226586Sdim      case CK_CPointerToObjCPointerCast:
415226586Sdim      case CK_BlockPointerToObjCPointerCast:
416296417Sdim      case CK_AnyPointerToBlockPointerCast:
417296417Sdim      case CK_ObjCObjectLValueCast:
418344779Sdim      case CK_ZeroToOCLOpaqueType:
419314564Sdim      case CK_IntToOCLSampler:
420344779Sdim      case CK_LValueBitCast:
421344779Sdim      case CK_FixedPointCast:
422353358Sdim      case CK_FixedPointToBoolean:
423353358Sdim      case CK_FixedPointToIntegral:
424353358Sdim      case CK_IntegralToFixedPoint: {
425314564Sdim        state =
426314564Sdim            handleLValueBitCast(state, Ex, LCtx, T, ExTy, CastE, Bldr, Pred);
427226586Sdim        continue;
428226586Sdim      }
429296417Sdim      case CK_IntegralCast: {
430296417Sdim        // Delegate to SValBuilder to process.
431296417Sdim        SVal V = state->getSVal(Ex, LCtx);
432296417Sdim        V = svalBuilder.evalIntegralCast(state, V, T, ExTy);
433296417Sdim        state = state->BindExpr(CastE, LCtx, V);
434296417Sdim        Bldr.generateNode(CastE, Pred, state);
435296417Sdim        continue;
436296417Sdim      }
437226586Sdim      case CK_DerivedToBase:
438226586Sdim      case CK_UncheckedDerivedToBase: {
439226586Sdim        // For DerivedToBase cast, delegate to the store manager.
440234353Sdim        SVal val = state->getSVal(Ex, LCtx);
441239462Sdim        val = getStoreManager().evalDerivedToBase(val, CastE);
442234353Sdim        state = state->BindExpr(CastE, LCtx, val);
443234353Sdim        Bldr.generateNode(CastE, Pred, state);
444226586Sdim        continue;
445226586Sdim      }
446234353Sdim      // Handle C++ dyn_cast.
447234353Sdim      case CK_Dynamic: {
448234353Sdim        SVal val = state->getSVal(Ex, LCtx);
449234353Sdim
450234353Sdim        // Compute the type of the result.
451234353Sdim        QualType resultType = CastE->getType();
452239462Sdim        if (CastE->isGLValue())
453234353Sdim          resultType = getContext().getPointerType(resultType);
454234353Sdim
455234353Sdim        bool Failed = false;
456234353Sdim
457234353Sdim        // Check if the value being cast evaluates to 0.
458234353Sdim        if (val.isZeroConstant())
459234353Sdim          Failed = true;
460234353Sdim        // Else, evaluate the cast.
461234353Sdim        else
462314564Sdim          val = getStoreManager().attemptDownCast(val, T, Failed);
463234353Sdim
464234353Sdim        if (Failed) {
465234353Sdim          if (T->isReferenceType()) {
466234353Sdim            // A bad_cast exception is thrown if input value is a reference.
467234353Sdim            // Currently, we model this, by generating a sink.
468243830Sdim            Bldr.generateSink(CastE, Pred, state);
469234353Sdim            continue;
470234353Sdim          } else {
471234353Sdim            // If the cast fails on a pointer, bind to 0.
472234353Sdim            state = state->BindExpr(CastE, LCtx, svalBuilder.makeNull());
473234353Sdim          }
474234353Sdim        } else {
475234353Sdim          // If we don't know if the cast succeeded, conjure a new symbol.
476234353Sdim          if (val.isUnknown()) {
477243830Sdim            DefinedOrUnknownSVal NewSym =
478276479Sdim              svalBuilder.conjureSymbolVal(nullptr, CastE, LCtx, resultType,
479243830Sdim                                           currBldrCtx->blockCount());
480234353Sdim            state = state->BindExpr(CastE, LCtx, NewSym);
481296417Sdim          } else
482234353Sdim            // Else, bind to the derived region value.
483234353Sdim            state = state->BindExpr(CastE, LCtx, val);
484234353Sdim        }
485234353Sdim        Bldr.generateNode(CastE, Pred, state);
486234353Sdim        continue;
487234353Sdim      }
488314564Sdim      case CK_BaseToDerived: {
489314564Sdim        SVal val = state->getSVal(Ex, LCtx);
490314564Sdim        QualType resultType = CastE->getType();
491314564Sdim        if (CastE->isGLValue())
492314564Sdim          resultType = getContext().getPointerType(resultType);
493314564Sdim
494314564Sdim        bool Failed = false;
495314564Sdim
496314564Sdim        if (!val.isConstant()) {
497314564Sdim          val = getStoreManager().attemptDownCast(val, T, Failed);
498314564Sdim        }
499314564Sdim
500314564Sdim        // Failed to cast or the result is unknown, fall back to conservative.
501314564Sdim        if (Failed || val.isUnknown()) {
502314564Sdim          val =
503314564Sdim            svalBuilder.conjureSymbolVal(nullptr, CastE, LCtx, resultType,
504314564Sdim                                         currBldrCtx->blockCount());
505314564Sdim        }
506314564Sdim        state = state->BindExpr(CastE, LCtx, val);
507314564Sdim        Bldr.generateNode(CastE, Pred, state);
508314564Sdim        continue;
509314564Sdim      }
510353358Sdim      case CK_NullToPointer: {
511353358Sdim        SVal V = svalBuilder.makeNull();
512353358Sdim        state = state->BindExpr(CastE, LCtx, V);
513353358Sdim        Bldr.generateNode(CastE, Pred, state);
514353358Sdim        continue;
515353358Sdim      }
516243830Sdim      case CK_NullToMemberPointer: {
517314564Sdim        SVal V = svalBuilder.getMemberPointer(nullptr);
518243830Sdim        state = state->BindExpr(CastE, LCtx, V);
519243830Sdim        Bldr.generateNode(CastE, Pred, state);
520243830Sdim        continue;
521243830Sdim      }
522314564Sdim      case CK_DerivedToBaseMemberPointer:
523314564Sdim      case CK_BaseToDerivedMemberPointer:
524314564Sdim      case CK_ReinterpretMemberPointer: {
525314564Sdim        SVal V = state->getSVal(Ex, LCtx);
526314564Sdim        if (auto PTMSV = V.getAs<nonloc::PointerToMember>()) {
527314564Sdim          SVal CastedPTMSV = svalBuilder.makePointerToMember(
528314564Sdim              getBasicVals().accumCXXBase(
529314564Sdim                  llvm::make_range<CastExpr::path_const_iterator>(
530314564Sdim                      CastE->path_begin(), CastE->path_end()), *PTMSV));
531314564Sdim          state = state->BindExpr(CastE, LCtx, CastedPTMSV);
532314564Sdim          Bldr.generateNode(CastE, Pred, state);
533314564Sdim          continue;
534314564Sdim        }
535314564Sdim        // Explicitly proceed with default handler for this case cascade.
536314564Sdim        state = handleLVectorSplat(state, LCtx, CastE, Bldr, Pred);
537314564Sdim        continue;
538314564Sdim      }
539234353Sdim      // Various C++ casts that are not handled yet.
540226586Sdim      case CK_ToUnion:
541261991Sdim      case CK_VectorSplat: {
542314564Sdim        state = handleLVectorSplat(state, LCtx, CastE, Bldr, Pred);
543226586Sdim        continue;
544226586Sdim      }
545226586Sdim    }
546226586Sdim  }
547226586Sdim}
548226586Sdim
549226586Sdimvoid ExprEngine::VisitCompoundLiteralExpr(const CompoundLiteralExpr *CL,
550226586Sdim                                          ExplodedNode *Pred,
551226586Sdim                                          ExplodedNodeSet &Dst) {
552243830Sdim  StmtNodeBuilder B(Pred, Dst, *currBldrCtx);
553234353Sdim
554251662Sdim  ProgramStateRef State = Pred->getState();
555251662Sdim  const LocationContext *LCtx = Pred->getLocationContext();
556251662Sdim
557251662Sdim  const Expr *Init = CL->getInitializer();
558251662Sdim  SVal V = State->getSVal(CL->getInitializer(), LCtx);
559296417Sdim
560327952Sdim  if (isa<CXXConstructExpr>(Init) || isa<CXXStdInitializerListExpr>(Init)) {
561251662Sdim    // No work needed. Just pass the value up to this expression.
562251662Sdim  } else {
563251662Sdim    assert(isa<InitListExpr>(Init));
564251662Sdim    Loc CLLoc = State->getLValue(CL, LCtx);
565321369Sdim    State = State->bindLoc(CLLoc, V, LCtx);
566239462Sdim
567314564Sdim    if (CL->isGLValue())
568251662Sdim      V = CLLoc;
569251662Sdim  }
570251662Sdim
571251662Sdim  B.generateNode(CL, Pred, State->BindExpr(CL, LCtx, V));
572226586Sdim}
573226586Sdim
574226586Sdimvoid ExprEngine::VisitDeclStmt(const DeclStmt *DS, ExplodedNode *Pred,
575226586Sdim                               ExplodedNodeSet &Dst) {
576226586Sdim  // Assumption: The CFG has one DeclStmt per Decl.
577249423Sdim  const VarDecl *VD = dyn_cast_or_null<VarDecl>(*DS->decl_begin());
578249423Sdim
579249423Sdim  if (!VD) {
580234353Sdim    //TODO:AZ: remove explicit insertion after refactoring is done.
581234353Sdim    Dst.insert(Pred);
582226586Sdim    return;
583234353Sdim  }
584296417Sdim
585226586Sdim  // FIXME: all pre/post visits should eventually be handled by ::Visit().
586226586Sdim  ExplodedNodeSet dstPreVisit;
587226586Sdim  getCheckerManager().runCheckersForPreStmt(dstPreVisit, Pred, DS, *this);
588296417Sdim
589261991Sdim  ExplodedNodeSet dstEvaluated;
590261991Sdim  StmtNodeBuilder B(dstPreVisit, dstEvaluated, *currBldrCtx);
591226586Sdim  for (ExplodedNodeSet::iterator I = dstPreVisit.begin(), E = dstPreVisit.end();
592226586Sdim       I!=E; ++I) {
593226586Sdim    ExplodedNode *N = *I;
594234353Sdim    ProgramStateRef state = N->getState();
595249423Sdim    const LocationContext *LC = N->getLocationContext();
596249423Sdim
597226586Sdim    // Decls without InitExpr are not initialized explicitly.
598226586Sdim    if (const Expr *InitEx = VD->getInit()) {
599249423Sdim
600249423Sdim      // Note in the state that the initialization has occurred.
601249423Sdim      ExplodedNode *UpdatedN = N;
602239462Sdim      SVal InitVal = state->getSVal(InitEx, LC);
603234353Sdim
604296417Sdim      assert(DS->isSingleDecl());
605341825Sdim      if (getObjectUnderConstruction(state, DS, LC)) {
606341825Sdim        state = finishObjectConstruction(state, DS, LC);
607239462Sdim        // We constructed the object directly in the variable.
608239462Sdim        // No need to bind anything.
609249423Sdim        B.generateNode(DS, UpdatedN, state);
610239462Sdim      } else {
611239462Sdim        // Recover some path-sensitivity if a scalar value evaluated to
612239462Sdim        // UnknownVal.
613239462Sdim        if (InitVal.isUnknown()) {
614239462Sdim          QualType Ty = InitEx->getType();
615239462Sdim          if (InitEx->isGLValue()) {
616239462Sdim            Ty = getContext().getPointerType(Ty);
617239462Sdim          }
618239462Sdim
619276479Sdim          InitVal = svalBuilder.conjureSymbolVal(nullptr, InitEx, LC, Ty,
620243830Sdim                                                 currBldrCtx->blockCount());
621239462Sdim        }
622249423Sdim
623249423Sdim
624249423Sdim        B.takeNodes(UpdatedN);
625239462Sdim        ExplodedNodeSet Dst2;
626249423Sdim        evalBind(Dst2, DS, UpdatedN, state->getLValue(VD, LC), InitVal, true);
627239462Sdim        B.addNodes(Dst2);
628226586Sdim      }
629226586Sdim    }
630226586Sdim    else {
631243830Sdim      B.generateNode(DS, N, state);
632226586Sdim    }
633226586Sdim  }
634261991Sdim
635261991Sdim  getCheckerManager().runCheckersForPostStmt(Dst, B.getResults(), DS, *this);
636226586Sdim}
637226586Sdim
638226586Sdimvoid ExprEngine::VisitLogicalExpr(const BinaryOperator* B, ExplodedNode *Pred,
639226586Sdim                                  ExplodedNodeSet &Dst) {
640353358Sdim  // This method acts upon CFG elements for logical operators && and ||
641353358Sdim  // and attaches the value (true or false) to them as expressions.
642353358Sdim  // It doesn't produce any state splits.
643353358Sdim  // If we made it that far, we're past the point when we modeled the short
644353358Sdim  // circuit. It means that we should have precise knowledge about whether
645353358Sdim  // we've short-circuited. If we did, we already know the value we need to
646353358Sdim  // bind. If we didn't, the value of the RHS (casted to the boolean type)
647353358Sdim  // is the answer.
648353358Sdim  // Currently this method tries to figure out whether we've short-circuited
649353358Sdim  // by looking at the ExplodedGraph. This method is imperfect because there
650353358Sdim  // could inevitably have been merges that would have resulted in multiple
651353358Sdim  // potential path traversal histories. We bail out when we fail.
652353358Sdim  // Due to this ambiguity, a more reliable solution would have been to
653353358Sdim  // track the short circuit operation history path-sensitively until
654353358Sdim  // we evaluate the respective logical operator.
655226586Sdim  assert(B->getOpcode() == BO_LAnd ||
656226586Sdim         B->getOpcode() == BO_LOr);
657234353Sdim
658243830Sdim  StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx);
659234353Sdim  ProgramStateRef state = Pred->getState();
660239462Sdim
661327952Sdim  if (B->getType()->isVectorType()) {
662327952Sdim    // FIXME: We do not model vector arithmetic yet. When adding support for
663327952Sdim    // that, note that the CFG-based reasoning below does not apply, because
664327952Sdim    // logical operators on vectors are not short-circuit. Currently they are
665327952Sdim    // modeled as short-circuit in Clang CFG but this is incorrect.
666327952Sdim    // Do not set the value for the expression. It'd be UnknownVal by default.
667327952Sdim    Bldr.generateNode(B, Pred, state);
668327952Sdim    return;
669327952Sdim  }
670327952Sdim
671239462Sdim  ExplodedNode *N = Pred;
672249423Sdim  while (!N->getLocation().getAs<BlockEntrance>()) {
673239462Sdim    ProgramPoint P = N->getLocation();
674249423Sdim    assert(P.getAs<PreStmt>()|| P.getAs<PreStmtPurgeDeadSymbols>());
675239462Sdim    (void) P;
676353358Sdim    if (N->pred_size() != 1) {
677353358Sdim      // We failed to track back where we came from.
678353358Sdim      Bldr.generateNode(B, Pred, state);
679353358Sdim      return;
680353358Sdim    }
681239462Sdim    N = *N->pred_begin();
682226586Sdim  }
683353358Sdim
684353358Sdim  if (N->pred_size() != 1) {
685353358Sdim    // We failed to track back where we came from.
686353358Sdim    Bldr.generateNode(B, Pred, state);
687353358Sdim    return;
688353358Sdim  }
689353358Sdim
690239462Sdim  N = *N->pred_begin();
691249423Sdim  BlockEdge BE = N->getLocation().castAs<BlockEdge>();
692239462Sdim  SVal X;
693239462Sdim
694239462Sdim  // Determine the value of the expression by introspecting how we
695239462Sdim  // got this location in the CFG.  This requires looking at the previous
696239462Sdim  // block we were in and what kind of control-flow transfer was involved.
697239462Sdim  const CFGBlock *SrcBlock = BE.getSrc();
698239462Sdim  // The only terminator (if there is one) that makes sense is a logical op.
699239462Sdim  CFGTerminator T = SrcBlock->getTerminator();
700239462Sdim  if (const BinaryOperator *Term = cast_or_null<BinaryOperator>(T.getStmt())) {
701239462Sdim    (void) Term;
702239462Sdim    assert(Term->isLogicalOp());
703239462Sdim    assert(SrcBlock->succ_size() == 2);
704239462Sdim    // Did we take the true or false branch?
705239462Sdim    unsigned constant = (*SrcBlock->succ_begin() == BE.getDst()) ? 1 : 0;
706239462Sdim    X = svalBuilder.makeIntVal(constant, B->getType());
707239462Sdim  }
708226586Sdim  else {
709239462Sdim    // If there is no terminator, by construction the last statement
710239462Sdim    // in SrcBlock is the value of the enclosing expression.
711243830Sdim    // However, we still need to constrain that value to be 0 or 1.
712239462Sdim    assert(!SrcBlock->empty());
713249423Sdim    CFGStmt Elem = SrcBlock->rbegin()->castAs<CFGStmt>();
714243830Sdim    const Expr *RHS = cast<Expr>(Elem.getStmt());
715243830Sdim    SVal RHSVal = N->getState()->getSVal(RHS, Pred->getLocationContext());
716243830Sdim
717249423Sdim    if (RHSVal.isUndef()) {
718249423Sdim      X = RHSVal;
719249423Sdim    } else {
720314564Sdim      // We evaluate "RHSVal != 0" expression which result in 0 if the value is
721314564Sdim      // known to be false, 1 if the value is known to be true and a new symbol
722314564Sdim      // when the assumption is unknown.
723314564Sdim      nonloc::ConcreteInt Zero(getBasicVals().getValue(0, B->getType()));
724341825Sdim      X = evalBinOp(N->getState(), BO_NE,
725314564Sdim                    svalBuilder.evalCast(RHSVal, B->getType(), RHS->getType()),
726314564Sdim                    Zero, B->getType());
727243830Sdim    }
728226586Sdim  }
729239462Sdim  Bldr.generateNode(B, Pred, state->BindExpr(B, Pred->getLocationContext(), X));
730226586Sdim}
731226586Sdim
732226586Sdimvoid ExprEngine::VisitInitListExpr(const InitListExpr *IE,
733226586Sdim                                   ExplodedNode *Pred,
734226586Sdim                                   ExplodedNodeSet &Dst) {
735243830Sdim  StmtNodeBuilder B(Pred, Dst, *currBldrCtx);
736226586Sdim
737234353Sdim  ProgramStateRef state = Pred->getState();
738234353Sdim  const LocationContext *LCtx = Pred->getLocationContext();
739226586Sdim  QualType T = getContext().getCanonicalType(IE->getType());
740226586Sdim  unsigned NumInitElements = IE->getNumInits();
741261991Sdim
742353358Sdim  if (!IE->isGLValue() && !IE->isTransparent() &&
743261991Sdim      (T->isArrayType() || T->isRecordType() || T->isVectorType() ||
744261991Sdim       T->isAnyComplexType())) {
745226586Sdim    llvm::ImmutableList<SVal> vals = getBasicVals().getEmptySValList();
746296417Sdim
747226586Sdim    // Handle base case where the initializer has no elements.
748226586Sdim    // e.g: static int* myArray[] = {};
749226586Sdim    if (NumInitElements == 0) {
750226586Sdim      SVal V = svalBuilder.makeCompoundVal(T, vals);
751234353Sdim      B.generateNode(IE, Pred, state->BindExpr(IE, LCtx, V));
752226586Sdim      return;
753226586Sdim    }
754296417Sdim
755226586Sdim    for (InitListExpr::const_reverse_iterator it = IE->rbegin(),
756226586Sdim         ei = IE->rend(); it != ei; ++it) {
757249423Sdim      SVal V = state->getSVal(cast<Expr>(*it), LCtx);
758314564Sdim      vals = getBasicVals().prependSVal(V, vals);
759226586Sdim    }
760296417Sdim
761234353Sdim    B.generateNode(IE, Pred,
762234353Sdim                   state->BindExpr(IE, LCtx,
763234353Sdim                                   svalBuilder.makeCompoundVal(T, vals)));
764226586Sdim    return;
765226586Sdim  }
766239462Sdim
767261991Sdim  // Handle scalars: int{5} and int{} and GLvalues.
768261991Sdim  // Note, if the InitListExpr is a GLvalue, it means that there is an address
769261991Sdim  // representing it, so it must have a single init element.
770239462Sdim  assert(NumInitElements <= 1);
771239462Sdim
772239462Sdim  SVal V;
773239462Sdim  if (NumInitElements == 0)
774239462Sdim    V = getSValBuilder().makeZeroVal(T);
775239462Sdim  else
776239462Sdim    V = state->getSVal(IE->getInit(0), LCtx);
777239462Sdim
778239462Sdim  B.generateNode(IE, Pred, state->BindExpr(IE, LCtx, V));
779226586Sdim}
780226586Sdim
781226586Sdimvoid ExprEngine::VisitGuardedExpr(const Expr *Ex,
782296417Sdim                                  const Expr *L,
783226586Sdim                                  const Expr *R,
784226586Sdim                                  ExplodedNode *Pred,
785226586Sdim                                  ExplodedNodeSet &Dst) {
786251662Sdim  assert(L && R);
787251662Sdim
788243830Sdim  StmtNodeBuilder B(Pred, Dst, *currBldrCtx);
789234353Sdim  ProgramStateRef state = Pred->getState();
790234353Sdim  const LocationContext *LCtx = Pred->getLocationContext();
791276479Sdim  const CFGBlock *SrcBlock = nullptr;
792239462Sdim
793251662Sdim  // Find the predecessor block.
794251662Sdim  ProgramStateRef SrcState = state;
795239462Sdim  for (const ExplodedNode *N = Pred ; N ; N = *N->pred_begin()) {
796239462Sdim    ProgramPoint PP = N->getLocation();
797249423Sdim    if (PP.getAs<PreStmtPurgeDeadSymbols>() || PP.getAs<BlockEntrance>()) {
798341825Sdim      // If the state N has multiple predecessors P, it means that successors
799341825Sdim      // of P are all equivalent.
800341825Sdim      // In turn, that means that all nodes at P are equivalent in terms
801341825Sdim      // of observable behavior at N, and we can follow any of them.
802341825Sdim      // FIXME: a more robust solution which does not walk up the tree.
803239462Sdim      continue;
804239462Sdim    }
805249423Sdim    SrcBlock = PP.castAs<BlockEdge>().getSrc();
806251662Sdim    SrcState = N->getState();
807239462Sdim    break;
808239462Sdim  }
809239462Sdim
810249423Sdim  assert(SrcBlock && "missing function entry");
811249423Sdim
812239462Sdim  // Find the last expression in the predecessor block.  That is the
813239462Sdim  // expression that is used for the value of the ternary expression.
814239462Sdim  bool hasValue = false;
815239462Sdim  SVal V;
816239462Sdim
817296417Sdim  for (CFGElement CE : llvm::reverse(*SrcBlock)) {
818249423Sdim    if (Optional<CFGStmt> CS = CE.getAs<CFGStmt>()) {
819239462Sdim      const Expr *ValEx = cast<Expr>(CS->getStmt());
820251662Sdim      ValEx = ValEx->IgnoreParens();
821251662Sdim
822251662Sdim      // For GNU extension '?:' operator, the left hand side will be an
823251662Sdim      // OpaqueValueExpr, so get the underlying expression.
824251662Sdim      if (const OpaqueValueExpr *OpaqueEx = dyn_cast<OpaqueValueExpr>(L))
825251662Sdim        L = OpaqueEx->getSourceExpr();
826251662Sdim
827251662Sdim      // If the last expression in the predecessor block matches true or false
828251662Sdim      // subexpression, get its the value.
829251662Sdim      if (ValEx == L->IgnoreParens() || ValEx == R->IgnoreParens()) {
830251662Sdim        hasValue = true;
831251662Sdim        V = SrcState->getSVal(ValEx, LCtx);
832251662Sdim      }
833239462Sdim      break;
834239462Sdim    }
835239462Sdim  }
836239462Sdim
837251662Sdim  if (!hasValue)
838276479Sdim    V = svalBuilder.conjureSymbolVal(nullptr, Ex, LCtx,
839276479Sdim                                     currBldrCtx->blockCount());
840239462Sdim
841239462Sdim  // Generate a new node with the binding from the appropriate path.
842239462Sdim  B.generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V, true));
843226586Sdim}
844226586Sdim
845226586Sdimvoid ExprEngine::
846296417SdimVisitOffsetOfExpr(const OffsetOfExpr *OOE,
847226586Sdim                  ExplodedNode *Pred, ExplodedNodeSet &Dst) {
848243830Sdim  StmtNodeBuilder B(Pred, Dst, *currBldrCtx);
849344779Sdim  Expr::EvalResult Result;
850344779Sdim  if (OOE->EvaluateAsInt(Result, getContext())) {
851344779Sdim    APSInt IV = Result.Val.getInt();
852226586Sdim    assert(IV.getBitWidth() == getContext().getTypeSize(OOE->getType()));
853360784Sdim    assert(OOE->getType()->castAs<BuiltinType>()->isInteger());
854251662Sdim    assert(IV.isSigned() == OOE->getType()->isSignedIntegerType());
855226586Sdim    SVal X = svalBuilder.makeIntVal(IV);
856234353Sdim    B.generateNode(OOE, Pred,
857234353Sdim                   Pred->getState()->BindExpr(OOE, Pred->getLocationContext(),
858234353Sdim                                              X));
859226586Sdim  }
860226586Sdim  // FIXME: Handle the case where __builtin_offsetof is not a constant.
861226586Sdim}
862226586Sdim
863226586Sdim
864226586Sdimvoid ExprEngine::
865226586SdimVisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Ex,
866226586Sdim                              ExplodedNode *Pred,
867226586Sdim                              ExplodedNodeSet &Dst) {
868276479Sdim  // FIXME: Prechecks eventually go in ::Visit().
869276479Sdim  ExplodedNodeSet CheckedSet;
870276479Sdim  getCheckerManager().runCheckersForPreStmt(CheckedSet, Pred, Ex, *this);
871226586Sdim
872276479Sdim  ExplodedNodeSet EvalSet;
873276479Sdim  StmtNodeBuilder Bldr(CheckedSet, EvalSet, *currBldrCtx);
874276479Sdim
875226586Sdim  QualType T = Ex->getTypeOfArgument();
876276479Sdim
877276479Sdim  for (ExplodedNodeSet::iterator I = CheckedSet.begin(), E = CheckedSet.end();
878276479Sdim       I != E; ++I) {
879276479Sdim    if (Ex->getKind() == UETT_SizeOf) {
880276479Sdim      if (!T->isIncompleteType() && !T->isConstantSizeType()) {
881276479Sdim        assert(T->isVariableArrayType() && "Unknown non-constant-sized type.");
882296417Sdim
883276479Sdim        // FIXME: Add support for VLA type arguments and VLA expressions.
884276479Sdim        // When that happens, we should probably refactor VLASizeChecker's code.
885276479Sdim        continue;
886276479Sdim      } else if (T->getAs<ObjCObjectType>()) {
887276479Sdim        // Some code tries to take the sizeof an ObjCObjectType, relying that
888276479Sdim        // the compiler has laid out its representation.  Just report Unknown
889276479Sdim        // for these.
890276479Sdim        continue;
891276479Sdim      }
892226586Sdim    }
893296417Sdim
894276479Sdim    APSInt Value = Ex->EvaluateKnownConstInt(getContext());
895276479Sdim    CharUnits amt = CharUnits::fromQuantity(Value.getZExtValue());
896296417Sdim
897276479Sdim    ProgramStateRef state = (*I)->getState();
898276479Sdim    state = state->BindExpr(Ex, (*I)->getLocationContext(),
899276479Sdim                            svalBuilder.makeIntVal(amt.getQuantity(),
900276479Sdim                                                   Ex->getType()));
901276479Sdim    Bldr.generateNode(Ex, *I, state);
902226586Sdim  }
903276479Sdim
904276479Sdim  getCheckerManager().runCheckersForPostStmt(Dst, EvalSet, Ex, *this);
905226586Sdim}
906226586Sdim
907314564Sdimvoid ExprEngine::handleUOExtension(ExplodedNodeSet::iterator I,
908314564Sdim                                   const UnaryOperator *U,
909314564Sdim                                   StmtNodeBuilder &Bldr) {
910314564Sdim  // FIXME: We can probably just have some magic in Environment::getSVal()
911314564Sdim  // that propagates values, instead of creating a new node here.
912314564Sdim  //
913314564Sdim  // Unary "+" is a no-op, similar to a parentheses.  We still have places
914314564Sdim  // where it may be a block-level expression, so we need to
915314564Sdim  // generate an extra node that just propagates the value of the
916314564Sdim  // subexpression.
917314564Sdim  const Expr *Ex = U->getSubExpr()->IgnoreParens();
918314564Sdim  ProgramStateRef state = (*I)->getState();
919314564Sdim  const LocationContext *LCtx = (*I)->getLocationContext();
920314564Sdim  Bldr.generateNode(U, *I, state->BindExpr(U, LCtx,
921314564Sdim                                           state->getSVal(Ex, LCtx)));
922314564Sdim}
923314564Sdim
924314564Sdimvoid ExprEngine::VisitUnaryOperator(const UnaryOperator* U, ExplodedNode *Pred,
925234353Sdim                                    ExplodedNodeSet &Dst) {
926261991Sdim  // FIXME: Prechecks eventually go in ::Visit().
927261991Sdim  ExplodedNodeSet CheckedSet;
928261991Sdim  getCheckerManager().runCheckersForPreStmt(CheckedSet, Pred, U, *this);
929261991Sdim
930261991Sdim  ExplodedNodeSet EvalSet;
931261991Sdim  StmtNodeBuilder Bldr(CheckedSet, EvalSet, *currBldrCtx);
932261991Sdim
933261991Sdim  for (ExplodedNodeSet::iterator I = CheckedSet.begin(), E = CheckedSet.end();
934261991Sdim       I != E; ++I) {
935261991Sdim    switch (U->getOpcode()) {
936234353Sdim    default: {
937261991Sdim      Bldr.takeNodes(*I);
938234353Sdim      ExplodedNodeSet Tmp;
939261991Sdim      VisitIncrementDecrementOperator(U, *I, Tmp);
940234353Sdim      Bldr.addNodes(Tmp);
941261991Sdim      break;
942234353Sdim    }
943226586Sdim    case UO_Real: {
944226586Sdim      const Expr *Ex = U->getSubExpr()->IgnoreParens();
945296417Sdim
946234353Sdim      // FIXME: We don't have complex SValues yet.
947234353Sdim      if (Ex->getType()->isAnyComplexType()) {
948234353Sdim        // Just report "Unknown."
949234353Sdim        break;
950234353Sdim      }
951296417Sdim
952234353Sdim      // For all other types, UO_Real is an identity operation.
953234353Sdim      assert (U->getType() == Ex->getType());
954261991Sdim      ProgramStateRef state = (*I)->getState();
955261991Sdim      const LocationContext *LCtx = (*I)->getLocationContext();
956261991Sdim      Bldr.generateNode(U, *I, state->BindExpr(U, LCtx,
957261991Sdim                                               state->getSVal(Ex, LCtx)));
958234353Sdim      break;
959226586Sdim    }
960296417Sdim
961296417Sdim    case UO_Imag: {
962226586Sdim      const Expr *Ex = U->getSubExpr()->IgnoreParens();
963234353Sdim      // FIXME: We don't have complex SValues yet.
964234353Sdim      if (Ex->getType()->isAnyComplexType()) {
965234353Sdim        // Just report "Unknown."
966234353Sdim        break;
967226586Sdim      }
968234353Sdim      // For all other types, UO_Imag returns 0.
969261991Sdim      ProgramStateRef state = (*I)->getState();
970261991Sdim      const LocationContext *LCtx = (*I)->getLocationContext();
971234353Sdim      SVal X = svalBuilder.makeZeroVal(Ex->getType());
972261991Sdim      Bldr.generateNode(U, *I, state->BindExpr(U, LCtx, X));
973234353Sdim      break;
974226586Sdim    }
975296417Sdim
976314564Sdim    case UO_AddrOf: {
977314564Sdim      // Process pointer-to-member address operation.
978314564Sdim      const Expr *Ex = U->getSubExpr()->IgnoreParens();
979314564Sdim      if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Ex)) {
980314564Sdim        const ValueDecl *VD = DRE->getDecl();
981314564Sdim
982314564Sdim        if (isa<CXXMethodDecl>(VD) || isa<FieldDecl>(VD)) {
983314564Sdim          ProgramStateRef State = (*I)->getState();
984314564Sdim          const LocationContext *LCtx = (*I)->getLocationContext();
985314564Sdim          SVal SV = svalBuilder.getMemberPointer(cast<DeclaratorDecl>(VD));
986314564Sdim          Bldr.generateNode(U, *I, State->BindExpr(U, LCtx, SV));
987314564Sdim          break;
988314564Sdim        }
989314564Sdim      }
990314564Sdim      // Explicitly proceed with default handler for this case cascade.
991314564Sdim      handleUOExtension(I, U, Bldr);
992314564Sdim      break;
993314564Sdim    }
994226586Sdim    case UO_Plus:
995239462Sdim      assert(!U->isGLValue());
996344779Sdim      LLVM_FALLTHROUGH;
997226586Sdim    case UO_Deref:
998226586Sdim    case UO_Extension: {
999314564Sdim      handleUOExtension(I, U, Bldr);
1000234353Sdim      break;
1001226586Sdim    }
1002296417Sdim
1003226586Sdim    case UO_LNot:
1004226586Sdim    case UO_Minus:
1005226586Sdim    case UO_Not: {
1006239462Sdim      assert (!U->isGLValue());
1007226586Sdim      const Expr *Ex = U->getSubExpr()->IgnoreParens();
1008261991Sdim      ProgramStateRef state = (*I)->getState();
1009261991Sdim      const LocationContext *LCtx = (*I)->getLocationContext();
1010296417Sdim
1011234353Sdim      // Get the value of the subexpression.
1012234353Sdim      SVal V = state->getSVal(Ex, LCtx);
1013296417Sdim
1014234353Sdim      if (V.isUnknownOrUndef()) {
1015261991Sdim        Bldr.generateNode(U, *I, state->BindExpr(U, LCtx, V));
1016234353Sdim        break;
1017234353Sdim      }
1018296417Sdim
1019234353Sdim      switch (U->getOpcode()) {
1020234353Sdim        default:
1021234353Sdim          llvm_unreachable("Invalid Opcode.");
1022234353Sdim        case UO_Not:
1023234353Sdim          // FIXME: Do we need to handle promotions?
1024249423Sdim          state = state->BindExpr(U, LCtx, evalComplement(V.castAs<NonLoc>()));
1025234353Sdim          break;
1026234353Sdim        case UO_Minus:
1027234353Sdim          // FIXME: Do we need to handle promotions?
1028249423Sdim          state = state->BindExpr(U, LCtx, evalMinus(V.castAs<NonLoc>()));
1029234353Sdim          break;
1030234353Sdim        case UO_LNot:
1031234353Sdim          // C99 6.5.3.3: "The expression !E is equivalent to (0==E)."
1032234353Sdim          //
1033234353Sdim          //  Note: technically we do "E == 0", but this is the same in the
1034234353Sdim          //    transfer functions as "0 == E".
1035296417Sdim          SVal Result;
1036249423Sdim          if (Optional<Loc> LV = V.getAs<Loc>()) {
1037321369Sdim            Loc X = svalBuilder.makeNullWithType(Ex->getType());
1038249423Sdim            Result = evalBinOp(state, BO_EQ, *LV, X, U->getType());
1039321369Sdim          } else if (Ex->getType()->isFloatingType()) {
1040249423Sdim            // FIXME: handle floating point types.
1041249423Sdim            Result = UnknownVal();
1042249423Sdim          } else {
1043234353Sdim            nonloc::ConcreteInt X(getBasicVals().getValue(0, Ex->getType()));
1044249423Sdim            Result = evalBinOp(state, BO_EQ, V.castAs<NonLoc>(), X,
1045234353Sdim                               U->getType());
1046234353Sdim          }
1047296417Sdim
1048296417Sdim          state = state->BindExpr(U, LCtx, Result);
1049234353Sdim          break;
1050226586Sdim      }
1051261991Sdim      Bldr.generateNode(U, *I, state);
1052234353Sdim      break;
1053226586Sdim    }
1054261991Sdim    }
1055226586Sdim  }
1056234353Sdim
1057261991Sdim  getCheckerManager().runCheckersForPostStmt(Dst, EvalSet, U, *this);
1058234353Sdim}
1059234353Sdim
1060234353Sdimvoid ExprEngine::VisitIncrementDecrementOperator(const UnaryOperator* U,
1061234353Sdim                                                 ExplodedNode *Pred,
1062234353Sdim                                                 ExplodedNodeSet &Dst) {
1063226586Sdim  // Handle ++ and -- (both pre- and post-increment).
1064226586Sdim  assert (U->isIncrementDecrementOp());
1065226586Sdim  const Expr *Ex = U->getSubExpr()->IgnoreParens();
1066296417Sdim
1067234353Sdim  const LocationContext *LCtx = Pred->getLocationContext();
1068234353Sdim  ProgramStateRef state = Pred->getState();
1069234353Sdim  SVal loc = state->getSVal(Ex, LCtx);
1070296417Sdim
1071234353Sdim  // Perform a load.
1072234353Sdim  ExplodedNodeSet Tmp;
1073234353Sdim  evalLoad(Tmp, U, Ex, Pred, state, loc);
1074296417Sdim
1075234353Sdim  ExplodedNodeSet Dst2;
1076243830Sdim  StmtNodeBuilder Bldr(Tmp, Dst2, *currBldrCtx);
1077234353Sdim  for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end();I!=E;++I) {
1078296417Sdim
1079234353Sdim    state = (*I)->getState();
1080234353Sdim    assert(LCtx == (*I)->getLocationContext());
1081234353Sdim    SVal V2_untested = state->getSVal(Ex, LCtx);
1082296417Sdim
1083234353Sdim    // Propagate unknown and undefined values.
1084234353Sdim    if (V2_untested.isUnknownOrUndef()) {
1085327952Sdim      state = state->BindExpr(U, LCtx, V2_untested);
1086327952Sdim
1087327952Sdim      // Perform the store, so that the uninitialized value detection happens.
1088327952Sdim      Bldr.takeNodes(*I);
1089327952Sdim      ExplodedNodeSet Dst3;
1090344779Sdim      evalStore(Dst3, U, Ex, *I, state, loc, V2_untested);
1091327952Sdim      Bldr.addNodes(Dst3);
1092327952Sdim
1093234353Sdim      continue;
1094234353Sdim    }
1095249423Sdim    DefinedSVal V2 = V2_untested.castAs<DefinedSVal>();
1096296417Sdim
1097234353Sdim    // Handle all other values.
1098234353Sdim    BinaryOperator::Opcode Op = U->isIncrementOp() ? BO_Add : BO_Sub;
1099296417Sdim
1100234353Sdim    // If the UnaryOperator has non-location type, use its type to create the
1101234353Sdim    // constant value. If the UnaryOperator has location type, create the
1102234353Sdim    // constant with int type and pointer width.
1103234353Sdim    SVal RHS;
1104341825Sdim    SVal Result;
1105296417Sdim
1106234353Sdim    if (U->getType()->isAnyPointerType())
1107234353Sdim      RHS = svalBuilder.makeArrayIndex(1);
1108243830Sdim    else if (U->getType()->isIntegralOrEnumerationType())
1109243830Sdim      RHS = svalBuilder.makeIntVal(1, U->getType());
1110234353Sdim    else
1111243830Sdim      RHS = UnknownVal();
1112296417Sdim
1113341825Sdim    // The use of an operand of type bool with the ++ operators is deprecated
1114341825Sdim    // but valid until C++17. And if the operand of the ++ operator is of type
1115341825Sdim    // bool, it is set to true until C++17. Note that for '_Bool', it is also
1116341825Sdim    // set to true when it encounters ++ operator.
1117341825Sdim    if (U->getType()->isBooleanType() && U->isIncrementOp())
1118341825Sdim      Result = svalBuilder.makeTruthVal(true, U->getType());
1119341825Sdim    else
1120341825Sdim      Result = evalBinOp(state, Op, V2, RHS, U->getType());
1121296417Sdim
1122234353Sdim    // Conjure a new symbol if necessary to recover precision.
1123234353Sdim    if (Result.isUnknown()){
1124234353Sdim      DefinedOrUnknownSVal SymVal =
1125321369Sdim        svalBuilder.conjureSymbolVal(nullptr, U, LCtx,
1126276479Sdim                                     currBldrCtx->blockCount());
1127234353Sdim      Result = SymVal;
1128296417Sdim
1129234353Sdim      // If the value is a location, ++/-- should always preserve
1130234353Sdim      // non-nullness.  Check if the original value was non-null, and if so
1131234353Sdim      // propagate that constraint.
1132234353Sdim      if (Loc::isLocType(U->getType())) {
1133234353Sdim        DefinedOrUnknownSVal Constraint =
1134234353Sdim        svalBuilder.evalEQ(state, V2,svalBuilder.makeZeroVal(U->getType()));
1135296417Sdim
1136234353Sdim        if (!state->assume(Constraint, true)) {
1137234353Sdim          // It isn't feasible for the original value to be null.
1138234353Sdim          // Propagate this constraint.
1139234353Sdim          Constraint = svalBuilder.evalEQ(state, SymVal,
1140234353Sdim                                       svalBuilder.makeZeroVal(U->getType()));
1141296417Sdim
1142234353Sdim          state = state->assume(Constraint, false);
1143234353Sdim          assert(state);
1144226586Sdim        }
1145226586Sdim      }
1146226586Sdim    }
1147296417Sdim
1148234353Sdim    // Since the lvalue-to-rvalue conversion is explicit in the AST,
1149234353Sdim    // we bind an l-value if the operator is prefix and an lvalue (in C++).
1150239462Sdim    if (U->isGLValue())
1151234353Sdim      state = state->BindExpr(U, LCtx, loc);
1152234353Sdim    else
1153234353Sdim      state = state->BindExpr(U, LCtx, U->isPostfix() ? V2 : Result);
1154296417Sdim
1155234353Sdim    // Perform the store.
1156234353Sdim    Bldr.takeNodes(*I);
1157234353Sdim    ExplodedNodeSet Dst3;
1158344779Sdim    evalStore(Dst3, U, Ex, *I, state, loc, Result);
1159234353Sdim    Bldr.addNodes(Dst3);
1160226586Sdim  }
1161234353Sdim  Dst.insert(Dst2);
1162226586Sdim}
1163