ExprEngineC.cpp revision 327952
1226586Sdim//=-- ExprEngineC.cpp - ExprEngine support for C expressions ----*- C++ -*-===//
2226586Sdim//
3226586Sdim//                     The LLVM Compiler Infrastructure
4226586Sdim//
5226586Sdim// This file is distributed under the University of Illinois Open Source
6226586Sdim// License. See LICENSE.TXT for details.
7226586Sdim//
8226586Sdim//===----------------------------------------------------------------------===//
9226586Sdim//
10226586Sdim//  This file defines ExprEngine's support for C expressions.
11226586Sdim//
12226586Sdim//===----------------------------------------------------------------------===//
13226586Sdim
14249423Sdim#include "clang/AST/ExprCXX.h"
15314564Sdim#include "clang/AST/DeclCXX.h"
16226586Sdim#include "clang/StaticAnalyzer/Core/CheckerManager.h"
17226586Sdim#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
18226586Sdim
19226586Sdimusing namespace clang;
20226586Sdimusing namespace ento;
21226586Sdimusing llvm::APSInt;
22226586Sdim
23327952Sdim/// \brief Optionally conjure and return a symbol for offset when processing
24327952Sdim/// an expression \p Expression.
25327952Sdim/// If \p Other is a location, conjure a symbol for \p Symbol
26327952Sdim/// (offset) if it is unknown so that memory arithmetic always
27327952Sdim/// results in an ElementRegion.
28327952Sdim/// \p Count The number of times the current basic block was visited.
29327952Sdimstatic SVal conjureOffsetSymbolOnLocation(
30327952Sdim    SVal Symbol, SVal Other, Expr* Expression, SValBuilder &svalBuilder,
31327952Sdim    unsigned Count, const LocationContext *LCtx) {
32327952Sdim  QualType Ty = Expression->getType();
33327952Sdim  if (Other.getAs<Loc>() &&
34327952Sdim      Ty->isIntegralOrEnumerationType() &&
35327952Sdim      Symbol.isUnknown()) {
36327952Sdim    return svalBuilder.conjureSymbolVal(Expression, LCtx, Ty, Count);
37327952Sdim  }
38327952Sdim  return Symbol;
39327952Sdim}
40327952Sdim
41226586Sdimvoid ExprEngine::VisitBinaryOperator(const BinaryOperator* B,
42226586Sdim                                     ExplodedNode *Pred,
43226586Sdim                                     ExplodedNodeSet &Dst) {
44226586Sdim
45226586Sdim  Expr *LHS = B->getLHS()->IgnoreParens();
46226586Sdim  Expr *RHS = B->getRHS()->IgnoreParens();
47296417Sdim
48226586Sdim  // FIXME: Prechecks eventually go in ::Visit().
49226586Sdim  ExplodedNodeSet CheckedSet;
50226586Sdim  ExplodedNodeSet Tmp2;
51226586Sdim  getCheckerManager().runCheckersForPreStmt(CheckedSet, Pred, B, *this);
52296417Sdim
53288943Sdim  // With both the LHS and RHS evaluated, process the operation itself.
54226586Sdim  for (ExplodedNodeSet::iterator it=CheckedSet.begin(), ei=CheckedSet.end();
55226586Sdim         it != ei; ++it) {
56296417Sdim
57234353Sdim    ProgramStateRef state = (*it)->getState();
58234353Sdim    const LocationContext *LCtx = (*it)->getLocationContext();
59234353Sdim    SVal LeftV = state->getSVal(LHS, LCtx);
60234353Sdim    SVal RightV = state->getSVal(RHS, LCtx);
61296417Sdim
62226586Sdim    BinaryOperator::Opcode Op = B->getOpcode();
63296417Sdim
64226586Sdim    if (Op == BO_Assign) {
65226586Sdim      // EXPERIMENTAL: "Conjured" symbols.
66226586Sdim      // FIXME: Handle structs.
67234353Sdim      if (RightV.isUnknown()) {
68243830Sdim        unsigned Count = currBldrCtx->blockCount();
69276479Sdim        RightV = svalBuilder.conjureSymbolVal(nullptr, B->getRHS(), LCtx,
70276479Sdim                                              Count);
71226586Sdim      }
72226586Sdim      // Simulate the effects of a "store":  bind the value of the RHS
73226586Sdim      // to the L-Value represented by the LHS.
74239462Sdim      SVal ExprVal = B->isGLValue() ? LeftV : RightV;
75234353Sdim      evalStore(Tmp2, B, LHS, *it, state->BindExpr(B, LCtx, ExprVal),
76234353Sdim                LeftV, RightV);
77226586Sdim      continue;
78226586Sdim    }
79296417Sdim
80226586Sdim    if (!B->isAssignmentOp()) {
81243830Sdim      StmtNodeBuilder Bldr(*it, Tmp2, *currBldrCtx);
82239462Sdim
83239462Sdim      if (B->isAdditiveOp()) {
84239462Sdim        // TODO: This can be removed after we enable history tracking with
85239462Sdim        // SymSymExpr.
86243830Sdim        unsigned Count = currBldrCtx->blockCount();
87327952Sdim        RightV = conjureOffsetSymbolOnLocation(
88327952Sdim            RightV, LeftV, RHS, svalBuilder, Count, LCtx);
89327952Sdim        LeftV = conjureOffsetSymbolOnLocation(
90327952Sdim            LeftV, RightV, LHS, svalBuilder, Count, LCtx);
91239462Sdim      }
92239462Sdim
93276479Sdim      // Although we don't yet model pointers-to-members, we do need to make
94276479Sdim      // sure that the members of temporaries have a valid 'this' pointer for
95276479Sdim      // other checks.
96276479Sdim      if (B->getOpcode() == BO_PtrMemD)
97276479Sdim        state = createTemporaryRegionIfNeeded(state, LCtx, LHS);
98276479Sdim
99226586Sdim      // Process non-assignments except commas or short-circuited
100226586Sdim      // logical expressions (LAnd and LOr).
101296417Sdim      SVal Result = evalBinOp(state, Op, LeftV, RightV, B->getType());
102327952Sdim      if (!Result.isUnknown()) {
103327952Sdim        state = state->BindExpr(B, LCtx, Result);
104296417Sdim      }
105226586Sdim
106234353Sdim      Bldr.generateNode(B, *it, state);
107226586Sdim      continue;
108226586Sdim    }
109296417Sdim
110226586Sdim    assert (B->isCompoundAssignmentOp());
111296417Sdim
112226586Sdim    switch (Op) {
113226586Sdim      default:
114226586Sdim        llvm_unreachable("Invalid opcode for compound assignment.");
115226586Sdim      case BO_MulAssign: Op = BO_Mul; break;
116226586Sdim      case BO_DivAssign: Op = BO_Div; break;
117226586Sdim      case BO_RemAssign: Op = BO_Rem; break;
118226586Sdim      case BO_AddAssign: Op = BO_Add; break;
119226586Sdim      case BO_SubAssign: Op = BO_Sub; break;
120226586Sdim      case BO_ShlAssign: Op = BO_Shl; break;
121226586Sdim      case BO_ShrAssign: Op = BO_Shr; break;
122226586Sdim      case BO_AndAssign: Op = BO_And; break;
123226586Sdim      case BO_XorAssign: Op = BO_Xor; break;
124226586Sdim      case BO_OrAssign:  Op = BO_Or;  break;
125226586Sdim    }
126296417Sdim
127226586Sdim    // Perform a load (the LHS).  This performs the checks for
128226586Sdim    // null dereferences, and so on.
129226586Sdim    ExplodedNodeSet Tmp;
130226586Sdim    SVal location = LeftV;
131234353Sdim    evalLoad(Tmp, B, LHS, *it, state, location);
132296417Sdim
133226586Sdim    for (ExplodedNodeSet::iterator I = Tmp.begin(), E = Tmp.end(); I != E;
134226586Sdim         ++I) {
135226586Sdim
136226586Sdim      state = (*I)->getState();
137234353Sdim      const LocationContext *LCtx = (*I)->getLocationContext();
138234353Sdim      SVal V = state->getSVal(LHS, LCtx);
139296417Sdim
140226586Sdim      // Get the computation type.
141226586Sdim      QualType CTy =
142226586Sdim        cast<CompoundAssignOperator>(B)->getComputationResultType();
143226586Sdim      CTy = getContext().getCanonicalType(CTy);
144296417Sdim
145226586Sdim      QualType CLHSTy =
146226586Sdim        cast<CompoundAssignOperator>(B)->getComputationLHSType();
147226586Sdim      CLHSTy = getContext().getCanonicalType(CLHSTy);
148296417Sdim
149226586Sdim      QualType LTy = getContext().getCanonicalType(LHS->getType());
150296417Sdim
151226586Sdim      // Promote LHS.
152226586Sdim      V = svalBuilder.evalCast(V, CLHSTy, LTy);
153296417Sdim
154226586Sdim      // Compute the result of the operation.
155226586Sdim      SVal Result = svalBuilder.evalCast(evalBinOp(state, Op, V, RightV, CTy),
156226586Sdim                                         B->getType(), CTy);
157296417Sdim
158226586Sdim      // EXPERIMENTAL: "Conjured" symbols.
159226586Sdim      // FIXME: Handle structs.
160296417Sdim
161226586Sdim      SVal LHSVal;
162296417Sdim
163234353Sdim      if (Result.isUnknown()) {
164226586Sdim        // The symbolic value is actually for the type of the left-hand side
165226586Sdim        // expression, not the computation type, as this is the value the
166226586Sdim        // LValue on the LHS will bind to.
167276479Sdim        LHSVal = svalBuilder.conjureSymbolVal(nullptr, B->getRHS(), LCtx, LTy,
168243830Sdim                                              currBldrCtx->blockCount());
169226586Sdim        // However, we need to convert the symbol to the computation type.
170226586Sdim        Result = svalBuilder.evalCast(LHSVal, CTy, LTy);
171226586Sdim      }
172226586Sdim      else {
173226586Sdim        // The left-hand side may bind to a different value then the
174226586Sdim        // computation type.
175226586Sdim        LHSVal = svalBuilder.evalCast(Result, LTy, CTy);
176226586Sdim      }
177296417Sdim
178296417Sdim      // In C++, assignment and compound assignment operators return an
179226586Sdim      // lvalue.
180239462Sdim      if (B->isGLValue())
181234353Sdim        state = state->BindExpr(B, LCtx, location);
182226586Sdim      else
183234353Sdim        state = state->BindExpr(B, LCtx, Result);
184296417Sdim
185226586Sdim      evalStore(Tmp2, B, LHS, *I, state, location, LHSVal);
186226586Sdim    }
187226586Sdim  }
188296417Sdim
189226586Sdim  // FIXME: postvisits eventually go in ::Visit()
190226586Sdim  getCheckerManager().runCheckersForPostStmt(Dst, Tmp2, B, *this);
191226586Sdim}
192226586Sdim
193226586Sdimvoid ExprEngine::VisitBlockExpr(const BlockExpr *BE, ExplodedNode *Pred,
194226586Sdim                                ExplodedNodeSet &Dst) {
195296417Sdim
196226586Sdim  CanQualType T = getContext().getCanonicalType(BE->getType());
197239462Sdim
198296417Sdim  const BlockDecl *BD = BE->getBlockDecl();
199239462Sdim  // Get the value of the block itself.
200296417Sdim  SVal V = svalBuilder.getBlockPointer(BD, T,
201261991Sdim                                       Pred->getLocationContext(),
202261991Sdim                                       currBldrCtx->blockCount());
203296417Sdim
204239462Sdim  ProgramStateRef State = Pred->getState();
205296417Sdim
206239462Sdim  // If we created a new MemRegion for the block, we should explicitly bind
207239462Sdim  // the captured variables.
208239462Sdim  if (const BlockDataRegion *BDR =
209239462Sdim      dyn_cast_or_null<BlockDataRegion>(V.getAsRegion())) {
210296417Sdim
211239462Sdim    BlockDataRegion::referenced_vars_iterator I = BDR->referenced_vars_begin(),
212239462Sdim                                              E = BDR->referenced_vars_end();
213296417Sdim
214296417Sdim    auto CI = BD->capture_begin();
215296417Sdim    auto CE = BD->capture_end();
216239462Sdim    for (; I != E; ++I) {
217296417Sdim      const VarRegion *capturedR = I.getCapturedRegion();
218296417Sdim      const VarRegion *originalR = I.getOriginalRegion();
219296417Sdim
220296417Sdim      // If the capture had a copy expression, use the result of evaluating
221296417Sdim      // that expression, otherwise use the original value.
222296417Sdim      // We rely on the invariant that the block declaration's capture variables
223296417Sdim      // are a prefix of the BlockDataRegion's referenced vars (which may include
224296417Sdim      // referenced globals, etc.) to enable fast lookup of the capture for a
225296417Sdim      // given referenced var.
226296417Sdim      const Expr *copyExpr = nullptr;
227296417Sdim      if (CI != CE) {
228296417Sdim        assert(CI->getVariable() == capturedR->getDecl());
229296417Sdim        copyExpr = CI->getCopyExpr();
230296417Sdim        CI++;
231296417Sdim      }
232296417Sdim
233239462Sdim      if (capturedR != originalR) {
234296417Sdim        SVal originalV;
235321369Sdim        const LocationContext *LCtx = Pred->getLocationContext();
236296417Sdim        if (copyExpr) {
237321369Sdim          originalV = State->getSVal(copyExpr, LCtx);
238296417Sdim        } else {
239296417Sdim          originalV = State->getSVal(loc::MemRegionVal(originalR));
240296417Sdim        }
241321369Sdim        State = State->bindLoc(loc::MemRegionVal(capturedR), originalV, LCtx);
242239462Sdim      }
243239462Sdim    }
244239462Sdim  }
245296417Sdim
246226586Sdim  ExplodedNodeSet Tmp;
247243830Sdim  StmtNodeBuilder Bldr(Pred, Tmp, *currBldrCtx);
248234353Sdim  Bldr.generateNode(BE, Pred,
249239462Sdim                    State->BindExpr(BE, Pred->getLocationContext(), V),
250276479Sdim                    nullptr, ProgramPoint::PostLValueKind);
251276479Sdim
252226586Sdim  // FIXME: Move all post/pre visits to ::Visit().
253226586Sdim  getCheckerManager().runCheckersForPostStmt(Dst, Tmp, BE, *this);
254226586Sdim}
255226586Sdim
256314564SdimProgramStateRef ExprEngine::handleLValueBitCast(
257314564Sdim    ProgramStateRef state, const Expr* Ex, const LocationContext* LCtx,
258314564Sdim    QualType T, QualType ExTy, const CastExpr* CastE, StmtNodeBuilder& Bldr,
259314564Sdim    ExplodedNode* Pred) {
260314564Sdim  // Delegate to SValBuilder to process.
261314564Sdim  SVal V = state->getSVal(Ex, LCtx);
262314564Sdim  V = svalBuilder.evalCast(V, T, ExTy);
263314564Sdim  // Negate the result if we're treating the boolean as a signed i1
264314564Sdim  if (CastE->getCastKind() == CK_BooleanToSignedIntegral)
265314564Sdim    V = evalMinus(V);
266314564Sdim  state = state->BindExpr(CastE, LCtx, V);
267314564Sdim  Bldr.generateNode(CastE, Pred, state);
268314564Sdim
269314564Sdim  return state;
270314564Sdim}
271314564Sdim
272314564SdimProgramStateRef ExprEngine::handleLVectorSplat(
273314564Sdim    ProgramStateRef state, const LocationContext* LCtx, const CastExpr* CastE,
274314564Sdim    StmtNodeBuilder &Bldr, ExplodedNode* Pred) {
275314564Sdim  // Recover some path sensitivity by conjuring a new value.
276314564Sdim  QualType resultType = CastE->getType();
277314564Sdim  if (CastE->isGLValue())
278314564Sdim    resultType = getContext().getPointerType(resultType);
279314564Sdim  SVal result = svalBuilder.conjureSymbolVal(nullptr, CastE, LCtx,
280314564Sdim                                             resultType,
281314564Sdim                                             currBldrCtx->blockCount());
282314564Sdim  state = state->BindExpr(CastE, LCtx, result);
283314564Sdim  Bldr.generateNode(CastE, Pred, state);
284314564Sdim
285314564Sdim  return state;
286314564Sdim}
287314564Sdim
288296417Sdimvoid ExprEngine::VisitCast(const CastExpr *CastE, const Expr *Ex,
289226586Sdim                           ExplodedNode *Pred, ExplodedNodeSet &Dst) {
290296417Sdim
291226586Sdim  ExplodedNodeSet dstPreStmt;
292226586Sdim  getCheckerManager().runCheckersForPreStmt(dstPreStmt, Pred, CastE, *this);
293296417Sdim
294234353Sdim  if (CastE->getCastKind() == CK_LValueToRValue) {
295226586Sdim    for (ExplodedNodeSet::iterator I = dstPreStmt.begin(), E = dstPreStmt.end();
296226586Sdim         I!=E; ++I) {
297226586Sdim      ExplodedNode *subExprNode = *I;
298234353Sdim      ProgramStateRef state = subExprNode->getState();
299234353Sdim      const LocationContext *LCtx = subExprNode->getLocationContext();
300234353Sdim      evalLoad(Dst, CastE, CastE, subExprNode, state, state->getSVal(Ex, LCtx));
301226586Sdim    }
302226586Sdim    return;
303226586Sdim  }
304296417Sdim
305296417Sdim  // All other casts.
306226586Sdim  QualType T = CastE->getType();
307226586Sdim  QualType ExTy = Ex->getType();
308296417Sdim
309226586Sdim  if (const ExplicitCastExpr *ExCast=dyn_cast_or_null<ExplicitCastExpr>(CastE))
310226586Sdim    T = ExCast->getTypeAsWritten();
311296417Sdim
312243830Sdim  StmtNodeBuilder Bldr(dstPreStmt, Dst, *currBldrCtx);
313226586Sdim  for (ExplodedNodeSet::iterator I = dstPreStmt.begin(), E = dstPreStmt.end();
314226586Sdim       I != E; ++I) {
315296417Sdim
316226586Sdim    Pred = *I;
317243830Sdim    ProgramStateRef state = Pred->getState();
318243830Sdim    const LocationContext *LCtx = Pred->getLocationContext();
319243830Sdim
320226586Sdim    switch (CastE->getCastKind()) {
321226586Sdim      case CK_LValueToRValue:
322226586Sdim        llvm_unreachable("LValueToRValue casts handled earlier.");
323226586Sdim      case CK_ToVoid:
324226586Sdim        continue;
325226586Sdim        // The analyzer doesn't do anything special with these casts,
326226586Sdim        // since it understands retain/release semantics already.
327226586Sdim      case CK_ARCProduceObject:
328226586Sdim      case CK_ARCConsumeObject:
329226586Sdim      case CK_ARCReclaimReturnedObject:
330226586Sdim      case CK_ARCExtendBlockObject: // Fall-through.
331234353Sdim      case CK_CopyAndAutoreleaseBlockObject:
332234353Sdim        // The analyser can ignore atomic casts for now, although some future
333234353Sdim        // checkers may want to make certain that you're not modifying the same
334234353Sdim        // value through atomic and nonatomic pointers.
335234353Sdim      case CK_AtomicToNonAtomic:
336234353Sdim      case CK_NonAtomicToAtomic:
337226586Sdim        // True no-ops.
338226586Sdim      case CK_NoOp:
339243830Sdim      case CK_ConstructorConversion:
340243830Sdim      case CK_UserDefinedConversion:
341243830Sdim      case CK_FunctionToPointerDecay:
342243830Sdim      case CK_BuiltinFnToFnPtr: {
343226586Sdim        // Copy the SVal of Ex to CastE.
344234353Sdim        ProgramStateRef state = Pred->getState();
345234353Sdim        const LocationContext *LCtx = Pred->getLocationContext();
346234353Sdim        SVal V = state->getSVal(Ex, LCtx);
347234353Sdim        state = state->BindExpr(CastE, LCtx, V);
348234353Sdim        Bldr.generateNode(CastE, Pred, state);
349226586Sdim        continue;
350226586Sdim      }
351243830Sdim      case CK_MemberPointerToBoolean:
352314564Sdim      case CK_PointerToBoolean: {
353314564Sdim        SVal V = state->getSVal(Ex, LCtx);
354314564Sdim        auto PTMSV = V.getAs<nonloc::PointerToMember>();
355314564Sdim        if (PTMSV)
356314564Sdim          V = svalBuilder.makeTruthVal(!PTMSV->isNullMemberPointer(), ExTy);
357314564Sdim        if (V.isUndef() || PTMSV) {
358314564Sdim          state = state->BindExpr(CastE, LCtx, V);
359314564Sdim          Bldr.generateNode(CastE, Pred, state);
360314564Sdim          continue;
361314564Sdim        }
362314564Sdim        // Explicitly proceed with default handler for this case cascade.
363314564Sdim        state =
364314564Sdim            handleLValueBitCast(state, Ex, LCtx, T, ExTy, CastE, Bldr, Pred);
365314564Sdim        continue;
366314564Sdim      }
367226586Sdim      case CK_Dependent:
368226586Sdim      case CK_ArrayToPointerDecay:
369226586Sdim      case CK_BitCast:
370276479Sdim      case CK_AddressSpaceConversion:
371296417Sdim      case CK_BooleanToSignedIntegral:
372226586Sdim      case CK_NullToPointer:
373226586Sdim      case CK_IntegralToPointer:
374314564Sdim      case CK_PointerToIntegral: {
375314564Sdim        SVal V = state->getSVal(Ex, LCtx);
376314564Sdim        if (V.getAs<nonloc::PointerToMember>()) {
377314564Sdim          state = state->BindExpr(CastE, LCtx, UnknownVal());
378314564Sdim          Bldr.generateNode(CastE, Pred, state);
379314564Sdim          continue;
380314564Sdim        }
381314564Sdim        // Explicitly proceed with default handler for this case cascade.
382314564Sdim        state =
383314564Sdim            handleLValueBitCast(state, Ex, LCtx, T, ExTy, CastE, Bldr, Pred);
384314564Sdim        continue;
385314564Sdim      }
386226586Sdim      case CK_IntegralToBoolean:
387226586Sdim      case CK_IntegralToFloating:
388226586Sdim      case CK_FloatingToIntegral:
389226586Sdim      case CK_FloatingToBoolean:
390226586Sdim      case CK_FloatingCast:
391226586Sdim      case CK_FloatingRealToComplex:
392226586Sdim      case CK_FloatingComplexToReal:
393226586Sdim      case CK_FloatingComplexToBoolean:
394226586Sdim      case CK_FloatingComplexCast:
395226586Sdim      case CK_FloatingComplexToIntegralComplex:
396226586Sdim      case CK_IntegralRealToComplex:
397226586Sdim      case CK_IntegralComplexToReal:
398226586Sdim      case CK_IntegralComplexToBoolean:
399226586Sdim      case CK_IntegralComplexCast:
400226586Sdim      case CK_IntegralComplexToFloatingComplex:
401226586Sdim      case CK_CPointerToObjCPointerCast:
402226586Sdim      case CK_BlockPointerToObjCPointerCast:
403296417Sdim      case CK_AnyPointerToBlockPointerCast:
404296417Sdim      case CK_ObjCObjectLValueCast:
405261991Sdim      case CK_ZeroToOCLEvent:
406314564Sdim      case CK_ZeroToOCLQueue:
407314564Sdim      case CK_IntToOCLSampler:
408261991Sdim      case CK_LValueBitCast: {
409314564Sdim        state =
410314564Sdim            handleLValueBitCast(state, Ex, LCtx, T, ExTy, CastE, Bldr, Pred);
411226586Sdim        continue;
412226586Sdim      }
413296417Sdim      case CK_IntegralCast: {
414296417Sdim        // Delegate to SValBuilder to process.
415296417Sdim        SVal V = state->getSVal(Ex, LCtx);
416296417Sdim        V = svalBuilder.evalIntegralCast(state, V, T, ExTy);
417296417Sdim        state = state->BindExpr(CastE, LCtx, V);
418296417Sdim        Bldr.generateNode(CastE, Pred, state);
419296417Sdim        continue;
420296417Sdim      }
421226586Sdim      case CK_DerivedToBase:
422226586Sdim      case CK_UncheckedDerivedToBase: {
423226586Sdim        // For DerivedToBase cast, delegate to the store manager.
424234353Sdim        SVal val = state->getSVal(Ex, LCtx);
425239462Sdim        val = getStoreManager().evalDerivedToBase(val, CastE);
426234353Sdim        state = state->BindExpr(CastE, LCtx, val);
427234353Sdim        Bldr.generateNode(CastE, Pred, state);
428226586Sdim        continue;
429226586Sdim      }
430234353Sdim      // Handle C++ dyn_cast.
431234353Sdim      case CK_Dynamic: {
432234353Sdim        SVal val = state->getSVal(Ex, LCtx);
433234353Sdim
434234353Sdim        // Compute the type of the result.
435234353Sdim        QualType resultType = CastE->getType();
436239462Sdim        if (CastE->isGLValue())
437234353Sdim          resultType = getContext().getPointerType(resultType);
438234353Sdim
439234353Sdim        bool Failed = false;
440234353Sdim
441234353Sdim        // Check if the value being cast evaluates to 0.
442234353Sdim        if (val.isZeroConstant())
443234353Sdim          Failed = true;
444234353Sdim        // Else, evaluate the cast.
445234353Sdim        else
446314564Sdim          val = getStoreManager().attemptDownCast(val, T, Failed);
447234353Sdim
448234353Sdim        if (Failed) {
449234353Sdim          if (T->isReferenceType()) {
450234353Sdim            // A bad_cast exception is thrown if input value is a reference.
451234353Sdim            // Currently, we model this, by generating a sink.
452243830Sdim            Bldr.generateSink(CastE, Pred, state);
453234353Sdim            continue;
454234353Sdim          } else {
455234353Sdim            // If the cast fails on a pointer, bind to 0.
456234353Sdim            state = state->BindExpr(CastE, LCtx, svalBuilder.makeNull());
457234353Sdim          }
458234353Sdim        } else {
459234353Sdim          // If we don't know if the cast succeeded, conjure a new symbol.
460234353Sdim          if (val.isUnknown()) {
461243830Sdim            DefinedOrUnknownSVal NewSym =
462276479Sdim              svalBuilder.conjureSymbolVal(nullptr, CastE, LCtx, resultType,
463243830Sdim                                           currBldrCtx->blockCount());
464234353Sdim            state = state->BindExpr(CastE, LCtx, NewSym);
465296417Sdim          } else
466234353Sdim            // Else, bind to the derived region value.
467234353Sdim            state = state->BindExpr(CastE, LCtx, val);
468234353Sdim        }
469234353Sdim        Bldr.generateNode(CastE, Pred, state);
470234353Sdim        continue;
471234353Sdim      }
472314564Sdim      case CK_BaseToDerived: {
473314564Sdim        SVal val = state->getSVal(Ex, LCtx);
474314564Sdim        QualType resultType = CastE->getType();
475314564Sdim        if (CastE->isGLValue())
476314564Sdim          resultType = getContext().getPointerType(resultType);
477314564Sdim
478314564Sdim        bool Failed = false;
479314564Sdim
480314564Sdim        if (!val.isConstant()) {
481314564Sdim          val = getStoreManager().attemptDownCast(val, T, Failed);
482314564Sdim        }
483314564Sdim
484314564Sdim        // Failed to cast or the result is unknown, fall back to conservative.
485314564Sdim        if (Failed || val.isUnknown()) {
486314564Sdim          val =
487314564Sdim            svalBuilder.conjureSymbolVal(nullptr, CastE, LCtx, resultType,
488314564Sdim                                         currBldrCtx->blockCount());
489314564Sdim        }
490314564Sdim        state = state->BindExpr(CastE, LCtx, val);
491314564Sdim        Bldr.generateNode(CastE, Pred, state);
492314564Sdim        continue;
493314564Sdim      }
494243830Sdim      case CK_NullToMemberPointer: {
495314564Sdim        SVal V = svalBuilder.getMemberPointer(nullptr);
496243830Sdim        state = state->BindExpr(CastE, LCtx, V);
497243830Sdim        Bldr.generateNode(CastE, Pred, state);
498243830Sdim        continue;
499243830Sdim      }
500314564Sdim      case CK_DerivedToBaseMemberPointer:
501314564Sdim      case CK_BaseToDerivedMemberPointer:
502314564Sdim      case CK_ReinterpretMemberPointer: {
503314564Sdim        SVal V = state->getSVal(Ex, LCtx);
504314564Sdim        if (auto PTMSV = V.getAs<nonloc::PointerToMember>()) {
505314564Sdim          SVal CastedPTMSV = svalBuilder.makePointerToMember(
506314564Sdim              getBasicVals().accumCXXBase(
507314564Sdim                  llvm::make_range<CastExpr::path_const_iterator>(
508314564Sdim                      CastE->path_begin(), CastE->path_end()), *PTMSV));
509314564Sdim          state = state->BindExpr(CastE, LCtx, CastedPTMSV);
510314564Sdim          Bldr.generateNode(CastE, Pred, state);
511314564Sdim          continue;
512314564Sdim        }
513314564Sdim        // Explicitly proceed with default handler for this case cascade.
514314564Sdim        state = handleLVectorSplat(state, LCtx, CastE, Bldr, Pred);
515314564Sdim        continue;
516314564Sdim      }
517234353Sdim      // Various C++ casts that are not handled yet.
518226586Sdim      case CK_ToUnion:
519261991Sdim      case CK_VectorSplat: {
520314564Sdim        state = handleLVectorSplat(state, LCtx, CastE, Bldr, Pred);
521226586Sdim        continue;
522226586Sdim      }
523226586Sdim    }
524226586Sdim  }
525226586Sdim}
526226586Sdim
527226586Sdimvoid ExprEngine::VisitCompoundLiteralExpr(const CompoundLiteralExpr *CL,
528226586Sdim                                          ExplodedNode *Pred,
529226586Sdim                                          ExplodedNodeSet &Dst) {
530243830Sdim  StmtNodeBuilder B(Pred, Dst, *currBldrCtx);
531234353Sdim
532251662Sdim  ProgramStateRef State = Pred->getState();
533251662Sdim  const LocationContext *LCtx = Pred->getLocationContext();
534251662Sdim
535251662Sdim  const Expr *Init = CL->getInitializer();
536251662Sdim  SVal V = State->getSVal(CL->getInitializer(), LCtx);
537296417Sdim
538327952Sdim  if (isa<CXXConstructExpr>(Init) || isa<CXXStdInitializerListExpr>(Init)) {
539251662Sdim    // No work needed. Just pass the value up to this expression.
540251662Sdim  } else {
541251662Sdim    assert(isa<InitListExpr>(Init));
542251662Sdim    Loc CLLoc = State->getLValue(CL, LCtx);
543321369Sdim    State = State->bindLoc(CLLoc, V, LCtx);
544239462Sdim
545314564Sdim    if (CL->isGLValue())
546251662Sdim      V = CLLoc;
547251662Sdim  }
548251662Sdim
549251662Sdim  B.generateNode(CL, Pred, State->BindExpr(CL, LCtx, V));
550226586Sdim}
551226586Sdim
552226586Sdimvoid ExprEngine::VisitDeclStmt(const DeclStmt *DS, ExplodedNode *Pred,
553226586Sdim                               ExplodedNodeSet &Dst) {
554226586Sdim  // Assumption: The CFG has one DeclStmt per Decl.
555249423Sdim  const VarDecl *VD = dyn_cast_or_null<VarDecl>(*DS->decl_begin());
556249423Sdim
557249423Sdim  if (!VD) {
558234353Sdim    //TODO:AZ: remove explicit insertion after refactoring is done.
559234353Sdim    Dst.insert(Pred);
560226586Sdim    return;
561234353Sdim  }
562296417Sdim
563226586Sdim  // FIXME: all pre/post visits should eventually be handled by ::Visit().
564226586Sdim  ExplodedNodeSet dstPreVisit;
565226586Sdim  getCheckerManager().runCheckersForPreStmt(dstPreVisit, Pred, DS, *this);
566296417Sdim
567261991Sdim  ExplodedNodeSet dstEvaluated;
568261991Sdim  StmtNodeBuilder B(dstPreVisit, dstEvaluated, *currBldrCtx);
569226586Sdim  for (ExplodedNodeSet::iterator I = dstPreVisit.begin(), E = dstPreVisit.end();
570226586Sdim       I!=E; ++I) {
571226586Sdim    ExplodedNode *N = *I;
572234353Sdim    ProgramStateRef state = N->getState();
573249423Sdim    const LocationContext *LC = N->getLocationContext();
574249423Sdim
575226586Sdim    // Decls without InitExpr are not initialized explicitly.
576226586Sdim    if (const Expr *InitEx = VD->getInit()) {
577249423Sdim
578249423Sdim      // Note in the state that the initialization has occurred.
579249423Sdim      ExplodedNode *UpdatedN = N;
580239462Sdim      SVal InitVal = state->getSVal(InitEx, LC);
581234353Sdim
582296417Sdim      assert(DS->isSingleDecl());
583296417Sdim      if (auto *CtorExpr = findDirectConstructorForCurrentCFGElement()) {
584296417Sdim        assert(InitEx->IgnoreImplicit() == CtorExpr);
585296417Sdim        (void)CtorExpr;
586239462Sdim        // We constructed the object directly in the variable.
587239462Sdim        // No need to bind anything.
588249423Sdim        B.generateNode(DS, UpdatedN, state);
589239462Sdim      } else {
590239462Sdim        // We bound the temp obj region to the CXXConstructExpr. Now recover
591239462Sdim        // the lazy compound value when the variable is not a reference.
592249423Sdim        if (AMgr.getLangOpts().CPlusPlus && VD->getType()->isRecordType() &&
593249423Sdim            !VD->getType()->isReferenceType()) {
594249423Sdim          if (Optional<loc::MemRegionVal> M =
595249423Sdim                  InitVal.getAs<loc::MemRegionVal>()) {
596249423Sdim            InitVal = state->getSVal(M->getRegion());
597249423Sdim            assert(InitVal.getAs<nonloc::LazyCompoundVal>());
598249423Sdim          }
599239462Sdim        }
600296417Sdim
601239462Sdim        // Recover some path-sensitivity if a scalar value evaluated to
602239462Sdim        // UnknownVal.
603239462Sdim        if (InitVal.isUnknown()) {
604239462Sdim          QualType Ty = InitEx->getType();
605239462Sdim          if (InitEx->isGLValue()) {
606239462Sdim            Ty = getContext().getPointerType(Ty);
607239462Sdim          }
608239462Sdim
609276479Sdim          InitVal = svalBuilder.conjureSymbolVal(nullptr, InitEx, LC, Ty,
610243830Sdim                                                 currBldrCtx->blockCount());
611239462Sdim        }
612249423Sdim
613249423Sdim
614249423Sdim        B.takeNodes(UpdatedN);
615239462Sdim        ExplodedNodeSet Dst2;
616249423Sdim        evalBind(Dst2, DS, UpdatedN, state->getLValue(VD, LC), InitVal, true);
617239462Sdim        B.addNodes(Dst2);
618226586Sdim      }
619226586Sdim    }
620226586Sdim    else {
621243830Sdim      B.generateNode(DS, N, state);
622226586Sdim    }
623226586Sdim  }
624261991Sdim
625261991Sdim  getCheckerManager().runCheckersForPostStmt(Dst, B.getResults(), DS, *this);
626226586Sdim}
627226586Sdim
628226586Sdimvoid ExprEngine::VisitLogicalExpr(const BinaryOperator* B, ExplodedNode *Pred,
629226586Sdim                                  ExplodedNodeSet &Dst) {
630226586Sdim  assert(B->getOpcode() == BO_LAnd ||
631226586Sdim         B->getOpcode() == BO_LOr);
632234353Sdim
633243830Sdim  StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx);
634234353Sdim  ProgramStateRef state = Pred->getState();
635239462Sdim
636327952Sdim  if (B->getType()->isVectorType()) {
637327952Sdim    // FIXME: We do not model vector arithmetic yet. When adding support for
638327952Sdim    // that, note that the CFG-based reasoning below does not apply, because
639327952Sdim    // logical operators on vectors are not short-circuit. Currently they are
640327952Sdim    // modeled as short-circuit in Clang CFG but this is incorrect.
641327952Sdim    // Do not set the value for the expression. It'd be UnknownVal by default.
642327952Sdim    Bldr.generateNode(B, Pred, state);
643327952Sdim    return;
644327952Sdim  }
645327952Sdim
646239462Sdim  ExplodedNode *N = Pred;
647249423Sdim  while (!N->getLocation().getAs<BlockEntrance>()) {
648239462Sdim    ProgramPoint P = N->getLocation();
649249423Sdim    assert(P.getAs<PreStmt>()|| P.getAs<PreStmtPurgeDeadSymbols>());
650239462Sdim    (void) P;
651239462Sdim    assert(N->pred_size() == 1);
652239462Sdim    N = *N->pred_begin();
653226586Sdim  }
654239462Sdim  assert(N->pred_size() == 1);
655239462Sdim  N = *N->pred_begin();
656249423Sdim  BlockEdge BE = N->getLocation().castAs<BlockEdge>();
657239462Sdim  SVal X;
658239462Sdim
659239462Sdim  // Determine the value of the expression by introspecting how we
660239462Sdim  // got this location in the CFG.  This requires looking at the previous
661239462Sdim  // block we were in and what kind of control-flow transfer was involved.
662239462Sdim  const CFGBlock *SrcBlock = BE.getSrc();
663239462Sdim  // The only terminator (if there is one) that makes sense is a logical op.
664239462Sdim  CFGTerminator T = SrcBlock->getTerminator();
665239462Sdim  if (const BinaryOperator *Term = cast_or_null<BinaryOperator>(T.getStmt())) {
666239462Sdim    (void) Term;
667239462Sdim    assert(Term->isLogicalOp());
668239462Sdim    assert(SrcBlock->succ_size() == 2);
669239462Sdim    // Did we take the true or false branch?
670239462Sdim    unsigned constant = (*SrcBlock->succ_begin() == BE.getDst()) ? 1 : 0;
671239462Sdim    X = svalBuilder.makeIntVal(constant, B->getType());
672239462Sdim  }
673226586Sdim  else {
674239462Sdim    // If there is no terminator, by construction the last statement
675239462Sdim    // in SrcBlock is the value of the enclosing expression.
676243830Sdim    // However, we still need to constrain that value to be 0 or 1.
677239462Sdim    assert(!SrcBlock->empty());
678249423Sdim    CFGStmt Elem = SrcBlock->rbegin()->castAs<CFGStmt>();
679243830Sdim    const Expr *RHS = cast<Expr>(Elem.getStmt());
680243830Sdim    SVal RHSVal = N->getState()->getSVal(RHS, Pred->getLocationContext());
681243830Sdim
682249423Sdim    if (RHSVal.isUndef()) {
683249423Sdim      X = RHSVal;
684249423Sdim    } else {
685314564Sdim      // We evaluate "RHSVal != 0" expression which result in 0 if the value is
686314564Sdim      // known to be false, 1 if the value is known to be true and a new symbol
687314564Sdim      // when the assumption is unknown.
688314564Sdim      nonloc::ConcreteInt Zero(getBasicVals().getValue(0, B->getType()));
689314564Sdim      X = evalBinOp(N->getState(), BO_NE,
690314564Sdim                    svalBuilder.evalCast(RHSVal, B->getType(), RHS->getType()),
691314564Sdim                    Zero, B->getType());
692243830Sdim    }
693226586Sdim  }
694239462Sdim  Bldr.generateNode(B, Pred, state->BindExpr(B, Pred->getLocationContext(), X));
695226586Sdim}
696226586Sdim
697226586Sdimvoid ExprEngine::VisitInitListExpr(const InitListExpr *IE,
698226586Sdim                                   ExplodedNode *Pred,
699226586Sdim                                   ExplodedNodeSet &Dst) {
700243830Sdim  StmtNodeBuilder B(Pred, Dst, *currBldrCtx);
701226586Sdim
702234353Sdim  ProgramStateRef state = Pred->getState();
703234353Sdim  const LocationContext *LCtx = Pred->getLocationContext();
704226586Sdim  QualType T = getContext().getCanonicalType(IE->getType());
705226586Sdim  unsigned NumInitElements = IE->getNumInits();
706261991Sdim
707261991Sdim  if (!IE->isGLValue() &&
708261991Sdim      (T->isArrayType() || T->isRecordType() || T->isVectorType() ||
709261991Sdim       T->isAnyComplexType())) {
710226586Sdim    llvm::ImmutableList<SVal> vals = getBasicVals().getEmptySValList();
711296417Sdim
712226586Sdim    // Handle base case where the initializer has no elements.
713226586Sdim    // e.g: static int* myArray[] = {};
714226586Sdim    if (NumInitElements == 0) {
715226586Sdim      SVal V = svalBuilder.makeCompoundVal(T, vals);
716234353Sdim      B.generateNode(IE, Pred, state->BindExpr(IE, LCtx, V));
717226586Sdim      return;
718226586Sdim    }
719296417Sdim
720226586Sdim    for (InitListExpr::const_reverse_iterator it = IE->rbegin(),
721226586Sdim         ei = IE->rend(); it != ei; ++it) {
722249423Sdim      SVal V = state->getSVal(cast<Expr>(*it), LCtx);
723314564Sdim      vals = getBasicVals().prependSVal(V, vals);
724226586Sdim    }
725296417Sdim
726234353Sdim    B.generateNode(IE, Pred,
727234353Sdim                   state->BindExpr(IE, LCtx,
728234353Sdim                                   svalBuilder.makeCompoundVal(T, vals)));
729226586Sdim    return;
730226586Sdim  }
731239462Sdim
732261991Sdim  // Handle scalars: int{5} and int{} and GLvalues.
733261991Sdim  // Note, if the InitListExpr is a GLvalue, it means that there is an address
734261991Sdim  // representing it, so it must have a single init element.
735239462Sdim  assert(NumInitElements <= 1);
736239462Sdim
737239462Sdim  SVal V;
738239462Sdim  if (NumInitElements == 0)
739239462Sdim    V = getSValBuilder().makeZeroVal(T);
740239462Sdim  else
741239462Sdim    V = state->getSVal(IE->getInit(0), LCtx);
742239462Sdim
743239462Sdim  B.generateNode(IE, Pred, state->BindExpr(IE, LCtx, V));
744226586Sdim}
745226586Sdim
746226586Sdimvoid ExprEngine::VisitGuardedExpr(const Expr *Ex,
747296417Sdim                                  const Expr *L,
748226586Sdim                                  const Expr *R,
749226586Sdim                                  ExplodedNode *Pred,
750226586Sdim                                  ExplodedNodeSet &Dst) {
751251662Sdim  assert(L && R);
752251662Sdim
753243830Sdim  StmtNodeBuilder B(Pred, Dst, *currBldrCtx);
754234353Sdim  ProgramStateRef state = Pred->getState();
755234353Sdim  const LocationContext *LCtx = Pred->getLocationContext();
756276479Sdim  const CFGBlock *SrcBlock = nullptr;
757239462Sdim
758251662Sdim  // Find the predecessor block.
759251662Sdim  ProgramStateRef SrcState = state;
760239462Sdim  for (const ExplodedNode *N = Pred ; N ; N = *N->pred_begin()) {
761239462Sdim    ProgramPoint PP = N->getLocation();
762249423Sdim    if (PP.getAs<PreStmtPurgeDeadSymbols>() || PP.getAs<BlockEntrance>()) {
763239462Sdim      assert(N->pred_size() == 1);
764239462Sdim      continue;
765239462Sdim    }
766249423Sdim    SrcBlock = PP.castAs<BlockEdge>().getSrc();
767251662Sdim    SrcState = N->getState();
768239462Sdim    break;
769239462Sdim  }
770239462Sdim
771249423Sdim  assert(SrcBlock && "missing function entry");
772249423Sdim
773239462Sdim  // Find the last expression in the predecessor block.  That is the
774239462Sdim  // expression that is used for the value of the ternary expression.
775239462Sdim  bool hasValue = false;
776239462Sdim  SVal V;
777239462Sdim
778296417Sdim  for (CFGElement CE : llvm::reverse(*SrcBlock)) {
779249423Sdim    if (Optional<CFGStmt> CS = CE.getAs<CFGStmt>()) {
780239462Sdim      const Expr *ValEx = cast<Expr>(CS->getStmt());
781251662Sdim      ValEx = ValEx->IgnoreParens();
782251662Sdim
783251662Sdim      // For GNU extension '?:' operator, the left hand side will be an
784251662Sdim      // OpaqueValueExpr, so get the underlying expression.
785251662Sdim      if (const OpaqueValueExpr *OpaqueEx = dyn_cast<OpaqueValueExpr>(L))
786251662Sdim        L = OpaqueEx->getSourceExpr();
787251662Sdim
788251662Sdim      // If the last expression in the predecessor block matches true or false
789251662Sdim      // subexpression, get its the value.
790251662Sdim      if (ValEx == L->IgnoreParens() || ValEx == R->IgnoreParens()) {
791251662Sdim        hasValue = true;
792251662Sdim        V = SrcState->getSVal(ValEx, LCtx);
793251662Sdim      }
794239462Sdim      break;
795239462Sdim    }
796239462Sdim  }
797239462Sdim
798251662Sdim  if (!hasValue)
799276479Sdim    V = svalBuilder.conjureSymbolVal(nullptr, Ex, LCtx,
800276479Sdim                                     currBldrCtx->blockCount());
801239462Sdim
802239462Sdim  // Generate a new node with the binding from the appropriate path.
803239462Sdim  B.generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V, true));
804226586Sdim}
805226586Sdim
806226586Sdimvoid ExprEngine::
807296417SdimVisitOffsetOfExpr(const OffsetOfExpr *OOE,
808226586Sdim                  ExplodedNode *Pred, ExplodedNodeSet &Dst) {
809243830Sdim  StmtNodeBuilder B(Pred, Dst, *currBldrCtx);
810234353Sdim  APSInt IV;
811234353Sdim  if (OOE->EvaluateAsInt(IV, getContext())) {
812226586Sdim    assert(IV.getBitWidth() == getContext().getTypeSize(OOE->getType()));
813251662Sdim    assert(OOE->getType()->isBuiltinType());
814251662Sdim    assert(OOE->getType()->getAs<BuiltinType>()->isInteger());
815251662Sdim    assert(IV.isSigned() == OOE->getType()->isSignedIntegerType());
816226586Sdim    SVal X = svalBuilder.makeIntVal(IV);
817234353Sdim    B.generateNode(OOE, Pred,
818234353Sdim                   Pred->getState()->BindExpr(OOE, Pred->getLocationContext(),
819234353Sdim                                              X));
820226586Sdim  }
821226586Sdim  // FIXME: Handle the case where __builtin_offsetof is not a constant.
822226586Sdim}
823226586Sdim
824226586Sdim
825226586Sdimvoid ExprEngine::
826226586SdimVisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Ex,
827226586Sdim                              ExplodedNode *Pred,
828226586Sdim                              ExplodedNodeSet &Dst) {
829276479Sdim  // FIXME: Prechecks eventually go in ::Visit().
830276479Sdim  ExplodedNodeSet CheckedSet;
831276479Sdim  getCheckerManager().runCheckersForPreStmt(CheckedSet, Pred, Ex, *this);
832226586Sdim
833276479Sdim  ExplodedNodeSet EvalSet;
834276479Sdim  StmtNodeBuilder Bldr(CheckedSet, EvalSet, *currBldrCtx);
835276479Sdim
836226586Sdim  QualType T = Ex->getTypeOfArgument();
837276479Sdim
838276479Sdim  for (ExplodedNodeSet::iterator I = CheckedSet.begin(), E = CheckedSet.end();
839276479Sdim       I != E; ++I) {
840276479Sdim    if (Ex->getKind() == UETT_SizeOf) {
841276479Sdim      if (!T->isIncompleteType() && !T->isConstantSizeType()) {
842276479Sdim        assert(T->isVariableArrayType() && "Unknown non-constant-sized type.");
843296417Sdim
844276479Sdim        // FIXME: Add support for VLA type arguments and VLA expressions.
845276479Sdim        // When that happens, we should probably refactor VLASizeChecker's code.
846276479Sdim        continue;
847276479Sdim      } else if (T->getAs<ObjCObjectType>()) {
848276479Sdim        // Some code tries to take the sizeof an ObjCObjectType, relying that
849276479Sdim        // the compiler has laid out its representation.  Just report Unknown
850276479Sdim        // for these.
851276479Sdim        continue;
852276479Sdim      }
853226586Sdim    }
854296417Sdim
855276479Sdim    APSInt Value = Ex->EvaluateKnownConstInt(getContext());
856276479Sdim    CharUnits amt = CharUnits::fromQuantity(Value.getZExtValue());
857296417Sdim
858276479Sdim    ProgramStateRef state = (*I)->getState();
859276479Sdim    state = state->BindExpr(Ex, (*I)->getLocationContext(),
860276479Sdim                            svalBuilder.makeIntVal(amt.getQuantity(),
861276479Sdim                                                   Ex->getType()));
862276479Sdim    Bldr.generateNode(Ex, *I, state);
863226586Sdim  }
864276479Sdim
865276479Sdim  getCheckerManager().runCheckersForPostStmt(Dst, EvalSet, Ex, *this);
866226586Sdim}
867226586Sdim
868314564Sdimvoid ExprEngine::handleUOExtension(ExplodedNodeSet::iterator I,
869314564Sdim                                   const UnaryOperator *U,
870314564Sdim                                   StmtNodeBuilder &Bldr) {
871314564Sdim  // FIXME: We can probably just have some magic in Environment::getSVal()
872314564Sdim  // that propagates values, instead of creating a new node here.
873314564Sdim  //
874314564Sdim  // Unary "+" is a no-op, similar to a parentheses.  We still have places
875314564Sdim  // where it may be a block-level expression, so we need to
876314564Sdim  // generate an extra node that just propagates the value of the
877314564Sdim  // subexpression.
878314564Sdim  const Expr *Ex = U->getSubExpr()->IgnoreParens();
879314564Sdim  ProgramStateRef state = (*I)->getState();
880314564Sdim  const LocationContext *LCtx = (*I)->getLocationContext();
881314564Sdim  Bldr.generateNode(U, *I, state->BindExpr(U, LCtx,
882314564Sdim                                           state->getSVal(Ex, LCtx)));
883314564Sdim}
884314564Sdim
885314564Sdimvoid ExprEngine::VisitUnaryOperator(const UnaryOperator* U, ExplodedNode *Pred,
886234353Sdim                                    ExplodedNodeSet &Dst) {
887261991Sdim  // FIXME: Prechecks eventually go in ::Visit().
888261991Sdim  ExplodedNodeSet CheckedSet;
889261991Sdim  getCheckerManager().runCheckersForPreStmt(CheckedSet, Pred, U, *this);
890261991Sdim
891261991Sdim  ExplodedNodeSet EvalSet;
892261991Sdim  StmtNodeBuilder Bldr(CheckedSet, EvalSet, *currBldrCtx);
893261991Sdim
894261991Sdim  for (ExplodedNodeSet::iterator I = CheckedSet.begin(), E = CheckedSet.end();
895261991Sdim       I != E; ++I) {
896261991Sdim    switch (U->getOpcode()) {
897234353Sdim    default: {
898261991Sdim      Bldr.takeNodes(*I);
899234353Sdim      ExplodedNodeSet Tmp;
900261991Sdim      VisitIncrementDecrementOperator(U, *I, Tmp);
901234353Sdim      Bldr.addNodes(Tmp);
902261991Sdim      break;
903234353Sdim    }
904226586Sdim    case UO_Real: {
905226586Sdim      const Expr *Ex = U->getSubExpr()->IgnoreParens();
906296417Sdim
907234353Sdim      // FIXME: We don't have complex SValues yet.
908234353Sdim      if (Ex->getType()->isAnyComplexType()) {
909234353Sdim        // Just report "Unknown."
910234353Sdim        break;
911234353Sdim      }
912296417Sdim
913234353Sdim      // For all other types, UO_Real is an identity operation.
914234353Sdim      assert (U->getType() == Ex->getType());
915261991Sdim      ProgramStateRef state = (*I)->getState();
916261991Sdim      const LocationContext *LCtx = (*I)->getLocationContext();
917261991Sdim      Bldr.generateNode(U, *I, state->BindExpr(U, LCtx,
918261991Sdim                                               state->getSVal(Ex, LCtx)));
919234353Sdim      break;
920226586Sdim    }
921296417Sdim
922296417Sdim    case UO_Imag: {
923226586Sdim      const Expr *Ex = U->getSubExpr()->IgnoreParens();
924234353Sdim      // FIXME: We don't have complex SValues yet.
925234353Sdim      if (Ex->getType()->isAnyComplexType()) {
926234353Sdim        // Just report "Unknown."
927234353Sdim        break;
928226586Sdim      }
929234353Sdim      // For all other types, UO_Imag returns 0.
930261991Sdim      ProgramStateRef state = (*I)->getState();
931261991Sdim      const LocationContext *LCtx = (*I)->getLocationContext();
932234353Sdim      SVal X = svalBuilder.makeZeroVal(Ex->getType());
933261991Sdim      Bldr.generateNode(U, *I, state->BindExpr(U, LCtx, X));
934234353Sdim      break;
935226586Sdim    }
936296417Sdim
937314564Sdim    case UO_AddrOf: {
938314564Sdim      // Process pointer-to-member address operation.
939314564Sdim      const Expr *Ex = U->getSubExpr()->IgnoreParens();
940314564Sdim      if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Ex)) {
941314564Sdim        const ValueDecl *VD = DRE->getDecl();
942314564Sdim
943314564Sdim        if (isa<CXXMethodDecl>(VD) || isa<FieldDecl>(VD)) {
944314564Sdim          ProgramStateRef State = (*I)->getState();
945314564Sdim          const LocationContext *LCtx = (*I)->getLocationContext();
946314564Sdim          SVal SV = svalBuilder.getMemberPointer(cast<DeclaratorDecl>(VD));
947314564Sdim          Bldr.generateNode(U, *I, State->BindExpr(U, LCtx, SV));
948314564Sdim          break;
949314564Sdim        }
950314564Sdim      }
951314564Sdim      // Explicitly proceed with default handler for this case cascade.
952314564Sdim      handleUOExtension(I, U, Bldr);
953314564Sdim      break;
954314564Sdim    }
955226586Sdim    case UO_Plus:
956239462Sdim      assert(!U->isGLValue());
957226586Sdim      // FALL-THROUGH.
958226586Sdim    case UO_Deref:
959226586Sdim    case UO_Extension: {
960314564Sdim      handleUOExtension(I, U, Bldr);
961234353Sdim      break;
962226586Sdim    }
963296417Sdim
964226586Sdim    case UO_LNot:
965226586Sdim    case UO_Minus:
966226586Sdim    case UO_Not: {
967239462Sdim      assert (!U->isGLValue());
968226586Sdim      const Expr *Ex = U->getSubExpr()->IgnoreParens();
969261991Sdim      ProgramStateRef state = (*I)->getState();
970261991Sdim      const LocationContext *LCtx = (*I)->getLocationContext();
971296417Sdim
972234353Sdim      // Get the value of the subexpression.
973234353Sdim      SVal V = state->getSVal(Ex, LCtx);
974296417Sdim
975234353Sdim      if (V.isUnknownOrUndef()) {
976261991Sdim        Bldr.generateNode(U, *I, state->BindExpr(U, LCtx, V));
977234353Sdim        break;
978234353Sdim      }
979296417Sdim
980234353Sdim      switch (U->getOpcode()) {
981234353Sdim        default:
982234353Sdim          llvm_unreachable("Invalid Opcode.");
983234353Sdim        case UO_Not:
984234353Sdim          // FIXME: Do we need to handle promotions?
985249423Sdim          state = state->BindExpr(U, LCtx, evalComplement(V.castAs<NonLoc>()));
986234353Sdim          break;
987234353Sdim        case UO_Minus:
988234353Sdim          // FIXME: Do we need to handle promotions?
989249423Sdim          state = state->BindExpr(U, LCtx, evalMinus(V.castAs<NonLoc>()));
990234353Sdim          break;
991234353Sdim        case UO_LNot:
992234353Sdim          // C99 6.5.3.3: "The expression !E is equivalent to (0==E)."
993234353Sdim          //
994234353Sdim          //  Note: technically we do "E == 0", but this is the same in the
995234353Sdim          //    transfer functions as "0 == E".
996296417Sdim          SVal Result;
997249423Sdim          if (Optional<Loc> LV = V.getAs<Loc>()) {
998321369Sdim            Loc X = svalBuilder.makeNullWithType(Ex->getType());
999249423Sdim            Result = evalBinOp(state, BO_EQ, *LV, X, U->getType());
1000321369Sdim          } else if (Ex->getType()->isFloatingType()) {
1001249423Sdim            // FIXME: handle floating point types.
1002249423Sdim            Result = UnknownVal();
1003249423Sdim          } else {
1004234353Sdim            nonloc::ConcreteInt X(getBasicVals().getValue(0, Ex->getType()));
1005249423Sdim            Result = evalBinOp(state, BO_EQ, V.castAs<NonLoc>(), X,
1006234353Sdim                               U->getType());
1007234353Sdim          }
1008296417Sdim
1009296417Sdim          state = state->BindExpr(U, LCtx, Result);
1010234353Sdim          break;
1011226586Sdim      }
1012261991Sdim      Bldr.generateNode(U, *I, state);
1013234353Sdim      break;
1014226586Sdim    }
1015261991Sdim    }
1016226586Sdim  }
1017234353Sdim
1018261991Sdim  getCheckerManager().runCheckersForPostStmt(Dst, EvalSet, U, *this);
1019234353Sdim}
1020234353Sdim
1021234353Sdimvoid ExprEngine::VisitIncrementDecrementOperator(const UnaryOperator* U,
1022234353Sdim                                                 ExplodedNode *Pred,
1023234353Sdim                                                 ExplodedNodeSet &Dst) {
1024226586Sdim  // Handle ++ and -- (both pre- and post-increment).
1025226586Sdim  assert (U->isIncrementDecrementOp());
1026226586Sdim  const Expr *Ex = U->getSubExpr()->IgnoreParens();
1027296417Sdim
1028234353Sdim  const LocationContext *LCtx = Pred->getLocationContext();
1029234353Sdim  ProgramStateRef state = Pred->getState();
1030234353Sdim  SVal loc = state->getSVal(Ex, LCtx);
1031296417Sdim
1032234353Sdim  // Perform a load.
1033234353Sdim  ExplodedNodeSet Tmp;
1034234353Sdim  evalLoad(Tmp, U, Ex, Pred, state, loc);
1035296417Sdim
1036234353Sdim  ExplodedNodeSet Dst2;
1037243830Sdim  StmtNodeBuilder Bldr(Tmp, Dst2, *currBldrCtx);
1038234353Sdim  for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end();I!=E;++I) {
1039296417Sdim
1040234353Sdim    state = (*I)->getState();
1041234353Sdim    assert(LCtx == (*I)->getLocationContext());
1042234353Sdim    SVal V2_untested = state->getSVal(Ex, LCtx);
1043296417Sdim
1044234353Sdim    // Propagate unknown and undefined values.
1045234353Sdim    if (V2_untested.isUnknownOrUndef()) {
1046327952Sdim      state = state->BindExpr(U, LCtx, V2_untested);
1047327952Sdim
1048327952Sdim      // Perform the store, so that the uninitialized value detection happens.
1049327952Sdim      Bldr.takeNodes(*I);
1050327952Sdim      ExplodedNodeSet Dst3;
1051327952Sdim      evalStore(Dst3, U, U, *I, state, loc, V2_untested);
1052327952Sdim      Bldr.addNodes(Dst3);
1053327952Sdim
1054234353Sdim      continue;
1055234353Sdim    }
1056249423Sdim    DefinedSVal V2 = V2_untested.castAs<DefinedSVal>();
1057296417Sdim
1058234353Sdim    // Handle all other values.
1059234353Sdim    BinaryOperator::Opcode Op = U->isIncrementOp() ? BO_Add : BO_Sub;
1060296417Sdim
1061234353Sdim    // If the UnaryOperator has non-location type, use its type to create the
1062234353Sdim    // constant value. If the UnaryOperator has location type, create the
1063234353Sdim    // constant with int type and pointer width.
1064234353Sdim    SVal RHS;
1065296417Sdim
1066234353Sdim    if (U->getType()->isAnyPointerType())
1067234353Sdim      RHS = svalBuilder.makeArrayIndex(1);
1068243830Sdim    else if (U->getType()->isIntegralOrEnumerationType())
1069243830Sdim      RHS = svalBuilder.makeIntVal(1, U->getType());
1070234353Sdim    else
1071243830Sdim      RHS = UnknownVal();
1072296417Sdim
1073234353Sdim    SVal Result = evalBinOp(state, Op, V2, RHS, U->getType());
1074296417Sdim
1075234353Sdim    // Conjure a new symbol if necessary to recover precision.
1076234353Sdim    if (Result.isUnknown()){
1077234353Sdim      DefinedOrUnknownSVal SymVal =
1078321369Sdim        svalBuilder.conjureSymbolVal(nullptr, U, LCtx,
1079276479Sdim                                     currBldrCtx->blockCount());
1080234353Sdim      Result = SymVal;
1081296417Sdim
1082234353Sdim      // If the value is a location, ++/-- should always preserve
1083234353Sdim      // non-nullness.  Check if the original value was non-null, and if so
1084234353Sdim      // propagate that constraint.
1085234353Sdim      if (Loc::isLocType(U->getType())) {
1086234353Sdim        DefinedOrUnknownSVal Constraint =
1087234353Sdim        svalBuilder.evalEQ(state, V2,svalBuilder.makeZeroVal(U->getType()));
1088296417Sdim
1089234353Sdim        if (!state->assume(Constraint, true)) {
1090234353Sdim          // It isn't feasible for the original value to be null.
1091234353Sdim          // Propagate this constraint.
1092234353Sdim          Constraint = svalBuilder.evalEQ(state, SymVal,
1093234353Sdim                                       svalBuilder.makeZeroVal(U->getType()));
1094296417Sdim
1095296417Sdim
1096234353Sdim          state = state->assume(Constraint, false);
1097234353Sdim          assert(state);
1098226586Sdim        }
1099226586Sdim      }
1100226586Sdim    }
1101296417Sdim
1102234353Sdim    // Since the lvalue-to-rvalue conversion is explicit in the AST,
1103234353Sdim    // we bind an l-value if the operator is prefix and an lvalue (in C++).
1104239462Sdim    if (U->isGLValue())
1105234353Sdim      state = state->BindExpr(U, LCtx, loc);
1106234353Sdim    else
1107234353Sdim      state = state->BindExpr(U, LCtx, U->isPostfix() ? V2 : Result);
1108296417Sdim
1109234353Sdim    // Perform the store.
1110234353Sdim    Bldr.takeNodes(*I);
1111234353Sdim    ExplodedNodeSet Dst3;
1112234353Sdim    evalStore(Dst3, U, U, *I, state, loc, Result);
1113234353Sdim    Bldr.addNodes(Dst3);
1114226586Sdim  }
1115234353Sdim  Dst.insert(Dst2);
1116226586Sdim}
1117