ExprEngineC.cpp revision 276479
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"
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
22226586Sdimvoid ExprEngine::VisitBinaryOperator(const BinaryOperator* B,
23226586Sdim                                     ExplodedNode *Pred,
24226586Sdim                                     ExplodedNodeSet &Dst) {
25226586Sdim
26226586Sdim  Expr *LHS = B->getLHS()->IgnoreParens();
27226586Sdim  Expr *RHS = B->getRHS()->IgnoreParens();
28226586Sdim
29226586Sdim  // FIXME: Prechecks eventually go in ::Visit().
30226586Sdim  ExplodedNodeSet CheckedSet;
31226586Sdim  ExplodedNodeSet Tmp2;
32226586Sdim  getCheckerManager().runCheckersForPreStmt(CheckedSet, Pred, B, *this);
33226586Sdim
34226586Sdim  // With both the LHS and RHS evaluated, process the operation itself.
35226586Sdim  for (ExplodedNodeSet::iterator it=CheckedSet.begin(), ei=CheckedSet.end();
36226586Sdim         it != ei; ++it) {
37226586Sdim
38234353Sdim    ProgramStateRef state = (*it)->getState();
39234353Sdim    const LocationContext *LCtx = (*it)->getLocationContext();
40234353Sdim    SVal LeftV = state->getSVal(LHS, LCtx);
41234353Sdim    SVal RightV = state->getSVal(RHS, LCtx);
42226586Sdim
43226586Sdim    BinaryOperator::Opcode Op = B->getOpcode();
44226586Sdim
45226586Sdim    if (Op == BO_Assign) {
46226586Sdim      // EXPERIMENTAL: "Conjured" symbols.
47226586Sdim      // FIXME: Handle structs.
48234353Sdim      if (RightV.isUnknown()) {
49243830Sdim        unsigned Count = currBldrCtx->blockCount();
50276479Sdim        RightV = svalBuilder.conjureSymbolVal(nullptr, B->getRHS(), LCtx,
51276479Sdim                                              Count);
52226586Sdim      }
53226586Sdim      // Simulate the effects of a "store":  bind the value of the RHS
54226586Sdim      // to the L-Value represented by the LHS.
55239462Sdim      SVal ExprVal = B->isGLValue() ? LeftV : RightV;
56234353Sdim      evalStore(Tmp2, B, LHS, *it, state->BindExpr(B, LCtx, ExprVal),
57234353Sdim                LeftV, RightV);
58226586Sdim      continue;
59226586Sdim    }
60226586Sdim
61226586Sdim    if (!B->isAssignmentOp()) {
62243830Sdim      StmtNodeBuilder Bldr(*it, Tmp2, *currBldrCtx);
63239462Sdim
64239462Sdim      if (B->isAdditiveOp()) {
65239462Sdim        // If one of the operands is a location, conjure a symbol for the other
66239462Sdim        // one (offset) if it's unknown so that memory arithmetic always
67239462Sdim        // results in an ElementRegion.
68239462Sdim        // TODO: This can be removed after we enable history tracking with
69239462Sdim        // SymSymExpr.
70243830Sdim        unsigned Count = currBldrCtx->blockCount();
71249423Sdim        if (LeftV.getAs<Loc>() &&
72251662Sdim            RHS->getType()->isIntegralOrEnumerationType() &&
73251662Sdim            RightV.isUnknown()) {
74243830Sdim          RightV = svalBuilder.conjureSymbolVal(RHS, LCtx, RHS->getType(),
75243830Sdim                                                Count);
76239462Sdim        }
77249423Sdim        if (RightV.getAs<Loc>() &&
78251662Sdim            LHS->getType()->isIntegralOrEnumerationType() &&
79251662Sdim            LeftV.isUnknown()) {
80243830Sdim          LeftV = svalBuilder.conjureSymbolVal(LHS, LCtx, LHS->getType(),
81243830Sdim                                               Count);
82239462Sdim        }
83239462Sdim      }
84239462Sdim
85276479Sdim      // Although we don't yet model pointers-to-members, we do need to make
86276479Sdim      // sure that the members of temporaries have a valid 'this' pointer for
87276479Sdim      // other checks.
88276479Sdim      if (B->getOpcode() == BO_PtrMemD)
89276479Sdim        state = createTemporaryRegionIfNeeded(state, LCtx, LHS);
90276479Sdim
91226586Sdim      // Process non-assignments except commas or short-circuited
92226586Sdim      // logical expressions (LAnd and LOr).
93226586Sdim      SVal Result = evalBinOp(state, Op, LeftV, RightV, B->getType());
94226586Sdim      if (Result.isUnknown()) {
95234353Sdim        Bldr.generateNode(B, *it, state);
96226586Sdim        continue;
97226586Sdim      }
98226586Sdim
99234353Sdim      state = state->BindExpr(B, LCtx, Result);
100234353Sdim      Bldr.generateNode(B, *it, state);
101226586Sdim      continue;
102226586Sdim    }
103226586Sdim
104226586Sdim    assert (B->isCompoundAssignmentOp());
105226586Sdim
106226586Sdim    switch (Op) {
107226586Sdim      default:
108226586Sdim        llvm_unreachable("Invalid opcode for compound assignment.");
109226586Sdim      case BO_MulAssign: Op = BO_Mul; break;
110226586Sdim      case BO_DivAssign: Op = BO_Div; break;
111226586Sdim      case BO_RemAssign: Op = BO_Rem; break;
112226586Sdim      case BO_AddAssign: Op = BO_Add; break;
113226586Sdim      case BO_SubAssign: Op = BO_Sub; break;
114226586Sdim      case BO_ShlAssign: Op = BO_Shl; break;
115226586Sdim      case BO_ShrAssign: Op = BO_Shr; break;
116226586Sdim      case BO_AndAssign: Op = BO_And; break;
117226586Sdim      case BO_XorAssign: Op = BO_Xor; break;
118226586Sdim      case BO_OrAssign:  Op = BO_Or;  break;
119226586Sdim    }
120226586Sdim
121226586Sdim    // Perform a load (the LHS).  This performs the checks for
122226586Sdim    // null dereferences, and so on.
123226586Sdim    ExplodedNodeSet Tmp;
124226586Sdim    SVal location = LeftV;
125234353Sdim    evalLoad(Tmp, B, LHS, *it, state, location);
126226586Sdim
127226586Sdim    for (ExplodedNodeSet::iterator I = Tmp.begin(), E = Tmp.end(); I != E;
128226586Sdim         ++I) {
129226586Sdim
130226586Sdim      state = (*I)->getState();
131234353Sdim      const LocationContext *LCtx = (*I)->getLocationContext();
132234353Sdim      SVal V = state->getSVal(LHS, LCtx);
133226586Sdim
134226586Sdim      // Get the computation type.
135226586Sdim      QualType CTy =
136226586Sdim        cast<CompoundAssignOperator>(B)->getComputationResultType();
137226586Sdim      CTy = getContext().getCanonicalType(CTy);
138226586Sdim
139226586Sdim      QualType CLHSTy =
140226586Sdim        cast<CompoundAssignOperator>(B)->getComputationLHSType();
141226586Sdim      CLHSTy = getContext().getCanonicalType(CLHSTy);
142226586Sdim
143226586Sdim      QualType LTy = getContext().getCanonicalType(LHS->getType());
144226586Sdim
145226586Sdim      // Promote LHS.
146226586Sdim      V = svalBuilder.evalCast(V, CLHSTy, LTy);
147226586Sdim
148226586Sdim      // Compute the result of the operation.
149226586Sdim      SVal Result = svalBuilder.evalCast(evalBinOp(state, Op, V, RightV, CTy),
150226586Sdim                                         B->getType(), CTy);
151226586Sdim
152226586Sdim      // EXPERIMENTAL: "Conjured" symbols.
153226586Sdim      // FIXME: Handle structs.
154226586Sdim
155226586Sdim      SVal LHSVal;
156226586Sdim
157234353Sdim      if (Result.isUnknown()) {
158226586Sdim        // The symbolic value is actually for the type of the left-hand side
159226586Sdim        // expression, not the computation type, as this is the value the
160226586Sdim        // LValue on the LHS will bind to.
161276479Sdim        LHSVal = svalBuilder.conjureSymbolVal(nullptr, B->getRHS(), LCtx, LTy,
162243830Sdim                                              currBldrCtx->blockCount());
163226586Sdim        // However, we need to convert the symbol to the computation type.
164226586Sdim        Result = svalBuilder.evalCast(LHSVal, CTy, LTy);
165226586Sdim      }
166226586Sdim      else {
167226586Sdim        // The left-hand side may bind to a different value then the
168226586Sdim        // computation type.
169226586Sdim        LHSVal = svalBuilder.evalCast(Result, LTy, CTy);
170226586Sdim      }
171226586Sdim
172226586Sdim      // In C++, assignment and compound assignment operators return an
173226586Sdim      // lvalue.
174239462Sdim      if (B->isGLValue())
175234353Sdim        state = state->BindExpr(B, LCtx, location);
176226586Sdim      else
177234353Sdim        state = state->BindExpr(B, LCtx, Result);
178226586Sdim
179226586Sdim      evalStore(Tmp2, B, LHS, *I, state, location, LHSVal);
180226586Sdim    }
181226586Sdim  }
182226586Sdim
183226586Sdim  // FIXME: postvisits eventually go in ::Visit()
184226586Sdim  getCheckerManager().runCheckersForPostStmt(Dst, Tmp2, B, *this);
185226586Sdim}
186226586Sdim
187226586Sdimvoid ExprEngine::VisitBlockExpr(const BlockExpr *BE, ExplodedNode *Pred,
188226586Sdim                                ExplodedNodeSet &Dst) {
189226586Sdim
190226586Sdim  CanQualType T = getContext().getCanonicalType(BE->getType());
191239462Sdim
192239462Sdim  // Get the value of the block itself.
193226586Sdim  SVal V = svalBuilder.getBlockPointer(BE->getBlockDecl(), T,
194261991Sdim                                       Pred->getLocationContext(),
195261991Sdim                                       currBldrCtx->blockCount());
196226586Sdim
197239462Sdim  ProgramStateRef State = Pred->getState();
198239462Sdim
199239462Sdim  // If we created a new MemRegion for the block, we should explicitly bind
200239462Sdim  // the captured variables.
201239462Sdim  if (const BlockDataRegion *BDR =
202239462Sdim      dyn_cast_or_null<BlockDataRegion>(V.getAsRegion())) {
203239462Sdim
204239462Sdim    BlockDataRegion::referenced_vars_iterator I = BDR->referenced_vars_begin(),
205239462Sdim                                              E = BDR->referenced_vars_end();
206239462Sdim
207239462Sdim    for (; I != E; ++I) {
208239462Sdim      const MemRegion *capturedR = I.getCapturedRegion();
209239462Sdim      const MemRegion *originalR = I.getOriginalRegion();
210239462Sdim      if (capturedR != originalR) {
211239462Sdim        SVal originalV = State->getSVal(loc::MemRegionVal(originalR));
212239462Sdim        State = State->bindLoc(loc::MemRegionVal(capturedR), originalV);
213239462Sdim      }
214239462Sdim    }
215239462Sdim  }
216239462Sdim
217226586Sdim  ExplodedNodeSet Tmp;
218243830Sdim  StmtNodeBuilder Bldr(Pred, Tmp, *currBldrCtx);
219234353Sdim  Bldr.generateNode(BE, Pred,
220239462Sdim                    State->BindExpr(BE, Pred->getLocationContext(), V),
221276479Sdim                    nullptr, ProgramPoint::PostLValueKind);
222276479Sdim
223226586Sdim  // FIXME: Move all post/pre visits to ::Visit().
224226586Sdim  getCheckerManager().runCheckersForPostStmt(Dst, Tmp, BE, *this);
225226586Sdim}
226226586Sdim
227226586Sdimvoid ExprEngine::VisitCast(const CastExpr *CastE, const Expr *Ex,
228226586Sdim                           ExplodedNode *Pred, ExplodedNodeSet &Dst) {
229226586Sdim
230226586Sdim  ExplodedNodeSet dstPreStmt;
231226586Sdim  getCheckerManager().runCheckersForPreStmt(dstPreStmt, Pred, CastE, *this);
232226586Sdim
233234353Sdim  if (CastE->getCastKind() == CK_LValueToRValue) {
234226586Sdim    for (ExplodedNodeSet::iterator I = dstPreStmt.begin(), E = dstPreStmt.end();
235226586Sdim         I!=E; ++I) {
236226586Sdim      ExplodedNode *subExprNode = *I;
237234353Sdim      ProgramStateRef state = subExprNode->getState();
238234353Sdim      const LocationContext *LCtx = subExprNode->getLocationContext();
239234353Sdim      evalLoad(Dst, CastE, CastE, subExprNode, state, state->getSVal(Ex, LCtx));
240226586Sdim    }
241226586Sdim    return;
242226586Sdim  }
243226586Sdim
244226586Sdim  // All other casts.
245226586Sdim  QualType T = CastE->getType();
246226586Sdim  QualType ExTy = Ex->getType();
247226586Sdim
248226586Sdim  if (const ExplicitCastExpr *ExCast=dyn_cast_or_null<ExplicitCastExpr>(CastE))
249226586Sdim    T = ExCast->getTypeAsWritten();
250226586Sdim
251243830Sdim  StmtNodeBuilder Bldr(dstPreStmt, Dst, *currBldrCtx);
252226586Sdim  for (ExplodedNodeSet::iterator I = dstPreStmt.begin(), E = dstPreStmt.end();
253226586Sdim       I != E; ++I) {
254226586Sdim
255226586Sdim    Pred = *I;
256243830Sdim    ProgramStateRef state = Pred->getState();
257243830Sdim    const LocationContext *LCtx = Pred->getLocationContext();
258243830Sdim
259226586Sdim    switch (CastE->getCastKind()) {
260226586Sdim      case CK_LValueToRValue:
261226586Sdim        llvm_unreachable("LValueToRValue casts handled earlier.");
262226586Sdim      case CK_ToVoid:
263226586Sdim        continue;
264226586Sdim        // The analyzer doesn't do anything special with these casts,
265226586Sdim        // since it understands retain/release semantics already.
266226586Sdim      case CK_ARCProduceObject:
267226586Sdim      case CK_ARCConsumeObject:
268226586Sdim      case CK_ARCReclaimReturnedObject:
269226586Sdim      case CK_ARCExtendBlockObject: // Fall-through.
270234353Sdim      case CK_CopyAndAutoreleaseBlockObject:
271234353Sdim        // The analyser can ignore atomic casts for now, although some future
272234353Sdim        // checkers may want to make certain that you're not modifying the same
273234353Sdim        // value through atomic and nonatomic pointers.
274234353Sdim      case CK_AtomicToNonAtomic:
275234353Sdim      case CK_NonAtomicToAtomic:
276226586Sdim        // True no-ops.
277226586Sdim      case CK_NoOp:
278243830Sdim      case CK_ConstructorConversion:
279243830Sdim      case CK_UserDefinedConversion:
280243830Sdim      case CK_FunctionToPointerDecay:
281243830Sdim      case CK_BuiltinFnToFnPtr: {
282226586Sdim        // Copy the SVal of Ex to CastE.
283234353Sdim        ProgramStateRef state = Pred->getState();
284234353Sdim        const LocationContext *LCtx = Pred->getLocationContext();
285234353Sdim        SVal V = state->getSVal(Ex, LCtx);
286234353Sdim        state = state->BindExpr(CastE, LCtx, V);
287234353Sdim        Bldr.generateNode(CastE, Pred, state);
288226586Sdim        continue;
289226586Sdim      }
290243830Sdim      case CK_MemberPointerToBoolean:
291243830Sdim        // FIXME: For now, member pointers are represented by void *.
292243830Sdim        // FALLTHROUGH
293226586Sdim      case CK_Dependent:
294226586Sdim      case CK_ArrayToPointerDecay:
295226586Sdim      case CK_BitCast:
296276479Sdim      case CK_AddressSpaceConversion:
297226586Sdim      case CK_IntegralCast:
298226586Sdim      case CK_NullToPointer:
299226586Sdim      case CK_IntegralToPointer:
300226586Sdim      case CK_PointerToIntegral:
301226586Sdim      case CK_PointerToBoolean:
302226586Sdim      case CK_IntegralToBoolean:
303226586Sdim      case CK_IntegralToFloating:
304226586Sdim      case CK_FloatingToIntegral:
305226586Sdim      case CK_FloatingToBoolean:
306226586Sdim      case CK_FloatingCast:
307226586Sdim      case CK_FloatingRealToComplex:
308226586Sdim      case CK_FloatingComplexToReal:
309226586Sdim      case CK_FloatingComplexToBoolean:
310226586Sdim      case CK_FloatingComplexCast:
311226586Sdim      case CK_FloatingComplexToIntegralComplex:
312226586Sdim      case CK_IntegralRealToComplex:
313226586Sdim      case CK_IntegralComplexToReal:
314226586Sdim      case CK_IntegralComplexToBoolean:
315226586Sdim      case CK_IntegralComplexCast:
316226586Sdim      case CK_IntegralComplexToFloatingComplex:
317226586Sdim      case CK_CPointerToObjCPointerCast:
318226586Sdim      case CK_BlockPointerToObjCPointerCast:
319226586Sdim      case CK_AnyPointerToBlockPointerCast:
320249423Sdim      case CK_ObjCObjectLValueCast:
321261991Sdim      case CK_ZeroToOCLEvent:
322261991Sdim      case CK_LValueBitCast: {
323226586Sdim        // Delegate to SValBuilder to process.
324234353Sdim        SVal V = state->getSVal(Ex, LCtx);
325226586Sdim        V = svalBuilder.evalCast(V, T, ExTy);
326234353Sdim        state = state->BindExpr(CastE, LCtx, V);
327234353Sdim        Bldr.generateNode(CastE, Pred, state);
328226586Sdim        continue;
329226586Sdim      }
330226586Sdim      case CK_DerivedToBase:
331226586Sdim      case CK_UncheckedDerivedToBase: {
332226586Sdim        // For DerivedToBase cast, delegate to the store manager.
333234353Sdim        SVal val = state->getSVal(Ex, LCtx);
334239462Sdim        val = getStoreManager().evalDerivedToBase(val, CastE);
335234353Sdim        state = state->BindExpr(CastE, LCtx, val);
336234353Sdim        Bldr.generateNode(CastE, Pred, state);
337226586Sdim        continue;
338226586Sdim      }
339234353Sdim      // Handle C++ dyn_cast.
340234353Sdim      case CK_Dynamic: {
341234353Sdim        SVal val = state->getSVal(Ex, LCtx);
342234353Sdim
343234353Sdim        // Compute the type of the result.
344234353Sdim        QualType resultType = CastE->getType();
345239462Sdim        if (CastE->isGLValue())
346234353Sdim          resultType = getContext().getPointerType(resultType);
347234353Sdim
348234353Sdim        bool Failed = false;
349234353Sdim
350234353Sdim        // Check if the value being cast evaluates to 0.
351234353Sdim        if (val.isZeroConstant())
352234353Sdim          Failed = true;
353234353Sdim        // Else, evaluate the cast.
354234353Sdim        else
355234353Sdim          val = getStoreManager().evalDynamicCast(val, T, Failed);
356234353Sdim
357234353Sdim        if (Failed) {
358234353Sdim          if (T->isReferenceType()) {
359234353Sdim            // A bad_cast exception is thrown if input value is a reference.
360234353Sdim            // Currently, we model this, by generating a sink.
361243830Sdim            Bldr.generateSink(CastE, Pred, state);
362234353Sdim            continue;
363234353Sdim          } else {
364234353Sdim            // If the cast fails on a pointer, bind to 0.
365234353Sdim            state = state->BindExpr(CastE, LCtx, svalBuilder.makeNull());
366234353Sdim          }
367234353Sdim        } else {
368234353Sdim          // If we don't know if the cast succeeded, conjure a new symbol.
369234353Sdim          if (val.isUnknown()) {
370243830Sdim            DefinedOrUnknownSVal NewSym =
371276479Sdim              svalBuilder.conjureSymbolVal(nullptr, CastE, LCtx, resultType,
372243830Sdim                                           currBldrCtx->blockCount());
373234353Sdim            state = state->BindExpr(CastE, LCtx, NewSym);
374234353Sdim          } else
375234353Sdim            // Else, bind to the derived region value.
376234353Sdim            state = state->BindExpr(CastE, LCtx, val);
377234353Sdim        }
378234353Sdim        Bldr.generateNode(CastE, Pred, state);
379234353Sdim        continue;
380234353Sdim      }
381243830Sdim      case CK_NullToMemberPointer: {
382243830Sdim        // FIXME: For now, member pointers are represented by void *.
383261991Sdim        SVal V = svalBuilder.makeNull();
384243830Sdim        state = state->BindExpr(CastE, LCtx, V);
385243830Sdim        Bldr.generateNode(CastE, Pred, state);
386243830Sdim        continue;
387243830Sdim      }
388234353Sdim      // Various C++ casts that are not handled yet.
389226586Sdim      case CK_ToUnion:
390226586Sdim      case CK_BaseToDerived:
391226586Sdim      case CK_BaseToDerivedMemberPointer:
392226586Sdim      case CK_DerivedToBaseMemberPointer:
393234353Sdim      case CK_ReinterpretMemberPointer:
394261991Sdim      case CK_VectorSplat: {
395226586Sdim        // Recover some path-sensitivty by conjuring a new value.
396226586Sdim        QualType resultType = CastE->getType();
397239462Sdim        if (CastE->isGLValue())
398226586Sdim          resultType = getContext().getPointerType(resultType);
399276479Sdim        SVal result = svalBuilder.conjureSymbolVal(nullptr, CastE, LCtx,
400243830Sdim                                                   resultType,
401243830Sdim                                                   currBldrCtx->blockCount());
402243830Sdim        state = state->BindExpr(CastE, LCtx, result);
403234353Sdim        Bldr.generateNode(CastE, Pred, state);
404226586Sdim        continue;
405226586Sdim      }
406226586Sdim    }
407226586Sdim  }
408226586Sdim}
409226586Sdim
410226586Sdimvoid ExprEngine::VisitCompoundLiteralExpr(const CompoundLiteralExpr *CL,
411226586Sdim                                          ExplodedNode *Pred,
412226586Sdim                                          ExplodedNodeSet &Dst) {
413243830Sdim  StmtNodeBuilder B(Pred, Dst, *currBldrCtx);
414234353Sdim
415251662Sdim  ProgramStateRef State = Pred->getState();
416251662Sdim  const LocationContext *LCtx = Pred->getLocationContext();
417251662Sdim
418251662Sdim  const Expr *Init = CL->getInitializer();
419251662Sdim  SVal V = State->getSVal(CL->getInitializer(), LCtx);
420226586Sdim
421251662Sdim  if (isa<CXXConstructExpr>(Init)) {
422251662Sdim    // No work needed. Just pass the value up to this expression.
423251662Sdim  } else {
424251662Sdim    assert(isa<InitListExpr>(Init));
425251662Sdim    Loc CLLoc = State->getLValue(CL, LCtx);
426251662Sdim    State = State->bindLoc(CLLoc, V);
427239462Sdim
428251662Sdim    // Compound literal expressions are a GNU extension in C++.
429251662Sdim    // Unlike in C, where CLs are lvalues, in C++ CLs are prvalues,
430251662Sdim    // and like temporary objects created by the functional notation T()
431251662Sdim    // CLs are destroyed at the end of the containing full-expression.
432251662Sdim    // HOWEVER, an rvalue of array type is not something the analyzer can
433251662Sdim    // reason about, since we expect all regions to be wrapped in Locs.
434251662Sdim    // So we treat array CLs as lvalues as well, knowing that they will decay
435251662Sdim    // to pointers as soon as they are used.
436251662Sdim    if (CL->isGLValue() || CL->getType()->isArrayType())
437251662Sdim      V = CLLoc;
438251662Sdim  }
439251662Sdim
440251662Sdim  B.generateNode(CL, Pred, State->BindExpr(CL, LCtx, V));
441226586Sdim}
442226586Sdim
443226586Sdimvoid ExprEngine::VisitDeclStmt(const DeclStmt *DS, ExplodedNode *Pred,
444226586Sdim                               ExplodedNodeSet &Dst) {
445226586Sdim  // Assumption: The CFG has one DeclStmt per Decl.
446249423Sdim  const VarDecl *VD = dyn_cast_or_null<VarDecl>(*DS->decl_begin());
447249423Sdim
448249423Sdim  if (!VD) {
449234353Sdim    //TODO:AZ: remove explicit insertion after refactoring is done.
450234353Sdim    Dst.insert(Pred);
451226586Sdim    return;
452234353Sdim  }
453226586Sdim
454226586Sdim  // FIXME: all pre/post visits should eventually be handled by ::Visit().
455226586Sdim  ExplodedNodeSet dstPreVisit;
456226586Sdim  getCheckerManager().runCheckersForPreStmt(dstPreVisit, Pred, DS, *this);
457226586Sdim
458261991Sdim  ExplodedNodeSet dstEvaluated;
459261991Sdim  StmtNodeBuilder B(dstPreVisit, dstEvaluated, *currBldrCtx);
460226586Sdim  for (ExplodedNodeSet::iterator I = dstPreVisit.begin(), E = dstPreVisit.end();
461226586Sdim       I!=E; ++I) {
462226586Sdim    ExplodedNode *N = *I;
463234353Sdim    ProgramStateRef state = N->getState();
464249423Sdim    const LocationContext *LC = N->getLocationContext();
465249423Sdim
466226586Sdim    // Decls without InitExpr are not initialized explicitly.
467226586Sdim    if (const Expr *InitEx = VD->getInit()) {
468249423Sdim
469249423Sdim      // Note in the state that the initialization has occurred.
470249423Sdim      ExplodedNode *UpdatedN = N;
471239462Sdim      SVal InitVal = state->getSVal(InitEx, LC);
472234353Sdim
473249423Sdim      if (isa<CXXConstructExpr>(InitEx->IgnoreImplicit())) {
474239462Sdim        // We constructed the object directly in the variable.
475239462Sdim        // No need to bind anything.
476249423Sdim        B.generateNode(DS, UpdatedN, state);
477239462Sdim      } else {
478239462Sdim        // We bound the temp obj region to the CXXConstructExpr. Now recover
479239462Sdim        // the lazy compound value when the variable is not a reference.
480249423Sdim        if (AMgr.getLangOpts().CPlusPlus && VD->getType()->isRecordType() &&
481249423Sdim            !VD->getType()->isReferenceType()) {
482249423Sdim          if (Optional<loc::MemRegionVal> M =
483249423Sdim                  InitVal.getAs<loc::MemRegionVal>()) {
484249423Sdim            InitVal = state->getSVal(M->getRegion());
485249423Sdim            assert(InitVal.getAs<nonloc::LazyCompoundVal>());
486249423Sdim          }
487239462Sdim        }
488239462Sdim
489239462Sdim        // Recover some path-sensitivity if a scalar value evaluated to
490239462Sdim        // UnknownVal.
491239462Sdim        if (InitVal.isUnknown()) {
492239462Sdim          QualType Ty = InitEx->getType();
493239462Sdim          if (InitEx->isGLValue()) {
494239462Sdim            Ty = getContext().getPointerType(Ty);
495239462Sdim          }
496239462Sdim
497276479Sdim          InitVal = svalBuilder.conjureSymbolVal(nullptr, InitEx, LC, Ty,
498243830Sdim                                                 currBldrCtx->blockCount());
499239462Sdim        }
500249423Sdim
501249423Sdim
502249423Sdim        B.takeNodes(UpdatedN);
503239462Sdim        ExplodedNodeSet Dst2;
504249423Sdim        evalBind(Dst2, DS, UpdatedN, state->getLValue(VD, LC), InitVal, true);
505239462Sdim        B.addNodes(Dst2);
506226586Sdim      }
507226586Sdim    }
508226586Sdim    else {
509243830Sdim      B.generateNode(DS, N, state);
510226586Sdim    }
511226586Sdim  }
512261991Sdim
513261991Sdim  getCheckerManager().runCheckersForPostStmt(Dst, B.getResults(), DS, *this);
514226586Sdim}
515226586Sdim
516226586Sdimvoid ExprEngine::VisitLogicalExpr(const BinaryOperator* B, ExplodedNode *Pred,
517226586Sdim                                  ExplodedNodeSet &Dst) {
518226586Sdim  assert(B->getOpcode() == BO_LAnd ||
519226586Sdim         B->getOpcode() == BO_LOr);
520234353Sdim
521243830Sdim  StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx);
522234353Sdim  ProgramStateRef state = Pred->getState();
523239462Sdim
524239462Sdim  ExplodedNode *N = Pred;
525249423Sdim  while (!N->getLocation().getAs<BlockEntrance>()) {
526239462Sdim    ProgramPoint P = N->getLocation();
527249423Sdim    assert(P.getAs<PreStmt>()|| P.getAs<PreStmtPurgeDeadSymbols>());
528239462Sdim    (void) P;
529239462Sdim    assert(N->pred_size() == 1);
530239462Sdim    N = *N->pred_begin();
531226586Sdim  }
532239462Sdim  assert(N->pred_size() == 1);
533239462Sdim  N = *N->pred_begin();
534249423Sdim  BlockEdge BE = N->getLocation().castAs<BlockEdge>();
535239462Sdim  SVal X;
536239462Sdim
537239462Sdim  // Determine the value of the expression by introspecting how we
538239462Sdim  // got this location in the CFG.  This requires looking at the previous
539239462Sdim  // block we were in and what kind of control-flow transfer was involved.
540239462Sdim  const CFGBlock *SrcBlock = BE.getSrc();
541239462Sdim  // The only terminator (if there is one) that makes sense is a logical op.
542239462Sdim  CFGTerminator T = SrcBlock->getTerminator();
543239462Sdim  if (const BinaryOperator *Term = cast_or_null<BinaryOperator>(T.getStmt())) {
544239462Sdim    (void) Term;
545239462Sdim    assert(Term->isLogicalOp());
546239462Sdim    assert(SrcBlock->succ_size() == 2);
547239462Sdim    // Did we take the true or false branch?
548239462Sdim    unsigned constant = (*SrcBlock->succ_begin() == BE.getDst()) ? 1 : 0;
549239462Sdim    X = svalBuilder.makeIntVal(constant, B->getType());
550239462Sdim  }
551226586Sdim  else {
552239462Sdim    // If there is no terminator, by construction the last statement
553239462Sdim    // in SrcBlock is the value of the enclosing expression.
554243830Sdim    // However, we still need to constrain that value to be 0 or 1.
555239462Sdim    assert(!SrcBlock->empty());
556249423Sdim    CFGStmt Elem = SrcBlock->rbegin()->castAs<CFGStmt>();
557243830Sdim    const Expr *RHS = cast<Expr>(Elem.getStmt());
558243830Sdim    SVal RHSVal = N->getState()->getSVal(RHS, Pred->getLocationContext());
559243830Sdim
560249423Sdim    if (RHSVal.isUndef()) {
561249423Sdim      X = RHSVal;
562249423Sdim    } else {
563249423Sdim      DefinedOrUnknownSVal DefinedRHS = RHSVal.castAs<DefinedOrUnknownSVal>();
564249423Sdim      ProgramStateRef StTrue, StFalse;
565276479Sdim      std::tie(StTrue, StFalse) = N->getState()->assume(DefinedRHS);
566249423Sdim      if (StTrue) {
567249423Sdim        if (StFalse) {
568249423Sdim          // We can't constrain the value to 0 or 1.
569249423Sdim          // The best we can do is a cast.
570249423Sdim          X = getSValBuilder().evalCast(RHSVal, B->getType(), RHS->getType());
571249423Sdim        } else {
572249423Sdim          // The value is known to be true.
573249423Sdim          X = getSValBuilder().makeIntVal(1, B->getType());
574249423Sdim        }
575243830Sdim      } else {
576249423Sdim        // The value is known to be false.
577249423Sdim        assert(StFalse && "Infeasible path!");
578249423Sdim        X = getSValBuilder().makeIntVal(0, B->getType());
579243830Sdim      }
580243830Sdim    }
581226586Sdim  }
582239462Sdim  Bldr.generateNode(B, Pred, state->BindExpr(B, Pred->getLocationContext(), X));
583226586Sdim}
584226586Sdim
585226586Sdimvoid ExprEngine::VisitInitListExpr(const InitListExpr *IE,
586226586Sdim                                   ExplodedNode *Pred,
587226586Sdim                                   ExplodedNodeSet &Dst) {
588243830Sdim  StmtNodeBuilder B(Pred, Dst, *currBldrCtx);
589226586Sdim
590234353Sdim  ProgramStateRef state = Pred->getState();
591234353Sdim  const LocationContext *LCtx = Pred->getLocationContext();
592226586Sdim  QualType T = getContext().getCanonicalType(IE->getType());
593226586Sdim  unsigned NumInitElements = IE->getNumInits();
594261991Sdim
595261991Sdim  if (!IE->isGLValue() &&
596261991Sdim      (T->isArrayType() || T->isRecordType() || T->isVectorType() ||
597261991Sdim       T->isAnyComplexType())) {
598226586Sdim    llvm::ImmutableList<SVal> vals = getBasicVals().getEmptySValList();
599226586Sdim
600226586Sdim    // Handle base case where the initializer has no elements.
601226586Sdim    // e.g: static int* myArray[] = {};
602226586Sdim    if (NumInitElements == 0) {
603226586Sdim      SVal V = svalBuilder.makeCompoundVal(T, vals);
604234353Sdim      B.generateNode(IE, Pred, state->BindExpr(IE, LCtx, V));
605226586Sdim      return;
606226586Sdim    }
607226586Sdim
608226586Sdim    for (InitListExpr::const_reverse_iterator it = IE->rbegin(),
609226586Sdim         ei = IE->rend(); it != ei; ++it) {
610249423Sdim      SVal V = state->getSVal(cast<Expr>(*it), LCtx);
611249423Sdim      vals = getBasicVals().consVals(V, vals);
612226586Sdim    }
613226586Sdim
614234353Sdim    B.generateNode(IE, Pred,
615234353Sdim                   state->BindExpr(IE, LCtx,
616234353Sdim                                   svalBuilder.makeCompoundVal(T, vals)));
617226586Sdim    return;
618226586Sdim  }
619239462Sdim
620261991Sdim  // Handle scalars: int{5} and int{} and GLvalues.
621261991Sdim  // Note, if the InitListExpr is a GLvalue, it means that there is an address
622261991Sdim  // representing it, so it must have a single init element.
623239462Sdim  assert(NumInitElements <= 1);
624239462Sdim
625239462Sdim  SVal V;
626239462Sdim  if (NumInitElements == 0)
627239462Sdim    V = getSValBuilder().makeZeroVal(T);
628239462Sdim  else
629239462Sdim    V = state->getSVal(IE->getInit(0), LCtx);
630239462Sdim
631239462Sdim  B.generateNode(IE, Pred, state->BindExpr(IE, LCtx, V));
632226586Sdim}
633226586Sdim
634226586Sdimvoid ExprEngine::VisitGuardedExpr(const Expr *Ex,
635226586Sdim                                  const Expr *L,
636226586Sdim                                  const Expr *R,
637226586Sdim                                  ExplodedNode *Pred,
638226586Sdim                                  ExplodedNodeSet &Dst) {
639251662Sdim  assert(L && R);
640251662Sdim
641243830Sdim  StmtNodeBuilder B(Pred, Dst, *currBldrCtx);
642234353Sdim  ProgramStateRef state = Pred->getState();
643234353Sdim  const LocationContext *LCtx = Pred->getLocationContext();
644276479Sdim  const CFGBlock *SrcBlock = nullptr;
645239462Sdim
646251662Sdim  // Find the predecessor block.
647251662Sdim  ProgramStateRef SrcState = state;
648239462Sdim  for (const ExplodedNode *N = Pred ; N ; N = *N->pred_begin()) {
649239462Sdim    ProgramPoint PP = N->getLocation();
650249423Sdim    if (PP.getAs<PreStmtPurgeDeadSymbols>() || PP.getAs<BlockEntrance>()) {
651239462Sdim      assert(N->pred_size() == 1);
652239462Sdim      continue;
653239462Sdim    }
654249423Sdim    SrcBlock = PP.castAs<BlockEdge>().getSrc();
655251662Sdim    SrcState = N->getState();
656239462Sdim    break;
657239462Sdim  }
658239462Sdim
659249423Sdim  assert(SrcBlock && "missing function entry");
660249423Sdim
661239462Sdim  // Find the last expression in the predecessor block.  That is the
662239462Sdim  // expression that is used for the value of the ternary expression.
663239462Sdim  bool hasValue = false;
664239462Sdim  SVal V;
665239462Sdim
666239462Sdim  for (CFGBlock::const_reverse_iterator I = SrcBlock->rbegin(),
667239462Sdim                                        E = SrcBlock->rend(); I != E; ++I) {
668239462Sdim    CFGElement CE = *I;
669249423Sdim    if (Optional<CFGStmt> CS = CE.getAs<CFGStmt>()) {
670239462Sdim      const Expr *ValEx = cast<Expr>(CS->getStmt());
671251662Sdim      ValEx = ValEx->IgnoreParens();
672251662Sdim
673251662Sdim      // For GNU extension '?:' operator, the left hand side will be an
674251662Sdim      // OpaqueValueExpr, so get the underlying expression.
675251662Sdim      if (const OpaqueValueExpr *OpaqueEx = dyn_cast<OpaqueValueExpr>(L))
676251662Sdim        L = OpaqueEx->getSourceExpr();
677251662Sdim
678251662Sdim      // If the last expression in the predecessor block matches true or false
679251662Sdim      // subexpression, get its the value.
680251662Sdim      if (ValEx == L->IgnoreParens() || ValEx == R->IgnoreParens()) {
681251662Sdim        hasValue = true;
682251662Sdim        V = SrcState->getSVal(ValEx, LCtx);
683251662Sdim      }
684239462Sdim      break;
685239462Sdim    }
686239462Sdim  }
687239462Sdim
688251662Sdim  if (!hasValue)
689276479Sdim    V = svalBuilder.conjureSymbolVal(nullptr, Ex, LCtx,
690276479Sdim                                     currBldrCtx->blockCount());
691239462Sdim
692239462Sdim  // Generate a new node with the binding from the appropriate path.
693239462Sdim  B.generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V, true));
694226586Sdim}
695226586Sdim
696226586Sdimvoid ExprEngine::
697226586SdimVisitOffsetOfExpr(const OffsetOfExpr *OOE,
698226586Sdim                  ExplodedNode *Pred, ExplodedNodeSet &Dst) {
699243830Sdim  StmtNodeBuilder B(Pred, Dst, *currBldrCtx);
700234353Sdim  APSInt IV;
701234353Sdim  if (OOE->EvaluateAsInt(IV, getContext())) {
702226586Sdim    assert(IV.getBitWidth() == getContext().getTypeSize(OOE->getType()));
703251662Sdim    assert(OOE->getType()->isBuiltinType());
704251662Sdim    assert(OOE->getType()->getAs<BuiltinType>()->isInteger());
705251662Sdim    assert(IV.isSigned() == OOE->getType()->isSignedIntegerType());
706226586Sdim    SVal X = svalBuilder.makeIntVal(IV);
707234353Sdim    B.generateNode(OOE, Pred,
708234353Sdim                   Pred->getState()->BindExpr(OOE, Pred->getLocationContext(),
709234353Sdim                                              X));
710226586Sdim  }
711226586Sdim  // FIXME: Handle the case where __builtin_offsetof is not a constant.
712226586Sdim}
713226586Sdim
714226586Sdim
715226586Sdimvoid ExprEngine::
716226586SdimVisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Ex,
717226586Sdim                              ExplodedNode *Pred,
718226586Sdim                              ExplodedNodeSet &Dst) {
719276479Sdim  // FIXME: Prechecks eventually go in ::Visit().
720276479Sdim  ExplodedNodeSet CheckedSet;
721276479Sdim  getCheckerManager().runCheckersForPreStmt(CheckedSet, Pred, Ex, *this);
722226586Sdim
723276479Sdim  ExplodedNodeSet EvalSet;
724276479Sdim  StmtNodeBuilder Bldr(CheckedSet, EvalSet, *currBldrCtx);
725276479Sdim
726226586Sdim  QualType T = Ex->getTypeOfArgument();
727276479Sdim
728276479Sdim  for (ExplodedNodeSet::iterator I = CheckedSet.begin(), E = CheckedSet.end();
729276479Sdim       I != E; ++I) {
730276479Sdim    if (Ex->getKind() == UETT_SizeOf) {
731276479Sdim      if (!T->isIncompleteType() && !T->isConstantSizeType()) {
732276479Sdim        assert(T->isVariableArrayType() && "Unknown non-constant-sized type.");
733276479Sdim
734276479Sdim        // FIXME: Add support for VLA type arguments and VLA expressions.
735276479Sdim        // When that happens, we should probably refactor VLASizeChecker's code.
736276479Sdim        continue;
737276479Sdim      } else if (T->getAs<ObjCObjectType>()) {
738276479Sdim        // Some code tries to take the sizeof an ObjCObjectType, relying that
739276479Sdim        // the compiler has laid out its representation.  Just report Unknown
740276479Sdim        // for these.
741276479Sdim        continue;
742276479Sdim      }
743226586Sdim    }
744276479Sdim
745276479Sdim    APSInt Value = Ex->EvaluateKnownConstInt(getContext());
746276479Sdim    CharUnits amt = CharUnits::fromQuantity(Value.getZExtValue());
747276479Sdim
748276479Sdim    ProgramStateRef state = (*I)->getState();
749276479Sdim    state = state->BindExpr(Ex, (*I)->getLocationContext(),
750276479Sdim                            svalBuilder.makeIntVal(amt.getQuantity(),
751276479Sdim                                                   Ex->getType()));
752276479Sdim    Bldr.generateNode(Ex, *I, state);
753226586Sdim  }
754276479Sdim
755276479Sdim  getCheckerManager().runCheckersForPostStmt(Dst, EvalSet, Ex, *this);
756226586Sdim}
757226586Sdim
758226586Sdimvoid ExprEngine::VisitUnaryOperator(const UnaryOperator* U,
759226586Sdim                                    ExplodedNode *Pred,
760234353Sdim                                    ExplodedNodeSet &Dst) {
761261991Sdim  // FIXME: Prechecks eventually go in ::Visit().
762261991Sdim  ExplodedNodeSet CheckedSet;
763261991Sdim  getCheckerManager().runCheckersForPreStmt(CheckedSet, Pred, U, *this);
764261991Sdim
765261991Sdim  ExplodedNodeSet EvalSet;
766261991Sdim  StmtNodeBuilder Bldr(CheckedSet, EvalSet, *currBldrCtx);
767261991Sdim
768261991Sdim  for (ExplodedNodeSet::iterator I = CheckedSet.begin(), E = CheckedSet.end();
769261991Sdim       I != E; ++I) {
770261991Sdim    switch (U->getOpcode()) {
771234353Sdim    default: {
772261991Sdim      Bldr.takeNodes(*I);
773234353Sdim      ExplodedNodeSet Tmp;
774261991Sdim      VisitIncrementDecrementOperator(U, *I, Tmp);
775234353Sdim      Bldr.addNodes(Tmp);
776261991Sdim      break;
777234353Sdim    }
778226586Sdim    case UO_Real: {
779226586Sdim      const Expr *Ex = U->getSubExpr()->IgnoreParens();
780226586Sdim
781234353Sdim      // FIXME: We don't have complex SValues yet.
782234353Sdim      if (Ex->getType()->isAnyComplexType()) {
783234353Sdim        // Just report "Unknown."
784234353Sdim        break;
785234353Sdim      }
786226586Sdim
787234353Sdim      // For all other types, UO_Real is an identity operation.
788234353Sdim      assert (U->getType() == Ex->getType());
789261991Sdim      ProgramStateRef state = (*I)->getState();
790261991Sdim      const LocationContext *LCtx = (*I)->getLocationContext();
791261991Sdim      Bldr.generateNode(U, *I, state->BindExpr(U, LCtx,
792261991Sdim                                               state->getSVal(Ex, LCtx)));
793234353Sdim      break;
794226586Sdim    }
795226586Sdim
796234353Sdim    case UO_Imag: {
797226586Sdim      const Expr *Ex = U->getSubExpr()->IgnoreParens();
798234353Sdim      // FIXME: We don't have complex SValues yet.
799234353Sdim      if (Ex->getType()->isAnyComplexType()) {
800234353Sdim        // Just report "Unknown."
801234353Sdim        break;
802226586Sdim      }
803234353Sdim      // For all other types, UO_Imag returns 0.
804261991Sdim      ProgramStateRef state = (*I)->getState();
805261991Sdim      const LocationContext *LCtx = (*I)->getLocationContext();
806234353Sdim      SVal X = svalBuilder.makeZeroVal(Ex->getType());
807261991Sdim      Bldr.generateNode(U, *I, state->BindExpr(U, LCtx, X));
808234353Sdim      break;
809226586Sdim    }
810226586Sdim
811226586Sdim    case UO_Plus:
812239462Sdim      assert(!U->isGLValue());
813226586Sdim      // FALL-THROUGH.
814226586Sdim    case UO_Deref:
815226586Sdim    case UO_AddrOf:
816226586Sdim    case UO_Extension: {
817234353Sdim      // FIXME: We can probably just have some magic in Environment::getSVal()
818234353Sdim      // that propagates values, instead of creating a new node here.
819234353Sdim      //
820226586Sdim      // Unary "+" is a no-op, similar to a parentheses.  We still have places
821226586Sdim      // where it may be a block-level expression, so we need to
822226586Sdim      // generate an extra node that just propagates the value of the
823234353Sdim      // subexpression.
824226586Sdim      const Expr *Ex = U->getSubExpr()->IgnoreParens();
825261991Sdim      ProgramStateRef state = (*I)->getState();
826261991Sdim      const LocationContext *LCtx = (*I)->getLocationContext();
827261991Sdim      Bldr.generateNode(U, *I, state->BindExpr(U, LCtx,
828261991Sdim                                               state->getSVal(Ex, LCtx)));
829234353Sdim      break;
830226586Sdim    }
831226586Sdim
832226586Sdim    case UO_LNot:
833226586Sdim    case UO_Minus:
834226586Sdim    case UO_Not: {
835239462Sdim      assert (!U->isGLValue());
836226586Sdim      const Expr *Ex = U->getSubExpr()->IgnoreParens();
837261991Sdim      ProgramStateRef state = (*I)->getState();
838261991Sdim      const LocationContext *LCtx = (*I)->getLocationContext();
839226586Sdim
840234353Sdim      // Get the value of the subexpression.
841234353Sdim      SVal V = state->getSVal(Ex, LCtx);
842226586Sdim
843234353Sdim      if (V.isUnknownOrUndef()) {
844261991Sdim        Bldr.generateNode(U, *I, state->BindExpr(U, LCtx, V));
845234353Sdim        break;
846234353Sdim      }
847226586Sdim
848234353Sdim      switch (U->getOpcode()) {
849234353Sdim        default:
850234353Sdim          llvm_unreachable("Invalid Opcode.");
851234353Sdim        case UO_Not:
852234353Sdim          // FIXME: Do we need to handle promotions?
853249423Sdim          state = state->BindExpr(U, LCtx, evalComplement(V.castAs<NonLoc>()));
854234353Sdim          break;
855234353Sdim        case UO_Minus:
856234353Sdim          // FIXME: Do we need to handle promotions?
857249423Sdim          state = state->BindExpr(U, LCtx, evalMinus(V.castAs<NonLoc>()));
858234353Sdim          break;
859234353Sdim        case UO_LNot:
860234353Sdim          // C99 6.5.3.3: "The expression !E is equivalent to (0==E)."
861234353Sdim          //
862234353Sdim          //  Note: technically we do "E == 0", but this is the same in the
863234353Sdim          //    transfer functions as "0 == E".
864234353Sdim          SVal Result;
865249423Sdim          if (Optional<Loc> LV = V.getAs<Loc>()) {
866234353Sdim            Loc X = svalBuilder.makeNull();
867249423Sdim            Result = evalBinOp(state, BO_EQ, *LV, X, U->getType());
868234353Sdim          }
869249423Sdim          else if (Ex->getType()->isFloatingType()) {
870249423Sdim            // FIXME: handle floating point types.
871249423Sdim            Result = UnknownVal();
872249423Sdim          } else {
873234353Sdim            nonloc::ConcreteInt X(getBasicVals().getValue(0, Ex->getType()));
874249423Sdim            Result = evalBinOp(state, BO_EQ, V.castAs<NonLoc>(), X,
875234353Sdim                               U->getType());
876234353Sdim          }
877234353Sdim
878234353Sdim          state = state->BindExpr(U, LCtx, Result);
879234353Sdim          break;
880226586Sdim      }
881261991Sdim      Bldr.generateNode(U, *I, state);
882234353Sdim      break;
883226586Sdim    }
884261991Sdim    }
885226586Sdim  }
886234353Sdim
887261991Sdim  getCheckerManager().runCheckersForPostStmt(Dst, EvalSet, U, *this);
888234353Sdim}
889234353Sdim
890234353Sdimvoid ExprEngine::VisitIncrementDecrementOperator(const UnaryOperator* U,
891234353Sdim                                                 ExplodedNode *Pred,
892234353Sdim                                                 ExplodedNodeSet &Dst) {
893226586Sdim  // Handle ++ and -- (both pre- and post-increment).
894226586Sdim  assert (U->isIncrementDecrementOp());
895226586Sdim  const Expr *Ex = U->getSubExpr()->IgnoreParens();
896226586Sdim
897234353Sdim  const LocationContext *LCtx = Pred->getLocationContext();
898234353Sdim  ProgramStateRef state = Pred->getState();
899234353Sdim  SVal loc = state->getSVal(Ex, LCtx);
900234353Sdim
901234353Sdim  // Perform a load.
902234353Sdim  ExplodedNodeSet Tmp;
903234353Sdim  evalLoad(Tmp, U, Ex, Pred, state, loc);
904234353Sdim
905234353Sdim  ExplodedNodeSet Dst2;
906243830Sdim  StmtNodeBuilder Bldr(Tmp, Dst2, *currBldrCtx);
907234353Sdim  for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end();I!=E;++I) {
908226586Sdim
909234353Sdim    state = (*I)->getState();
910234353Sdim    assert(LCtx == (*I)->getLocationContext());
911234353Sdim    SVal V2_untested = state->getSVal(Ex, LCtx);
912226586Sdim
913234353Sdim    // Propagate unknown and undefined values.
914234353Sdim    if (V2_untested.isUnknownOrUndef()) {
915234353Sdim      Bldr.generateNode(U, *I, state->BindExpr(U, LCtx, V2_untested));
916234353Sdim      continue;
917234353Sdim    }
918249423Sdim    DefinedSVal V2 = V2_untested.castAs<DefinedSVal>();
919226586Sdim
920234353Sdim    // Handle all other values.
921234353Sdim    BinaryOperator::Opcode Op = U->isIncrementOp() ? BO_Add : BO_Sub;
922234353Sdim
923234353Sdim    // If the UnaryOperator has non-location type, use its type to create the
924234353Sdim    // constant value. If the UnaryOperator has location type, create the
925234353Sdim    // constant with int type and pointer width.
926234353Sdim    SVal RHS;
927234353Sdim
928234353Sdim    if (U->getType()->isAnyPointerType())
929234353Sdim      RHS = svalBuilder.makeArrayIndex(1);
930243830Sdim    else if (U->getType()->isIntegralOrEnumerationType())
931243830Sdim      RHS = svalBuilder.makeIntVal(1, U->getType());
932234353Sdim    else
933243830Sdim      RHS = UnknownVal();
934234353Sdim
935234353Sdim    SVal Result = evalBinOp(state, Op, V2, RHS, U->getType());
936234353Sdim
937234353Sdim    // Conjure a new symbol if necessary to recover precision.
938234353Sdim    if (Result.isUnknown()){
939234353Sdim      DefinedOrUnknownSVal SymVal =
940276479Sdim        svalBuilder.conjureSymbolVal(nullptr, Ex, LCtx,
941276479Sdim                                     currBldrCtx->blockCount());
942234353Sdim      Result = SymVal;
943226586Sdim
944234353Sdim      // If the value is a location, ++/-- should always preserve
945234353Sdim      // non-nullness.  Check if the original value was non-null, and if so
946234353Sdim      // propagate that constraint.
947234353Sdim      if (Loc::isLocType(U->getType())) {
948234353Sdim        DefinedOrUnknownSVal Constraint =
949234353Sdim        svalBuilder.evalEQ(state, V2,svalBuilder.makeZeroVal(U->getType()));
950226586Sdim
951234353Sdim        if (!state->assume(Constraint, true)) {
952234353Sdim          // It isn't feasible for the original value to be null.
953234353Sdim          // Propagate this constraint.
954234353Sdim          Constraint = svalBuilder.evalEQ(state, SymVal,
955234353Sdim                                       svalBuilder.makeZeroVal(U->getType()));
956226586Sdim
957234353Sdim
958234353Sdim          state = state->assume(Constraint, false);
959234353Sdim          assert(state);
960226586Sdim        }
961226586Sdim      }
962226586Sdim    }
963234353Sdim
964234353Sdim    // Since the lvalue-to-rvalue conversion is explicit in the AST,
965234353Sdim    // we bind an l-value if the operator is prefix and an lvalue (in C++).
966239462Sdim    if (U->isGLValue())
967234353Sdim      state = state->BindExpr(U, LCtx, loc);
968234353Sdim    else
969234353Sdim      state = state->BindExpr(U, LCtx, U->isPostfix() ? V2 : Result);
970234353Sdim
971234353Sdim    // Perform the store.
972234353Sdim    Bldr.takeNodes(*I);
973234353Sdim    ExplodedNodeSet Dst3;
974234353Sdim    evalStore(Dst3, U, U, *I, state, loc, Result);
975234353Sdim    Bldr.addNodes(Dst3);
976226586Sdim  }
977234353Sdim  Dst.insert(Dst2);
978226586Sdim}
979