ExprEngineC.cpp revision 234353
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
14226586Sdim#include "clang/StaticAnalyzer/Core/CheckerManager.h"
15226586Sdim#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
16226586Sdim
17226586Sdimusing namespace clang;
18226586Sdimusing namespace ento;
19226586Sdimusing llvm::APSInt;
20226586Sdim
21226586Sdimvoid ExprEngine::VisitBinaryOperator(const BinaryOperator* B,
22226586Sdim                                     ExplodedNode *Pred,
23226586Sdim                                     ExplodedNodeSet &Dst) {
24226586Sdim
25226586Sdim  Expr *LHS = B->getLHS()->IgnoreParens();
26226586Sdim  Expr *RHS = B->getRHS()->IgnoreParens();
27226586Sdim
28226586Sdim  // FIXME: Prechecks eventually go in ::Visit().
29226586Sdim  ExplodedNodeSet CheckedSet;
30226586Sdim  ExplodedNodeSet Tmp2;
31226586Sdim  getCheckerManager().runCheckersForPreStmt(CheckedSet, Pred, B, *this);
32226586Sdim
33226586Sdim  // With both the LHS and RHS evaluated, process the operation itself.
34226586Sdim  for (ExplodedNodeSet::iterator it=CheckedSet.begin(), ei=CheckedSet.end();
35226586Sdim         it != ei; ++it) {
36226586Sdim
37234353Sdim    ProgramStateRef state = (*it)->getState();
38234353Sdim    const LocationContext *LCtx = (*it)->getLocationContext();
39234353Sdim    SVal LeftV = state->getSVal(LHS, LCtx);
40234353Sdim    SVal RightV = state->getSVal(RHS, LCtx);
41226586Sdim
42226586Sdim    BinaryOperator::Opcode Op = B->getOpcode();
43226586Sdim
44226586Sdim    if (Op == BO_Assign) {
45226586Sdim      // EXPERIMENTAL: "Conjured" symbols.
46226586Sdim      // FIXME: Handle structs.
47234353Sdim      if (RightV.isUnknown()) {
48234353Sdim        unsigned Count = currentBuilderContext->getCurrentBlockCount();
49234353Sdim        RightV = svalBuilder.getConjuredSymbolVal(NULL, B->getRHS(), LCtx, Count);
50226586Sdim      }
51226586Sdim      // Simulate the effects of a "store":  bind the value of the RHS
52226586Sdim      // to the L-Value represented by the LHS.
53226586Sdim      SVal ExprVal = B->isLValue() ? LeftV : RightV;
54234353Sdim      evalStore(Tmp2, B, LHS, *it, state->BindExpr(B, LCtx, ExprVal),
55234353Sdim                LeftV, RightV);
56226586Sdim      continue;
57226586Sdim    }
58226586Sdim
59226586Sdim    if (!B->isAssignmentOp()) {
60234353Sdim      StmtNodeBuilder Bldr(*it, Tmp2, *currentBuilderContext);
61226586Sdim      // Process non-assignments except commas or short-circuited
62226586Sdim      // logical expressions (LAnd and LOr).
63226586Sdim      SVal Result = evalBinOp(state, Op, LeftV, RightV, B->getType());
64226586Sdim      if (Result.isUnknown()) {
65234353Sdim        Bldr.generateNode(B, *it, state);
66226586Sdim        continue;
67226586Sdim      }
68226586Sdim
69234353Sdim      state = state->BindExpr(B, LCtx, Result);
70234353Sdim      Bldr.generateNode(B, *it, state);
71226586Sdim      continue;
72226586Sdim    }
73226586Sdim
74226586Sdim    assert (B->isCompoundAssignmentOp());
75226586Sdim
76226586Sdim    switch (Op) {
77226586Sdim      default:
78226586Sdim        llvm_unreachable("Invalid opcode for compound assignment.");
79226586Sdim      case BO_MulAssign: Op = BO_Mul; break;
80226586Sdim      case BO_DivAssign: Op = BO_Div; break;
81226586Sdim      case BO_RemAssign: Op = BO_Rem; break;
82226586Sdim      case BO_AddAssign: Op = BO_Add; break;
83226586Sdim      case BO_SubAssign: Op = BO_Sub; break;
84226586Sdim      case BO_ShlAssign: Op = BO_Shl; break;
85226586Sdim      case BO_ShrAssign: Op = BO_Shr; break;
86226586Sdim      case BO_AndAssign: Op = BO_And; break;
87226586Sdim      case BO_XorAssign: Op = BO_Xor; break;
88226586Sdim      case BO_OrAssign:  Op = BO_Or;  break;
89226586Sdim    }
90226586Sdim
91226586Sdim    // Perform a load (the LHS).  This performs the checks for
92226586Sdim    // null dereferences, and so on.
93226586Sdim    ExplodedNodeSet Tmp;
94226586Sdim    SVal location = LeftV;
95234353Sdim    evalLoad(Tmp, B, LHS, *it, state, location);
96226586Sdim
97226586Sdim    for (ExplodedNodeSet::iterator I = Tmp.begin(), E = Tmp.end(); I != E;
98226586Sdim         ++I) {
99226586Sdim
100226586Sdim      state = (*I)->getState();
101234353Sdim      const LocationContext *LCtx = (*I)->getLocationContext();
102234353Sdim      SVal V = state->getSVal(LHS, LCtx);
103226586Sdim
104226586Sdim      // Get the computation type.
105226586Sdim      QualType CTy =
106226586Sdim        cast<CompoundAssignOperator>(B)->getComputationResultType();
107226586Sdim      CTy = getContext().getCanonicalType(CTy);
108226586Sdim
109226586Sdim      QualType CLHSTy =
110226586Sdim        cast<CompoundAssignOperator>(B)->getComputationLHSType();
111226586Sdim      CLHSTy = getContext().getCanonicalType(CLHSTy);
112226586Sdim
113226586Sdim      QualType LTy = getContext().getCanonicalType(LHS->getType());
114226586Sdim
115226586Sdim      // Promote LHS.
116226586Sdim      V = svalBuilder.evalCast(V, CLHSTy, LTy);
117226586Sdim
118226586Sdim      // Compute the result of the operation.
119226586Sdim      SVal Result = svalBuilder.evalCast(evalBinOp(state, Op, V, RightV, CTy),
120226586Sdim                                         B->getType(), CTy);
121226586Sdim
122226586Sdim      // EXPERIMENTAL: "Conjured" symbols.
123226586Sdim      // FIXME: Handle structs.
124226586Sdim
125226586Sdim      SVal LHSVal;
126226586Sdim
127234353Sdim      if (Result.isUnknown()) {
128226586Sdim
129234353Sdim        unsigned Count = currentBuilderContext->getCurrentBlockCount();
130226586Sdim
131226586Sdim        // The symbolic value is actually for the type of the left-hand side
132226586Sdim        // expression, not the computation type, as this is the value the
133226586Sdim        // LValue on the LHS will bind to.
134234353Sdim        LHSVal = svalBuilder.getConjuredSymbolVal(NULL, B->getRHS(), LCtx,
135234353Sdim						  LTy, Count);
136226586Sdim
137226586Sdim        // However, we need to convert the symbol to the computation type.
138226586Sdim        Result = svalBuilder.evalCast(LHSVal, CTy, LTy);
139226586Sdim      }
140226586Sdim      else {
141226586Sdim        // The left-hand side may bind to a different value then the
142226586Sdim        // computation type.
143226586Sdim        LHSVal = svalBuilder.evalCast(Result, LTy, CTy);
144226586Sdim      }
145226586Sdim
146226586Sdim      // In C++, assignment and compound assignment operators return an
147226586Sdim      // lvalue.
148226586Sdim      if (B->isLValue())
149234353Sdim        state = state->BindExpr(B, LCtx, location);
150226586Sdim      else
151234353Sdim        state = state->BindExpr(B, LCtx, Result);
152226586Sdim
153226586Sdim      evalStore(Tmp2, B, LHS, *I, state, location, LHSVal);
154226586Sdim    }
155226586Sdim  }
156226586Sdim
157226586Sdim  // FIXME: postvisits eventually go in ::Visit()
158226586Sdim  getCheckerManager().runCheckersForPostStmt(Dst, Tmp2, B, *this);
159226586Sdim}
160226586Sdim
161226586Sdimvoid ExprEngine::VisitBlockExpr(const BlockExpr *BE, ExplodedNode *Pred,
162226586Sdim                                ExplodedNodeSet &Dst) {
163226586Sdim
164226586Sdim  CanQualType T = getContext().getCanonicalType(BE->getType());
165226586Sdim  SVal V = svalBuilder.getBlockPointer(BE->getBlockDecl(), T,
166226586Sdim                                       Pred->getLocationContext());
167226586Sdim
168226586Sdim  ExplodedNodeSet Tmp;
169234353Sdim  StmtNodeBuilder Bldr(Pred, Tmp, *currentBuilderContext);
170234353Sdim  Bldr.generateNode(BE, Pred,
171234353Sdim                    Pred->getState()->BindExpr(BE, Pred->getLocationContext(),
172234353Sdim                                               V),
173234353Sdim                    false, 0,
174234353Sdim                    ProgramPoint::PostLValueKind);
175226586Sdim
176226586Sdim  // FIXME: Move all post/pre visits to ::Visit().
177226586Sdim  getCheckerManager().runCheckersForPostStmt(Dst, Tmp, BE, *this);
178226586Sdim}
179226586Sdim
180226586Sdimvoid ExprEngine::VisitCast(const CastExpr *CastE, const Expr *Ex,
181226586Sdim                           ExplodedNode *Pred, ExplodedNodeSet &Dst) {
182226586Sdim
183226586Sdim  ExplodedNodeSet dstPreStmt;
184226586Sdim  getCheckerManager().runCheckersForPreStmt(dstPreStmt, Pred, CastE, *this);
185226586Sdim
186234353Sdim  if (CastE->getCastKind() == CK_LValueToRValue) {
187226586Sdim    for (ExplodedNodeSet::iterator I = dstPreStmt.begin(), E = dstPreStmt.end();
188226586Sdim         I!=E; ++I) {
189226586Sdim      ExplodedNode *subExprNode = *I;
190234353Sdim      ProgramStateRef state = subExprNode->getState();
191234353Sdim      const LocationContext *LCtx = subExprNode->getLocationContext();
192234353Sdim      evalLoad(Dst, CastE, CastE, subExprNode, state, state->getSVal(Ex, LCtx));
193226586Sdim    }
194226586Sdim    return;
195226586Sdim  }
196226586Sdim
197226586Sdim  // All other casts.
198226586Sdim  QualType T = CastE->getType();
199226586Sdim  QualType ExTy = Ex->getType();
200226586Sdim
201226586Sdim  if (const ExplicitCastExpr *ExCast=dyn_cast_or_null<ExplicitCastExpr>(CastE))
202226586Sdim    T = ExCast->getTypeAsWritten();
203226586Sdim
204234353Sdim  StmtNodeBuilder Bldr(dstPreStmt, Dst, *currentBuilderContext);
205226586Sdim  for (ExplodedNodeSet::iterator I = dstPreStmt.begin(), E = dstPreStmt.end();
206226586Sdim       I != E; ++I) {
207226586Sdim
208226586Sdim    Pred = *I;
209226586Sdim
210226586Sdim    switch (CastE->getCastKind()) {
211226586Sdim      case CK_LValueToRValue:
212226586Sdim        llvm_unreachable("LValueToRValue casts handled earlier.");
213226586Sdim      case CK_ToVoid:
214226586Sdim        continue;
215226586Sdim        // The analyzer doesn't do anything special with these casts,
216226586Sdim        // since it understands retain/release semantics already.
217226586Sdim      case CK_ARCProduceObject:
218226586Sdim      case CK_ARCConsumeObject:
219226586Sdim      case CK_ARCReclaimReturnedObject:
220226586Sdim      case CK_ARCExtendBlockObject: // Fall-through.
221234353Sdim      case CK_CopyAndAutoreleaseBlockObject:
222234353Sdim        // The analyser can ignore atomic casts for now, although some future
223234353Sdim        // checkers may want to make certain that you're not modifying the same
224234353Sdim        // value through atomic and nonatomic pointers.
225234353Sdim      case CK_AtomicToNonAtomic:
226234353Sdim      case CK_NonAtomicToAtomic:
227226586Sdim        // True no-ops.
228226586Sdim      case CK_NoOp:
229226586Sdim      case CK_FunctionToPointerDecay: {
230226586Sdim        // Copy the SVal of Ex to CastE.
231234353Sdim        ProgramStateRef state = Pred->getState();
232234353Sdim        const LocationContext *LCtx = Pred->getLocationContext();
233234353Sdim        SVal V = state->getSVal(Ex, LCtx);
234234353Sdim        state = state->BindExpr(CastE, LCtx, V);
235234353Sdim        Bldr.generateNode(CastE, Pred, state);
236226586Sdim        continue;
237226586Sdim      }
238226586Sdim      case CK_Dependent:
239226586Sdim      case CK_ArrayToPointerDecay:
240226586Sdim      case CK_BitCast:
241226586Sdim      case CK_LValueBitCast:
242226586Sdim      case CK_IntegralCast:
243226586Sdim      case CK_NullToPointer:
244226586Sdim      case CK_IntegralToPointer:
245226586Sdim      case CK_PointerToIntegral:
246226586Sdim      case CK_PointerToBoolean:
247226586Sdim      case CK_IntegralToBoolean:
248226586Sdim      case CK_IntegralToFloating:
249226586Sdim      case CK_FloatingToIntegral:
250226586Sdim      case CK_FloatingToBoolean:
251226586Sdim      case CK_FloatingCast:
252226586Sdim      case CK_FloatingRealToComplex:
253226586Sdim      case CK_FloatingComplexToReal:
254226586Sdim      case CK_FloatingComplexToBoolean:
255226586Sdim      case CK_FloatingComplexCast:
256226586Sdim      case CK_FloatingComplexToIntegralComplex:
257226586Sdim      case CK_IntegralRealToComplex:
258226586Sdim      case CK_IntegralComplexToReal:
259226586Sdim      case CK_IntegralComplexToBoolean:
260226586Sdim      case CK_IntegralComplexCast:
261226586Sdim      case CK_IntegralComplexToFloatingComplex:
262226586Sdim      case CK_CPointerToObjCPointerCast:
263226586Sdim      case CK_BlockPointerToObjCPointerCast:
264226586Sdim      case CK_AnyPointerToBlockPointerCast:
265226586Sdim      case CK_ObjCObjectLValueCast: {
266226586Sdim        // Delegate to SValBuilder to process.
267234353Sdim        ProgramStateRef state = Pred->getState();
268234353Sdim        const LocationContext *LCtx = Pred->getLocationContext();
269234353Sdim        SVal V = state->getSVal(Ex, LCtx);
270226586Sdim        V = svalBuilder.evalCast(V, T, ExTy);
271234353Sdim        state = state->BindExpr(CastE, LCtx, V);
272234353Sdim        Bldr.generateNode(CastE, Pred, state);
273226586Sdim        continue;
274226586Sdim      }
275226586Sdim      case CK_DerivedToBase:
276226586Sdim      case CK_UncheckedDerivedToBase: {
277226586Sdim        // For DerivedToBase cast, delegate to the store manager.
278234353Sdim        ProgramStateRef state = Pred->getState();
279234353Sdim        const LocationContext *LCtx = Pred->getLocationContext();
280234353Sdim        SVal val = state->getSVal(Ex, LCtx);
281226586Sdim        val = getStoreManager().evalDerivedToBase(val, T);
282234353Sdim        state = state->BindExpr(CastE, LCtx, val);
283234353Sdim        Bldr.generateNode(CastE, Pred, state);
284226586Sdim        continue;
285226586Sdim      }
286234353Sdim      // Handle C++ dyn_cast.
287234353Sdim      case CK_Dynamic: {
288234353Sdim        ProgramStateRef state = Pred->getState();
289234353Sdim        const LocationContext *LCtx = Pred->getLocationContext();
290234353Sdim        SVal val = state->getSVal(Ex, LCtx);
291234353Sdim
292234353Sdim        // Compute the type of the result.
293234353Sdim        QualType resultType = CastE->getType();
294234353Sdim        if (CastE->isLValue())
295234353Sdim          resultType = getContext().getPointerType(resultType);
296234353Sdim
297234353Sdim        bool Failed = false;
298234353Sdim
299234353Sdim        // Check if the value being cast evaluates to 0.
300234353Sdim        if (val.isZeroConstant())
301234353Sdim          Failed = true;
302234353Sdim        // Else, evaluate the cast.
303234353Sdim        else
304234353Sdim          val = getStoreManager().evalDynamicCast(val, T, Failed);
305234353Sdim
306234353Sdim        if (Failed) {
307234353Sdim          if (T->isReferenceType()) {
308234353Sdim            // A bad_cast exception is thrown if input value is a reference.
309234353Sdim            // Currently, we model this, by generating a sink.
310234353Sdim            Bldr.generateNode(CastE, Pred, state, true);
311234353Sdim            continue;
312234353Sdim          } else {
313234353Sdim            // If the cast fails on a pointer, bind to 0.
314234353Sdim            state = state->BindExpr(CastE, LCtx, svalBuilder.makeNull());
315234353Sdim          }
316234353Sdim        } else {
317234353Sdim          // If we don't know if the cast succeeded, conjure a new symbol.
318234353Sdim          if (val.isUnknown()) {
319234353Sdim            DefinedOrUnknownSVal NewSym = svalBuilder.getConjuredSymbolVal(NULL,
320234353Sdim                                 CastE, LCtx, resultType,
321234353Sdim                                 currentBuilderContext->getCurrentBlockCount());
322234353Sdim            state = state->BindExpr(CastE, LCtx, NewSym);
323234353Sdim          } else
324234353Sdim            // Else, bind to the derived region value.
325234353Sdim            state = state->BindExpr(CastE, LCtx, val);
326234353Sdim        }
327234353Sdim        Bldr.generateNode(CastE, Pred, state);
328234353Sdim        continue;
329234353Sdim      }
330234353Sdim      // Various C++ casts that are not handled yet.
331226586Sdim      case CK_ToUnion:
332226586Sdim      case CK_BaseToDerived:
333226586Sdim      case CK_NullToMemberPointer:
334226586Sdim      case CK_BaseToDerivedMemberPointer:
335226586Sdim      case CK_DerivedToBaseMemberPointer:
336234353Sdim      case CK_ReinterpretMemberPointer:
337226586Sdim      case CK_UserDefinedConversion:
338226586Sdim      case CK_ConstructorConversion:
339226586Sdim      case CK_VectorSplat:
340226586Sdim      case CK_MemberPointerToBoolean: {
341226586Sdim        // Recover some path-sensitivty by conjuring a new value.
342226586Sdim        QualType resultType = CastE->getType();
343226586Sdim        if (CastE->isLValue())
344226586Sdim          resultType = getContext().getPointerType(resultType);
345234353Sdim        const LocationContext *LCtx = Pred->getLocationContext();
346234353Sdim        SVal result = svalBuilder.getConjuredSymbolVal(NULL, CastE, LCtx,
347234353Sdim                    resultType, currentBuilderContext->getCurrentBlockCount());
348234353Sdim        ProgramStateRef state = Pred->getState()->BindExpr(CastE, LCtx,
349234353Sdim                                                               result);
350234353Sdim        Bldr.generateNode(CastE, Pred, state);
351226586Sdim        continue;
352226586Sdim      }
353226586Sdim    }
354226586Sdim  }
355226586Sdim}
356226586Sdim
357226586Sdimvoid ExprEngine::VisitCompoundLiteralExpr(const CompoundLiteralExpr *CL,
358226586Sdim                                          ExplodedNode *Pred,
359226586Sdim                                          ExplodedNodeSet &Dst) {
360234353Sdim  StmtNodeBuilder B(Pred, Dst, *currentBuilderContext);
361234353Sdim
362226586Sdim  const InitListExpr *ILE
363226586Sdim    = cast<InitListExpr>(CL->getInitializer()->IgnoreParens());
364226586Sdim
365234353Sdim  ProgramStateRef state = Pred->getState();
366234353Sdim  SVal ILV = state->getSVal(ILE, Pred->getLocationContext());
367226586Sdim  const LocationContext *LC = Pred->getLocationContext();
368226586Sdim  state = state->bindCompoundLiteral(CL, LC, ILV);
369226586Sdim
370226586Sdim  if (CL->isLValue())
371234353Sdim    B.generateNode(CL, Pred, state->BindExpr(CL, LC, state->getLValue(CL, LC)));
372226586Sdim  else
373234353Sdim    B.generateNode(CL, Pred, state->BindExpr(CL, LC, ILV));
374226586Sdim}
375226586Sdim
376226586Sdimvoid ExprEngine::VisitDeclStmt(const DeclStmt *DS, ExplodedNode *Pred,
377226586Sdim                               ExplodedNodeSet &Dst) {
378226586Sdim
379226586Sdim  // FIXME: static variables may have an initializer, but the second
380226586Sdim  //  time a function is called those values may not be current.
381226586Sdim  //  This may need to be reflected in the CFG.
382226586Sdim
383226586Sdim  // Assumption: The CFG has one DeclStmt per Decl.
384226586Sdim  const Decl *D = *DS->decl_begin();
385226586Sdim
386234353Sdim  if (!D || !isa<VarDecl>(D)) {
387234353Sdim    //TODO:AZ: remove explicit insertion after refactoring is done.
388234353Sdim    Dst.insert(Pred);
389226586Sdim    return;
390234353Sdim  }
391226586Sdim
392226586Sdim  // FIXME: all pre/post visits should eventually be handled by ::Visit().
393226586Sdim  ExplodedNodeSet dstPreVisit;
394226586Sdim  getCheckerManager().runCheckersForPreStmt(dstPreVisit, Pred, DS, *this);
395226586Sdim
396234353Sdim  StmtNodeBuilder B(dstPreVisit, Dst, *currentBuilderContext);
397226586Sdim  const VarDecl *VD = dyn_cast<VarDecl>(D);
398226586Sdim  for (ExplodedNodeSet::iterator I = dstPreVisit.begin(), E = dstPreVisit.end();
399226586Sdim       I!=E; ++I) {
400226586Sdim    ExplodedNode *N = *I;
401234353Sdim    ProgramStateRef state = N->getState();
402226586Sdim
403226586Sdim    // Decls without InitExpr are not initialized explicitly.
404226586Sdim    const LocationContext *LC = N->getLocationContext();
405226586Sdim
406226586Sdim    if (const Expr *InitEx = VD->getInit()) {
407234353Sdim      SVal InitVal = state->getSVal(InitEx, Pred->getLocationContext());
408226586Sdim
409226586Sdim      // We bound the temp obj region to the CXXConstructExpr. Now recover
410226586Sdim      // the lazy compound value when the variable is not a reference.
411234353Sdim      if (AMgr.getLangOpts().CPlusPlus && VD->getType()->isRecordType() &&
412226586Sdim          !VD->getType()->isReferenceType() && isa<loc::MemRegionVal>(InitVal)){
413226586Sdim        InitVal = state->getSVal(cast<loc::MemRegionVal>(InitVal).getRegion());
414226586Sdim        assert(isa<nonloc::LazyCompoundVal>(InitVal));
415226586Sdim      }
416226586Sdim
417226586Sdim      // Recover some path-sensitivity if a scalar value evaluated to
418226586Sdim      // UnknownVal.
419234353Sdim      if (InitVal.isUnknown()) {
420234353Sdim	QualType Ty = InitEx->getType();
421234353Sdim	if (InitEx->isLValue()) {
422234353Sdim	  Ty = getContext().getPointerType(Ty);
423234353Sdim	}
424234353Sdim
425234353Sdim        InitVal = svalBuilder.getConjuredSymbolVal(NULL, InitEx, LC, Ty,
426234353Sdim                                 currentBuilderContext->getCurrentBlockCount());
427226586Sdim      }
428234353Sdim      B.takeNodes(N);
429234353Sdim      ExplodedNodeSet Dst2;
430234353Sdim      evalBind(Dst2, DS, N, state->getLValue(VD, LC), InitVal, true);
431234353Sdim      B.addNodes(Dst2);
432226586Sdim    }
433226586Sdim    else {
434234353Sdim      B.generateNode(DS, N,state->bindDeclWithNoInit(state->getRegion(VD, LC)));
435226586Sdim    }
436226586Sdim  }
437226586Sdim}
438226586Sdim
439226586Sdimvoid ExprEngine::VisitLogicalExpr(const BinaryOperator* B, ExplodedNode *Pred,
440226586Sdim                                  ExplodedNodeSet &Dst) {
441226586Sdim  assert(B->getOpcode() == BO_LAnd ||
442226586Sdim         B->getOpcode() == BO_LOr);
443234353Sdim
444234353Sdim  StmtNodeBuilder Bldr(Pred, Dst, *currentBuilderContext);
445234353Sdim  ProgramStateRef state = Pred->getState();
446234353Sdim  const LocationContext *LCtx = Pred->getLocationContext();
447234353Sdim  SVal X = state->getSVal(B, LCtx);
448226586Sdim  assert(X.isUndef());
449226586Sdim
450226586Sdim  const Expr *Ex = (const Expr*) cast<UndefinedVal>(X).getData();
451226586Sdim  assert(Ex);
452226586Sdim
453226586Sdim  if (Ex == B->getRHS()) {
454234353Sdim    X = state->getSVal(Ex, LCtx);
455226586Sdim
456226586Sdim    // Handle undefined values.
457226586Sdim    if (X.isUndef()) {
458234353Sdim      Bldr.generateNode(B, Pred, state->BindExpr(B, LCtx, X));
459226586Sdim      return;
460226586Sdim    }
461226586Sdim
462226586Sdim    DefinedOrUnknownSVal XD = cast<DefinedOrUnknownSVal>(X);
463226586Sdim
464226586Sdim    // We took the RHS.  Because the value of the '&&' or '||' expression must
465226586Sdim    // evaluate to 0 or 1, we must assume the value of the RHS evaluates to 0
466226586Sdim    // or 1.  Alternatively, we could take a lazy approach, and calculate this
467226586Sdim    // value later when necessary.  We don't have the machinery in place for
468226586Sdim    // this right now, and since most logical expressions are used for branches,
469226586Sdim    // the payoff is not likely to be large.  Instead, we do eager evaluation.
470234353Sdim    if (ProgramStateRef newState = state->assume(XD, true))
471234353Sdim      Bldr.generateNode(B, Pred,
472234353Sdim               newState->BindExpr(B, LCtx,
473234353Sdim                                  svalBuilder.makeIntVal(1U, B->getType())));
474226586Sdim
475234353Sdim    if (ProgramStateRef newState = state->assume(XD, false))
476234353Sdim      Bldr.generateNode(B, Pred,
477234353Sdim               newState->BindExpr(B, LCtx,
478234353Sdim                                  svalBuilder.makeIntVal(0U, B->getType())));
479226586Sdim  }
480226586Sdim  else {
481226586Sdim    // We took the LHS expression.  Depending on whether we are '&&' or
482226586Sdim    // '||' we know what the value of the expression is via properties of
483226586Sdim    // the short-circuiting.
484226586Sdim    X = svalBuilder.makeIntVal(B->getOpcode() == BO_LAnd ? 0U : 1U,
485226586Sdim                               B->getType());
486234353Sdim    Bldr.generateNode(B, Pred, state->BindExpr(B, LCtx, X));
487226586Sdim  }
488226586Sdim}
489226586Sdim
490226586Sdimvoid ExprEngine::VisitInitListExpr(const InitListExpr *IE,
491226586Sdim                                   ExplodedNode *Pred,
492226586Sdim                                   ExplodedNodeSet &Dst) {
493234353Sdim  StmtNodeBuilder B(Pred, Dst, *currentBuilderContext);
494226586Sdim
495234353Sdim  ProgramStateRef state = Pred->getState();
496234353Sdim  const LocationContext *LCtx = Pred->getLocationContext();
497226586Sdim  QualType T = getContext().getCanonicalType(IE->getType());
498226586Sdim  unsigned NumInitElements = IE->getNumInits();
499226586Sdim
500226586Sdim  if (T->isArrayType() || T->isRecordType() || T->isVectorType()) {
501226586Sdim    llvm::ImmutableList<SVal> vals = getBasicVals().getEmptySValList();
502226586Sdim
503226586Sdim    // Handle base case where the initializer has no elements.
504226586Sdim    // e.g: static int* myArray[] = {};
505226586Sdim    if (NumInitElements == 0) {
506226586Sdim      SVal V = svalBuilder.makeCompoundVal(T, vals);
507234353Sdim      B.generateNode(IE, Pred, state->BindExpr(IE, LCtx, V));
508226586Sdim      return;
509226586Sdim    }
510226586Sdim
511226586Sdim    for (InitListExpr::const_reverse_iterator it = IE->rbegin(),
512226586Sdim         ei = IE->rend(); it != ei; ++it) {
513234353Sdim      vals = getBasicVals().consVals(state->getSVal(cast<Expr>(*it), LCtx),
514234353Sdim                                     vals);
515226586Sdim    }
516226586Sdim
517234353Sdim    B.generateNode(IE, Pred,
518234353Sdim                   state->BindExpr(IE, LCtx,
519234353Sdim                                   svalBuilder.makeCompoundVal(T, vals)));
520226586Sdim    return;
521226586Sdim  }
522226586Sdim
523226586Sdim  if (Loc::isLocType(T) || T->isIntegerType()) {
524226586Sdim    assert(IE->getNumInits() == 1);
525226586Sdim    const Expr *initEx = IE->getInit(0);
526234353Sdim    B.generateNode(IE, Pred, state->BindExpr(IE, LCtx,
527234353Sdim                                             state->getSVal(initEx, LCtx)));
528226586Sdim    return;
529226586Sdim  }
530226586Sdim
531226586Sdim  llvm_unreachable("unprocessed InitListExpr type");
532226586Sdim}
533226586Sdim
534226586Sdimvoid ExprEngine::VisitGuardedExpr(const Expr *Ex,
535226586Sdim                                  const Expr *L,
536226586Sdim                                  const Expr *R,
537226586Sdim                                  ExplodedNode *Pred,
538226586Sdim                                  ExplodedNodeSet &Dst) {
539234353Sdim  StmtNodeBuilder B(Pred, Dst, *currentBuilderContext);
540226586Sdim
541234353Sdim  ProgramStateRef state = Pred->getState();
542234353Sdim  const LocationContext *LCtx = Pred->getLocationContext();
543234353Sdim  SVal X = state->getSVal(Ex, LCtx);
544226586Sdim  assert (X.isUndef());
545226586Sdim  const Expr *SE = (Expr*) cast<UndefinedVal>(X).getData();
546226586Sdim  assert(SE);
547234353Sdim  X = state->getSVal(SE, LCtx);
548226586Sdim
549226586Sdim  // Make sure that we invalidate the previous binding.
550234353Sdim  B.generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, X, true));
551226586Sdim}
552226586Sdim
553226586Sdimvoid ExprEngine::
554226586SdimVisitOffsetOfExpr(const OffsetOfExpr *OOE,
555226586Sdim                  ExplodedNode *Pred, ExplodedNodeSet &Dst) {
556234353Sdim  StmtNodeBuilder B(Pred, Dst, *currentBuilderContext);
557234353Sdim  APSInt IV;
558234353Sdim  if (OOE->EvaluateAsInt(IV, getContext())) {
559226586Sdim    assert(IV.getBitWidth() == getContext().getTypeSize(OOE->getType()));
560226586Sdim    assert(OOE->getType()->isIntegerType());
561226586Sdim    assert(IV.isSigned() == OOE->getType()->isSignedIntegerOrEnumerationType());
562226586Sdim    SVal X = svalBuilder.makeIntVal(IV);
563234353Sdim    B.generateNode(OOE, Pred,
564234353Sdim                   Pred->getState()->BindExpr(OOE, Pred->getLocationContext(),
565234353Sdim                                              X));
566226586Sdim  }
567226586Sdim  // FIXME: Handle the case where __builtin_offsetof is not a constant.
568226586Sdim}
569226586Sdim
570226586Sdim
571226586Sdimvoid ExprEngine::
572226586SdimVisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Ex,
573226586Sdim                              ExplodedNode *Pred,
574226586Sdim                              ExplodedNodeSet &Dst) {
575234353Sdim  StmtNodeBuilder Bldr(Pred, Dst, *currentBuilderContext);
576226586Sdim
577226586Sdim  QualType T = Ex->getTypeOfArgument();
578226586Sdim
579226586Sdim  if (Ex->getKind() == UETT_SizeOf) {
580226586Sdim    if (!T->isIncompleteType() && !T->isConstantSizeType()) {
581226586Sdim      assert(T->isVariableArrayType() && "Unknown non-constant-sized type.");
582226586Sdim
583226586Sdim      // FIXME: Add support for VLA type arguments and VLA expressions.
584226586Sdim      // When that happens, we should probably refactor VLASizeChecker's code.
585226586Sdim      return;
586226586Sdim    }
587226586Sdim    else if (T->getAs<ObjCObjectType>()) {
588226586Sdim      // Some code tries to take the sizeof an ObjCObjectType, relying that
589226586Sdim      // the compiler has laid out its representation.  Just report Unknown
590226586Sdim      // for these.
591226586Sdim      return;
592226586Sdim    }
593226586Sdim  }
594226586Sdim
595234353Sdim  APSInt Value = Ex->EvaluateKnownConstInt(getContext());
596234353Sdim  CharUnits amt = CharUnits::fromQuantity(Value.getZExtValue());
597226586Sdim
598234353Sdim  ProgramStateRef state = Pred->getState();
599234353Sdim  state = state->BindExpr(Ex, Pred->getLocationContext(),
600234353Sdim                          svalBuilder.makeIntVal(amt.getQuantity(),
601226586Sdim                                                     Ex->getType()));
602234353Sdim  Bldr.generateNode(Ex, Pred, state);
603226586Sdim}
604226586Sdim
605226586Sdimvoid ExprEngine::VisitUnaryOperator(const UnaryOperator* U,
606226586Sdim                                    ExplodedNode *Pred,
607234353Sdim                                    ExplodedNodeSet &Dst) {
608234353Sdim  StmtNodeBuilder Bldr(Pred, Dst, *currentBuilderContext);
609226586Sdim  switch (U->getOpcode()) {
610234353Sdim    default: {
611234353Sdim      Bldr.takeNodes(Pred);
612234353Sdim      ExplodedNodeSet Tmp;
613234353Sdim      VisitIncrementDecrementOperator(U, Pred, Tmp);
614234353Sdim      Bldr.addNodes(Tmp);
615234353Sdim    }
616226586Sdim      break;
617226586Sdim    case UO_Real: {
618226586Sdim      const Expr *Ex = U->getSubExpr()->IgnoreParens();
619226586Sdim
620234353Sdim      // FIXME: We don't have complex SValues yet.
621234353Sdim      if (Ex->getType()->isAnyComplexType()) {
622234353Sdim        // Just report "Unknown."
623234353Sdim        break;
624234353Sdim      }
625226586Sdim
626234353Sdim      // For all other types, UO_Real is an identity operation.
627234353Sdim      assert (U->getType() == Ex->getType());
628234353Sdim      ProgramStateRef state = Pred->getState();
629234353Sdim      const LocationContext *LCtx = Pred->getLocationContext();
630234353Sdim      Bldr.generateNode(U, Pred, state->BindExpr(U, LCtx,
631234353Sdim                                                 state->getSVal(Ex, LCtx)));
632234353Sdim      break;
633226586Sdim    }
634226586Sdim
635234353Sdim    case UO_Imag: {
636226586Sdim      const Expr *Ex = U->getSubExpr()->IgnoreParens();
637234353Sdim      // FIXME: We don't have complex SValues yet.
638234353Sdim      if (Ex->getType()->isAnyComplexType()) {
639234353Sdim        // Just report "Unknown."
640234353Sdim        break;
641226586Sdim      }
642234353Sdim      // For all other types, UO_Imag returns 0.
643234353Sdim      ProgramStateRef state = Pred->getState();
644234353Sdim      const LocationContext *LCtx = Pred->getLocationContext();
645234353Sdim      SVal X = svalBuilder.makeZeroVal(Ex->getType());
646234353Sdim      Bldr.generateNode(U, Pred, state->BindExpr(U, LCtx, X));
647234353Sdim      break;
648226586Sdim    }
649226586Sdim
650226586Sdim    case UO_Plus:
651226586Sdim      assert(!U->isLValue());
652226586Sdim      // FALL-THROUGH.
653226586Sdim    case UO_Deref:
654226586Sdim    case UO_AddrOf:
655226586Sdim    case UO_Extension: {
656234353Sdim      // FIXME: We can probably just have some magic in Environment::getSVal()
657234353Sdim      // that propagates values, instead of creating a new node here.
658234353Sdim      //
659226586Sdim      // Unary "+" is a no-op, similar to a parentheses.  We still have places
660226586Sdim      // where it may be a block-level expression, so we need to
661226586Sdim      // generate an extra node that just propagates the value of the
662234353Sdim      // subexpression.
663226586Sdim      const Expr *Ex = U->getSubExpr()->IgnoreParens();
664234353Sdim      ProgramStateRef state = Pred->getState();
665234353Sdim      const LocationContext *LCtx = Pred->getLocationContext();
666234353Sdim      Bldr.generateNode(U, Pred, state->BindExpr(U, LCtx,
667234353Sdim                                                 state->getSVal(Ex, LCtx)));
668234353Sdim      break;
669226586Sdim    }
670226586Sdim
671226586Sdim    case UO_LNot:
672226586Sdim    case UO_Minus:
673226586Sdim    case UO_Not: {
674226586Sdim      assert (!U->isLValue());
675226586Sdim      const Expr *Ex = U->getSubExpr()->IgnoreParens();
676234353Sdim      ProgramStateRef state = Pred->getState();
677234353Sdim      const LocationContext *LCtx = Pred->getLocationContext();
678226586Sdim
679234353Sdim      // Get the value of the subexpression.
680234353Sdim      SVal V = state->getSVal(Ex, LCtx);
681226586Sdim
682234353Sdim      if (V.isUnknownOrUndef()) {
683234353Sdim        Bldr.generateNode(U, Pred, state->BindExpr(U, LCtx, V));
684234353Sdim        break;
685234353Sdim      }
686226586Sdim
687234353Sdim      switch (U->getOpcode()) {
688234353Sdim        default:
689234353Sdim          llvm_unreachable("Invalid Opcode.");
690234353Sdim        case UO_Not:
691234353Sdim          // FIXME: Do we need to handle promotions?
692234353Sdim          state = state->BindExpr(U, LCtx, evalComplement(cast<NonLoc>(V)));
693234353Sdim          break;
694234353Sdim        case UO_Minus:
695234353Sdim          // FIXME: Do we need to handle promotions?
696234353Sdim          state = state->BindExpr(U, LCtx, evalMinus(cast<NonLoc>(V)));
697234353Sdim          break;
698234353Sdim        case UO_LNot:
699234353Sdim          // C99 6.5.3.3: "The expression !E is equivalent to (0==E)."
700234353Sdim          //
701234353Sdim          //  Note: technically we do "E == 0", but this is the same in the
702234353Sdim          //    transfer functions as "0 == E".
703234353Sdim          SVal Result;
704234353Sdim          if (isa<Loc>(V)) {
705234353Sdim            Loc X = svalBuilder.makeNull();
706234353Sdim            Result = evalBinOp(state, BO_EQ, cast<Loc>(V), X,
707234353Sdim                               U->getType());
708234353Sdim          }
709234353Sdim          else {
710234353Sdim            nonloc::ConcreteInt X(getBasicVals().getValue(0, Ex->getType()));
711234353Sdim            Result = evalBinOp(state, BO_EQ, cast<NonLoc>(V), X,
712234353Sdim                               U->getType());
713234353Sdim          }
714234353Sdim
715234353Sdim          state = state->BindExpr(U, LCtx, Result);
716234353Sdim          break;
717226586Sdim      }
718234353Sdim      Bldr.generateNode(U, Pred, state);
719234353Sdim      break;
720226586Sdim    }
721226586Sdim  }
722234353Sdim
723234353Sdim}
724234353Sdim
725234353Sdimvoid ExprEngine::VisitIncrementDecrementOperator(const UnaryOperator* U,
726234353Sdim                                                 ExplodedNode *Pred,
727234353Sdim                                                 ExplodedNodeSet &Dst) {
728226586Sdim  // Handle ++ and -- (both pre- and post-increment).
729226586Sdim  assert (U->isIncrementDecrementOp());
730226586Sdim  const Expr *Ex = U->getSubExpr()->IgnoreParens();
731226586Sdim
732234353Sdim  const LocationContext *LCtx = Pred->getLocationContext();
733234353Sdim  ProgramStateRef state = Pred->getState();
734234353Sdim  SVal loc = state->getSVal(Ex, LCtx);
735234353Sdim
736234353Sdim  // Perform a load.
737234353Sdim  ExplodedNodeSet Tmp;
738234353Sdim  evalLoad(Tmp, U, Ex, Pred, state, loc);
739234353Sdim
740234353Sdim  ExplodedNodeSet Dst2;
741234353Sdim  StmtNodeBuilder Bldr(Tmp, Dst2, *currentBuilderContext);
742234353Sdim  for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end();I!=E;++I) {
743226586Sdim
744234353Sdim    state = (*I)->getState();
745234353Sdim    assert(LCtx == (*I)->getLocationContext());
746234353Sdim    SVal V2_untested = state->getSVal(Ex, LCtx);
747226586Sdim
748234353Sdim    // Propagate unknown and undefined values.
749234353Sdim    if (V2_untested.isUnknownOrUndef()) {
750234353Sdim      Bldr.generateNode(U, *I, state->BindExpr(U, LCtx, V2_untested));
751234353Sdim      continue;
752234353Sdim    }
753234353Sdim    DefinedSVal V2 = cast<DefinedSVal>(V2_untested);
754226586Sdim
755234353Sdim    // Handle all other values.
756234353Sdim    BinaryOperator::Opcode Op = U->isIncrementOp() ? BO_Add : BO_Sub;
757234353Sdim
758234353Sdim    // If the UnaryOperator has non-location type, use its type to create the
759234353Sdim    // constant value. If the UnaryOperator has location type, create the
760234353Sdim    // constant with int type and pointer width.
761234353Sdim    SVal RHS;
762234353Sdim
763234353Sdim    if (U->getType()->isAnyPointerType())
764234353Sdim      RHS = svalBuilder.makeArrayIndex(1);
765234353Sdim    else
766234353Sdim      RHS = svalBuilder.makeIntVal(1, U->getType());
767234353Sdim
768234353Sdim    SVal Result = evalBinOp(state, Op, V2, RHS, U->getType());
769234353Sdim
770234353Sdim    // Conjure a new symbol if necessary to recover precision.
771234353Sdim    if (Result.isUnknown()){
772234353Sdim      DefinedOrUnknownSVal SymVal =
773234353Sdim	svalBuilder.getConjuredSymbolVal(NULL, Ex, LCtx,
774234353Sdim                               currentBuilderContext->getCurrentBlockCount());
775234353Sdim      Result = SymVal;
776226586Sdim
777234353Sdim      // If the value is a location, ++/-- should always preserve
778234353Sdim      // non-nullness.  Check if the original value was non-null, and if so
779234353Sdim      // propagate that constraint.
780234353Sdim      if (Loc::isLocType(U->getType())) {
781234353Sdim        DefinedOrUnknownSVal Constraint =
782234353Sdim        svalBuilder.evalEQ(state, V2,svalBuilder.makeZeroVal(U->getType()));
783226586Sdim
784234353Sdim        if (!state->assume(Constraint, true)) {
785234353Sdim          // It isn't feasible for the original value to be null.
786234353Sdim          // Propagate this constraint.
787234353Sdim          Constraint = svalBuilder.evalEQ(state, SymVal,
788234353Sdim                                       svalBuilder.makeZeroVal(U->getType()));
789226586Sdim
790234353Sdim
791234353Sdim          state = state->assume(Constraint, false);
792234353Sdim          assert(state);
793226586Sdim        }
794226586Sdim      }
795226586Sdim    }
796234353Sdim
797234353Sdim    // Since the lvalue-to-rvalue conversion is explicit in the AST,
798234353Sdim    // we bind an l-value if the operator is prefix and an lvalue (in C++).
799234353Sdim    if (U->isLValue())
800234353Sdim      state = state->BindExpr(U, LCtx, loc);
801234353Sdim    else
802234353Sdim      state = state->BindExpr(U, LCtx, U->isPostfix() ? V2 : Result);
803234353Sdim
804234353Sdim    // Perform the store.
805234353Sdim    Bldr.takeNodes(*I);
806234353Sdim    ExplodedNodeSet Dst3;
807234353Sdim    evalStore(Dst3, U, U, *I, state, loc, Result);
808234353Sdim    Bldr.addNodes(Dst3);
809226586Sdim  }
810234353Sdim  Dst.insert(Dst2);
811226586Sdim}
812