ExprEngine.cpp revision 5344baa704f42b22d9df25c24ffbbf6b4716603b
1//=-- ExprEngine.cpp - Path-Sensitive Expression-Level Dataflow ---*- C++ -*-=
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10//  This file defines a meta-engine for path-sensitive dataflow analysis that
11//  is built on GREngine, but provides the boilerplate to execute transfer
12//  functions and build the ExplodedGraph at the expression level.
13//
14//===----------------------------------------------------------------------===//
15
16#include "clang/StaticAnalyzer/Core/CheckerManager.h"
17#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
18#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
19#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
20#include "clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h"
21#include "clang/AST/CharUnits.h"
22#include "clang/AST/ParentMap.h"
23#include "clang/AST/StmtObjC.h"
24#include "clang/AST/DeclCXX.h"
25#include "clang/Basic/Builtins.h"
26#include "clang/Basic/SourceManager.h"
27#include "clang/Basic/SourceManager.h"
28#include "clang/Basic/PrettyStackTrace.h"
29#include "llvm/Support/raw_ostream.h"
30#include "llvm/ADT/ImmutableList.h"
31
32#ifndef NDEBUG
33#include "llvm/Support/GraphWriter.h"
34#endif
35
36using namespace clang;
37using namespace ento;
38using llvm::APSInt;
39
40//===----------------------------------------------------------------------===//
41// Utility functions.
42//===----------------------------------------------------------------------===//
43
44static inline Selector GetNullarySelector(const char* name, ASTContext &Ctx) {
45  IdentifierInfo* II = &Ctx.Idents.get(name);
46  return Ctx.Selectors.getSelector(0, &II);
47}
48
49//===----------------------------------------------------------------------===//
50// Engine construction and deletion.
51//===----------------------------------------------------------------------===//
52
53ExprEngine::ExprEngine(AnalysisManager &mgr, bool gcEnabled)
54  : AMgr(mgr),
55    AnalysisDeclContexts(mgr.getAnalysisDeclContextManager()),
56    Engine(*this),
57    G(Engine.getGraph()),
58    StateMgr(getContext(), mgr.getStoreManagerCreator(),
59             mgr.getConstraintManagerCreator(), G.getAllocator(),
60             *this),
61    SymMgr(StateMgr.getSymbolManager()),
62    svalBuilder(StateMgr.getSValBuilder()),
63    EntryNode(NULL),
64    currentStmt(NULL), currentStmtIdx(0), currentBuilderContext(0),
65    NSExceptionII(NULL), NSExceptionInstanceRaiseSelectors(NULL),
66    RaiseSel(GetNullarySelector("raise", getContext())),
67    ObjCGCEnabled(gcEnabled), BR(mgr, *this) {
68
69  if (mgr.shouldEagerlyTrimExplodedGraph()) {
70    // Enable eager node reclaimation when constructing the ExplodedGraph.
71    G.enableNodeReclamation();
72  }
73}
74
75ExprEngine::~ExprEngine() {
76  BR.FlushReports();
77  delete [] NSExceptionInstanceRaiseSelectors;
78}
79
80//===----------------------------------------------------------------------===//
81// Utility methods.
82//===----------------------------------------------------------------------===//
83
84const ProgramState *ExprEngine::getInitialState(const LocationContext *InitLoc) {
85  const ProgramState *state = StateMgr.getInitialState(InitLoc);
86  const Decl *D = InitLoc->getDecl();
87
88  // Preconditions.
89  // FIXME: It would be nice if we had a more general mechanism to add
90  // such preconditions.  Some day.
91  do {
92
93    if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
94      // Precondition: the first argument of 'main' is an integer guaranteed
95      //  to be > 0.
96      const IdentifierInfo *II = FD->getIdentifier();
97      if (!II || !(II->getName() == "main" && FD->getNumParams() > 0))
98        break;
99
100      const ParmVarDecl *PD = FD->getParamDecl(0);
101      QualType T = PD->getType();
102      if (!T->isIntegerType())
103        break;
104
105      const MemRegion *R = state->getRegion(PD, InitLoc);
106      if (!R)
107        break;
108
109      SVal V = state->getSVal(loc::MemRegionVal(R));
110      SVal Constraint_untested = evalBinOp(state, BO_GT, V,
111                                           svalBuilder.makeZeroVal(T),
112                                           getContext().IntTy);
113
114      DefinedOrUnknownSVal *Constraint =
115        dyn_cast<DefinedOrUnknownSVal>(&Constraint_untested);
116
117      if (!Constraint)
118        break;
119
120      if (const ProgramState *newState = state->assume(*Constraint, true))
121        state = newState;
122    }
123    break;
124  }
125  while (0);
126
127  if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
128    // Precondition: 'self' is always non-null upon entry to an Objective-C
129    // method.
130    const ImplicitParamDecl *SelfD = MD->getSelfDecl();
131    const MemRegion *R = state->getRegion(SelfD, InitLoc);
132    SVal V = state->getSVal(loc::MemRegionVal(R));
133
134    if (const Loc *LV = dyn_cast<Loc>(&V)) {
135      // Assume that the pointer value in 'self' is non-null.
136      state = state->assume(*LV, true);
137      assert(state && "'self' cannot be null");
138    }
139  }
140
141  if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) {
142    if (!MD->isStatic()) {
143      // Precondition: 'this' is always non-null upon entry to the
144      // top-level function.  This is our starting assumption for
145      // analyzing an "open" program.
146      const StackFrameContext *SFC = InitLoc->getCurrentStackFrame();
147      if (SFC->getParent() == 0) {
148        loc::MemRegionVal L(getCXXThisRegion(MD, SFC));
149        SVal V = state->getSVal(L);
150        if (const Loc *LV = dyn_cast<Loc>(&V)) {
151          state = state->assume(*LV, true);
152          assert(state && "'this' cannot be null");
153        }
154      }
155    }
156  }
157
158  return state;
159}
160
161bool
162ExprEngine::doesInvalidateGlobals(const CallOrObjCMessage &callOrMessage) const
163{
164  if (callOrMessage.isFunctionCall() && !callOrMessage.isCXXCall()) {
165    SVal calleeV = callOrMessage.getFunctionCallee();
166    if (const FunctionTextRegion *codeR =
167          dyn_cast_or_null<FunctionTextRegion>(calleeV.getAsRegion())) {
168
169      const FunctionDecl *fd = codeR->getDecl();
170      if (const IdentifierInfo *ii = fd->getIdentifier()) {
171        StringRef fname = ii->getName();
172        if (fname == "strlen")
173          return false;
174      }
175    }
176  }
177
178  // The conservative answer: invalidates globals.
179  return true;
180}
181
182//===----------------------------------------------------------------------===//
183// Top-level transfer function logic (Dispatcher).
184//===----------------------------------------------------------------------===//
185
186/// evalAssume - Called by ConstraintManager. Used to call checker-specific
187///  logic for handling assumptions on symbolic values.
188const ProgramState *ExprEngine::processAssume(const ProgramState *state,
189                                              SVal cond, bool assumption) {
190  return getCheckerManager().runCheckersForEvalAssume(state, cond, assumption);
191}
192
193bool ExprEngine::wantsRegionChangeUpdate(const ProgramState *state) {
194  return getCheckerManager().wantsRegionChangeUpdate(state);
195}
196
197const ProgramState *
198ExprEngine::processRegionChanges(const ProgramState *state,
199                            const StoreManager::InvalidatedSymbols *invalidated,
200                                 ArrayRef<const MemRegion *> Explicits,
201                                 ArrayRef<const MemRegion *> Regions) {
202  return getCheckerManager().runCheckersForRegionChanges(state, invalidated,
203                                                         Explicits, Regions);
204}
205
206void ExprEngine::printState(raw_ostream &Out, const ProgramState *State,
207                            const char *NL, const char *Sep) {
208  getCheckerManager().runCheckersForPrintState(Out, State, NL, Sep);
209}
210
211void ExprEngine::processEndWorklist(bool hasWorkRemaining) {
212  getCheckerManager().runCheckersForEndAnalysis(G, BR, *this);
213}
214
215void ExprEngine::processCFGElement(const CFGElement E, ExplodedNode *Pred,
216                                   unsigned StmtIdx, NodeBuilderContext *Ctx) {
217  currentStmtIdx = StmtIdx;
218  currentBuilderContext = Ctx;
219
220  switch (E.getKind()) {
221    case CFGElement::Invalid:
222      llvm_unreachable("Unexpected CFGElement kind.");
223    case CFGElement::Statement:
224      ProcessStmt(const_cast<Stmt*>(E.getAs<CFGStmt>()->getStmt()), Pred);
225      return;
226    case CFGElement::Initializer:
227      ProcessInitializer(E.getAs<CFGInitializer>()->getInitializer(), Pred);
228      return;
229    case CFGElement::AutomaticObjectDtor:
230    case CFGElement::BaseDtor:
231    case CFGElement::MemberDtor:
232    case CFGElement::TemporaryDtor:
233      ProcessImplicitDtor(*E.getAs<CFGImplicitDtor>(), Pred);
234      return;
235  }
236  currentStmtIdx = 0;
237  currentBuilderContext = 0;
238}
239
240static bool shouldRemoveDeadBindings(AnalysisManager &AMgr,
241                                     const CFGStmt S,
242                                     const ExplodedNode *Pred,
243                                     const LocationContext *LC) {
244
245  // Are we never purging state values?
246  if (AMgr.getPurgeMode() == PurgeNone)
247    return false;
248
249  // Is this the beginning of a basic block?
250  if (isa<BlockEntrance>(Pred->getLocation()))
251    return true;
252
253  // Is this on a non-expression?
254  if (!isa<Expr>(S.getStmt()))
255    return true;
256
257  // Is this an expression that is consumed by another expression?  If so,
258  // postpone cleaning out the state.
259  ParentMap &PM = LC->getAnalysisDeclContext()->getParentMap();
260  return !PM.isConsumedExpr(cast<Expr>(S.getStmt()));
261}
262
263void ExprEngine::ProcessStmt(const CFGStmt S,
264                             ExplodedNode *Pred) {
265  // TODO: Use RAII to remove the unnecessary, tagged nodes.
266  //RegisterCreatedNodes registerCreatedNodes(getGraph());
267
268  // Reclaim any unnecessary nodes in the ExplodedGraph.
269  G.reclaimRecentlyAllocatedNodes();
270  // Recycle any unused states in the ProgramStateManager.
271  StateMgr.recycleUnusedStates();
272
273  currentStmt = S.getStmt();
274  PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),
275                                currentStmt->getLocStart(),
276                                "Error evaluating statement");
277
278  EntryNode = Pred;
279
280  const ProgramState *EntryState = EntryNode->getState();
281  CleanedState = EntryState;
282
283  // Create the cleaned state.
284  const LocationContext *LC = EntryNode->getLocationContext();
285  SymbolReaper SymReaper(LC, currentStmt, SymMgr, getStoreManager());
286
287  if (shouldRemoveDeadBindings(AMgr, S, Pred, LC)) {
288    getCheckerManager().runCheckersForLiveSymbols(CleanedState, SymReaper);
289
290    const StackFrameContext *SFC = LC->getCurrentStackFrame();
291
292    // Create a state in which dead bindings are removed from the environment
293    // and the store. TODO: The function should just return new env and store,
294    // not a new state.
295    CleanedState = StateMgr.removeDeadBindings(CleanedState, SFC, SymReaper);
296  }
297
298  // Process any special transfer function for dead symbols.
299  ExplodedNodeSet Tmp;
300  // A tag to track convenience transitions, which can be removed at cleanup.
301  static SimpleProgramPointTag cleanupTag("ExprEngine : Clean Node");
302
303  if (!SymReaper.hasDeadSymbols()) {
304    // Generate a CleanedNode that has the environment and store cleaned
305    // up. Since no symbols are dead, we can optimize and not clean out
306    // the constraint manager.
307    StmtNodeBuilder Bldr(Pred, Tmp, *currentBuilderContext);
308    Bldr.generateNode(currentStmt, EntryNode, CleanedState, false, &cleanupTag);
309
310  } else {
311    // Call checkers with the non-cleaned state so that they could query the
312    // values of the soon to be dead symbols.
313    ExplodedNodeSet CheckedSet;
314    getCheckerManager().runCheckersForDeadSymbols(CheckedSet, EntryNode,
315                                                 SymReaper, currentStmt, *this);
316
317    // For each node in CheckedSet, generate CleanedNodes that have the
318    // environment, the store, and the constraints cleaned up but have the
319    // user-supplied states as the predecessors.
320    StmtNodeBuilder Bldr(CheckedSet, Tmp, *currentBuilderContext);
321    for (ExplodedNodeSet::const_iterator
322          I = CheckedSet.begin(), E = CheckedSet.end(); I != E; ++I) {
323      const ProgramState *CheckerState = (*I)->getState();
324
325      // The constraint manager has not been cleaned up yet, so clean up now.
326      CheckerState = getConstraintManager().removeDeadBindings(CheckerState,
327                                                               SymReaper);
328
329      assert(StateMgr.haveEqualEnvironments(CheckerState, EntryState) &&
330        "Checkers are not allowed to modify the Environment as a part of "
331        "checkDeadSymbols processing.");
332      assert(StateMgr.haveEqualStores(CheckerState, EntryState) &&
333        "Checkers are not allowed to modify the Store as a part of "
334        "checkDeadSymbols processing.");
335
336      // Create a state based on CleanedState with CheckerState GDM and
337      // generate a transition to that state.
338      const ProgramState *CleanedCheckerSt =
339        StateMgr.getPersistentStateWithGDM(CleanedState, CheckerState);
340      Bldr.generateNode(currentStmt, *I, CleanedCheckerSt, false, &cleanupTag,
341                        ProgramPoint::PostPurgeDeadSymbolsKind);
342    }
343  }
344
345  ExplodedNodeSet Dst;
346  for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
347    ExplodedNodeSet DstI;
348    // Visit the statement.
349    Visit(currentStmt, *I, DstI);
350    Dst.insert(DstI);
351  }
352
353  // Enqueue the new nodes onto the work list.
354  Engine.enqueue(Dst, currentBuilderContext->getBlock(), currentStmtIdx);
355
356  // NULL out these variables to cleanup.
357  CleanedState = NULL;
358  EntryNode = NULL;
359  currentStmt = 0;
360}
361
362void ExprEngine::ProcessInitializer(const CFGInitializer Init,
363                                    ExplodedNode *Pred) {
364  ExplodedNodeSet Dst;
365
366  // We don't set EntryNode and currentStmt. And we don't clean up state.
367  const CXXCtorInitializer *BMI = Init.getInitializer();
368  const StackFrameContext *stackFrame =
369                           cast<StackFrameContext>(Pred->getLocationContext());
370  const CXXConstructorDecl *decl =
371                           cast<CXXConstructorDecl>(stackFrame->getDecl());
372  const CXXThisRegion *thisReg = getCXXThisRegion(decl, stackFrame);
373
374  SVal thisVal = Pred->getState()->getSVal(thisReg);
375
376  if (BMI->isAnyMemberInitializer()) {
377    ExplodedNodeSet AfterEval;
378
379    // Evaluate the initializer.
380    Visit(BMI->getInit(), Pred, AfterEval);
381
382    StmtNodeBuilder Bldr(AfterEval, Dst, *currentBuilderContext);
383    for (ExplodedNodeSet::iterator I = AfterEval.begin(),
384                                   E = AfterEval.end(); I != E; ++I){
385      ExplodedNode *P = *I;
386      const ProgramState *state = P->getState();
387
388      const FieldDecl *FD = BMI->getAnyMember();
389
390      SVal FieldLoc = state->getLValue(FD, thisVal);
391      SVal InitVal = state->getSVal(BMI->getInit());
392      state = state->bindLoc(FieldLoc, InitVal);
393
394      // Use a custom node building process.
395      PostInitializer PP(BMI, stackFrame);
396      // Builder automatically add the generated node to the deferred set,
397      // which are processed in the builder's dtor.
398      Bldr.generateNode(PP, P, state);
399    }
400  } else {
401    assert(BMI->isBaseInitializer());
402
403    // Get the base class declaration.
404    const CXXConstructExpr *ctorExpr = cast<CXXConstructExpr>(BMI->getInit());
405
406    // Create the base object region.
407    SVal baseVal =
408        getStoreManager().evalDerivedToBase(thisVal, ctorExpr->getType());
409    const MemRegion *baseReg = baseVal.getAsRegion();
410    assert(baseReg);
411
412    VisitCXXConstructExpr(ctorExpr, baseReg, Pred, Dst);
413  }
414
415  // Enqueue the new nodes onto the work list.
416  Engine.enqueue(Dst, currentBuilderContext->getBlock(), currentStmtIdx);
417}
418
419void ExprEngine::ProcessImplicitDtor(const CFGImplicitDtor D,
420                                     ExplodedNode *Pred) {
421  ExplodedNodeSet Dst;
422  switch (D.getKind()) {
423  case CFGElement::AutomaticObjectDtor:
424    ProcessAutomaticObjDtor(cast<CFGAutomaticObjDtor>(D), Pred, Dst);
425    break;
426  case CFGElement::BaseDtor:
427    ProcessBaseDtor(cast<CFGBaseDtor>(D), Pred, Dst);
428    break;
429  case CFGElement::MemberDtor:
430    ProcessMemberDtor(cast<CFGMemberDtor>(D), Pred, Dst);
431    break;
432  case CFGElement::TemporaryDtor:
433    ProcessTemporaryDtor(cast<CFGTemporaryDtor>(D), Pred, Dst);
434    break;
435  default:
436    llvm_unreachable("Unexpected dtor kind.");
437  }
438
439  // Enqueue the new nodes onto the work list.
440  Engine.enqueue(Dst, currentBuilderContext->getBlock(), currentStmtIdx);
441}
442
443void ExprEngine::ProcessAutomaticObjDtor(const CFGAutomaticObjDtor Dtor,
444                                         ExplodedNode *Pred,
445                                         ExplodedNodeSet &Dst) {
446  const ProgramState *state = Pred->getState();
447  const VarDecl *varDecl = Dtor.getVarDecl();
448
449  QualType varType = varDecl->getType();
450
451  if (const ReferenceType *refType = varType->getAs<ReferenceType>())
452    varType = refType->getPointeeType();
453
454  const CXXRecordDecl *recordDecl = varType->getAsCXXRecordDecl();
455  assert(recordDecl && "get CXXRecordDecl fail");
456  const CXXDestructorDecl *dtorDecl = recordDecl->getDestructor();
457
458  Loc dest = state->getLValue(varDecl, Pred->getLocationContext());
459
460  VisitCXXDestructor(dtorDecl, cast<loc::MemRegionVal>(dest).getRegion(),
461                     Dtor.getTriggerStmt(), Pred, Dst);
462}
463
464void ExprEngine::ProcessBaseDtor(const CFGBaseDtor D,
465                                 ExplodedNode *Pred, ExplodedNodeSet &Dst) {}
466
467void ExprEngine::ProcessMemberDtor(const CFGMemberDtor D,
468                                   ExplodedNode *Pred, ExplodedNodeSet &Dst) {}
469
470void ExprEngine::ProcessTemporaryDtor(const CFGTemporaryDtor D,
471                                      ExplodedNode *Pred,
472                                      ExplodedNodeSet &Dst) {}
473
474void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
475                       ExplodedNodeSet &DstTop) {
476  PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),
477                                S->getLocStart(),
478                                "Error evaluating statement");
479  ExplodedNodeSet Dst;
480  StmtNodeBuilder Bldr(Pred, DstTop, *currentBuilderContext);
481
482  // Expressions to ignore.
483  if (const Expr *Ex = dyn_cast<Expr>(S))
484    S = Ex->IgnoreParens();
485
486  // FIXME: add metadata to the CFG so that we can disable
487  //  this check when we KNOW that there is no block-level subexpression.
488  //  The motivation is that this check requires a hashtable lookup.
489
490  if (S != currentStmt && Pred->getLocationContext()->getCFG()->isBlkExpr(S))
491    return;
492
493  switch (S->getStmtClass()) {
494    // C++ and ARC stuff we don't support yet.
495    case Expr::ObjCIndirectCopyRestoreExprClass:
496    case Stmt::CXXBindTemporaryExprClass:
497    case Stmt::CXXCatchStmtClass:
498    case Stmt::CXXDependentScopeMemberExprClass:
499    case Stmt::CXXPseudoDestructorExprClass:
500    case Stmt::CXXThrowExprClass:
501    case Stmt::CXXTryStmtClass:
502    case Stmt::CXXTypeidExprClass:
503    case Stmt::CXXUuidofExprClass:
504    case Stmt::CXXUnresolvedConstructExprClass:
505    case Stmt::CXXScalarValueInitExprClass:
506    case Stmt::DependentScopeDeclRefExprClass:
507    case Stmt::UnaryTypeTraitExprClass:
508    case Stmt::BinaryTypeTraitExprClass:
509    case Stmt::ArrayTypeTraitExprClass:
510    case Stmt::ExpressionTraitExprClass:
511    case Stmt::UnresolvedLookupExprClass:
512    case Stmt::UnresolvedMemberExprClass:
513    case Stmt::CXXNoexceptExprClass:
514    case Stmt::PackExpansionExprClass:
515    case Stmt::SubstNonTypeTemplateParmPackExprClass:
516    case Stmt::SEHTryStmtClass:
517    case Stmt::SEHExceptStmtClass:
518    case Stmt::SEHFinallyStmtClass: {
519      const ExplodedNode *node = Bldr.generateNode(S, Pred, Pred->getState());
520      Engine.addAbortedBlock(node, currentBuilderContext->getBlock());
521      break;
522    }
523
524    // We don't handle default arguments either yet, but we can fake it
525    // for now by just skipping them.
526    case Stmt::SubstNonTypeTemplateParmExprClass:
527    case Stmt::CXXDefaultArgExprClass:
528      break;
529
530    case Stmt::ParenExprClass:
531      llvm_unreachable("ParenExprs already handled.");
532    case Stmt::GenericSelectionExprClass:
533      llvm_unreachable("GenericSelectionExprs already handled.");
534    // Cases that should never be evaluated simply because they shouldn't
535    // appear in the CFG.
536    case Stmt::BreakStmtClass:
537    case Stmt::CaseStmtClass:
538    case Stmt::CompoundStmtClass:
539    case Stmt::ContinueStmtClass:
540    case Stmt::CXXForRangeStmtClass:
541    case Stmt::DefaultStmtClass:
542    case Stmt::DoStmtClass:
543    case Stmt::ForStmtClass:
544    case Stmt::GotoStmtClass:
545    case Stmt::IfStmtClass:
546    case Stmt::IndirectGotoStmtClass:
547    case Stmt::LabelStmtClass:
548    case Stmt::NoStmtClass:
549    case Stmt::NullStmtClass:
550    case Stmt::SwitchStmtClass:
551    case Stmt::WhileStmtClass:
552    case Expr::MSDependentExistsStmtClass:
553      llvm_unreachable("Stmt should not be in analyzer evaluation loop");
554      break;
555
556    case Stmt::GNUNullExprClass: {
557      // GNU __null is a pointer-width integer, not an actual pointer.
558      const ProgramState *state = Pred->getState();
559      state = state->BindExpr(S, svalBuilder.makeIntValWithPtrWidth(0, false));
560      Bldr.generateNode(S, Pred, state);
561      break;
562    }
563
564    case Stmt::ObjCAtSynchronizedStmtClass:
565      Bldr.takeNodes(Pred);
566      VisitObjCAtSynchronizedStmt(cast<ObjCAtSynchronizedStmt>(S), Pred, Dst);
567      Bldr.addNodes(Dst);
568      break;
569
570    case Stmt::ObjCPropertyRefExprClass:
571      // Implicitly handled by Environment::getSVal().
572      break;
573
574    case Stmt::ImplicitValueInitExprClass: {
575      const ProgramState *state = Pred->getState();
576      QualType ty = cast<ImplicitValueInitExpr>(S)->getType();
577      SVal val = svalBuilder.makeZeroVal(ty);
578      Bldr.generateNode(S, Pred, state->BindExpr(S, val));
579      break;
580    }
581
582    case Stmt::ExprWithCleanupsClass:
583      Bldr.takeNodes(Pred);
584      Visit(cast<ExprWithCleanups>(S)->getSubExpr(), Pred, Dst);
585      Bldr.addNodes(Dst);
586      break;
587
588    // Cases not handled yet; but will handle some day.
589    case Stmt::DesignatedInitExprClass:
590    case Stmt::ExtVectorElementExprClass:
591    case Stmt::ImaginaryLiteralClass:
592    case Stmt::ObjCAtCatchStmtClass:
593    case Stmt::ObjCAtFinallyStmtClass:
594    case Stmt::ObjCAtTryStmtClass:
595    case Stmt::ObjCAutoreleasePoolStmtClass:
596    case Stmt::ObjCEncodeExprClass:
597    case Stmt::ObjCIsaExprClass:
598    case Stmt::ObjCProtocolExprClass:
599    case Stmt::ObjCSelectorExprClass:
600    case Stmt::ObjCStringLiteralClass:
601    case Stmt::ParenListExprClass:
602    case Stmt::PredefinedExprClass:
603    case Stmt::ShuffleVectorExprClass:
604    case Stmt::VAArgExprClass:
605    case Stmt::CUDAKernelCallExprClass:
606    case Stmt::OpaqueValueExprClass:
607    case Stmt::AsTypeExprClass:
608    case Stmt::AtomicExprClass:
609        // Fall through.
610
611    // Cases we intentionally don't evaluate, since they don't need
612    // to be explicitly evaluated.
613    case Stmt::AddrLabelExprClass:
614    case Stmt::IntegerLiteralClass:
615    case Stmt::CharacterLiteralClass:
616    case Stmt::CXXBoolLiteralExprClass:
617    case Stmt::FloatingLiteralClass:
618    case Stmt::SizeOfPackExprClass:
619    case Stmt::CXXNullPtrLiteralExprClass:
620      // No-op. Simply propagate the current state unchanged.
621      break;
622
623    case Stmt::ArraySubscriptExprClass:
624      Bldr.takeNodes(Pred);
625      VisitLvalArraySubscriptExpr(cast<ArraySubscriptExpr>(S), Pred, Dst);
626      Bldr.addNodes(Dst);
627      break;
628
629    case Stmt::AsmStmtClass:
630      Bldr.takeNodes(Pred);
631      VisitAsmStmt(cast<AsmStmt>(S), Pred, Dst);
632      Bldr.addNodes(Dst);
633      break;
634
635    case Stmt::BlockDeclRefExprClass: {
636      Bldr.takeNodes(Pred);
637      const BlockDeclRefExpr *BE = cast<BlockDeclRefExpr>(S);
638      VisitCommonDeclRefExpr(BE, BE->getDecl(), Pred, Dst);
639      Bldr.addNodes(Dst);
640      break;
641    }
642
643    case Stmt::BlockExprClass:
644      Bldr.takeNodes(Pred);
645      VisitBlockExpr(cast<BlockExpr>(S), Pred, Dst);
646      Bldr.addNodes(Dst);
647      break;
648
649    case Stmt::BinaryOperatorClass: {
650      const BinaryOperator* B = cast<BinaryOperator>(S);
651      if (B->isLogicalOp()) {
652        Bldr.takeNodes(Pred);
653        VisitLogicalExpr(B, Pred, Dst);
654        Bldr.addNodes(Dst);
655        break;
656      }
657      else if (B->getOpcode() == BO_Comma) {
658        const ProgramState *state = Pred->getState();
659        Bldr.generateNode(B, Pred,
660                          state->BindExpr(B, state->getSVal(B->getRHS())));
661        break;
662      }
663
664      Bldr.takeNodes(Pred);
665
666      if (AMgr.shouldEagerlyAssume() &&
667          (B->isRelationalOp() || B->isEqualityOp())) {
668        ExplodedNodeSet Tmp;
669        VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Tmp);
670        evalEagerlyAssume(Dst, Tmp, cast<Expr>(S));
671      }
672      else
673        VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Dst);
674
675      Bldr.addNodes(Dst);
676      break;
677    }
678
679    case Stmt::CallExprClass:
680    case Stmt::CXXOperatorCallExprClass:
681    case Stmt::CXXMemberCallExprClass: {
682      Bldr.takeNodes(Pred);
683      VisitCallExpr(cast<CallExpr>(S), Pred, Dst);
684      Bldr.addNodes(Dst);
685      break;
686    }
687
688    case Stmt::CXXTemporaryObjectExprClass:
689    case Stmt::CXXConstructExprClass: {
690      const CXXConstructExpr *C = cast<CXXConstructExpr>(S);
691      // For block-level CXXConstructExpr, we don't have a destination region.
692      // Let VisitCXXConstructExpr() create one.
693      Bldr.takeNodes(Pred);
694      VisitCXXConstructExpr(C, 0, Pred, Dst);
695      Bldr.addNodes(Dst);
696      break;
697    }
698
699    case Stmt::CXXNewExprClass: {
700      Bldr.takeNodes(Pred);
701      const CXXNewExpr *NE = cast<CXXNewExpr>(S);
702      VisitCXXNewExpr(NE, Pred, Dst);
703      Bldr.addNodes(Dst);
704      break;
705    }
706
707    case Stmt::CXXDeleteExprClass: {
708      Bldr.takeNodes(Pred);
709      const CXXDeleteExpr *CDE = cast<CXXDeleteExpr>(S);
710      VisitCXXDeleteExpr(CDE, Pred, Dst);
711      Bldr.addNodes(Dst);
712      break;
713    }
714      // FIXME: ChooseExpr is really a constant.  We need to fix
715      //        the CFG do not model them as explicit control-flow.
716
717    case Stmt::ChooseExprClass: { // __builtin_choose_expr
718      Bldr.takeNodes(Pred);
719      const ChooseExpr *C = cast<ChooseExpr>(S);
720      VisitGuardedExpr(C, C->getLHS(), C->getRHS(), Pred, Dst);
721      Bldr.addNodes(Dst);
722      break;
723    }
724
725    case Stmt::CompoundAssignOperatorClass:
726      Bldr.takeNodes(Pred);
727      VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Dst);
728      Bldr.addNodes(Dst);
729      break;
730
731    case Stmt::CompoundLiteralExprClass:
732      Bldr.takeNodes(Pred);
733      VisitCompoundLiteralExpr(cast<CompoundLiteralExpr>(S), Pred, Dst);
734      Bldr.addNodes(Dst);
735      break;
736
737    case Stmt::BinaryConditionalOperatorClass:
738    case Stmt::ConditionalOperatorClass: { // '?' operator
739      Bldr.takeNodes(Pred);
740      const AbstractConditionalOperator *C
741        = cast<AbstractConditionalOperator>(S);
742      VisitGuardedExpr(C, C->getTrueExpr(), C->getFalseExpr(), Pred, Dst);
743      Bldr.addNodes(Dst);
744      break;
745    }
746
747    case Stmt::CXXThisExprClass:
748      Bldr.takeNodes(Pred);
749      VisitCXXThisExpr(cast<CXXThisExpr>(S), Pred, Dst);
750      Bldr.addNodes(Dst);
751      break;
752
753    case Stmt::DeclRefExprClass: {
754      Bldr.takeNodes(Pred);
755      const DeclRefExpr *DE = cast<DeclRefExpr>(S);
756      VisitCommonDeclRefExpr(DE, DE->getDecl(), Pred, Dst);
757      Bldr.addNodes(Dst);
758      break;
759    }
760
761    case Stmt::DeclStmtClass:
762      Bldr.takeNodes(Pred);
763      VisitDeclStmt(cast<DeclStmt>(S), Pred, Dst);
764      Bldr.addNodes(Dst);
765      break;
766
767    case Stmt::ImplicitCastExprClass:
768    case Stmt::CStyleCastExprClass:
769    case Stmt::CXXStaticCastExprClass:
770    case Stmt::CXXDynamicCastExprClass:
771    case Stmt::CXXReinterpretCastExprClass:
772    case Stmt::CXXConstCastExprClass:
773    case Stmt::CXXFunctionalCastExprClass:
774    case Stmt::ObjCBridgedCastExprClass: {
775      Bldr.takeNodes(Pred);
776      const CastExpr *C = cast<CastExpr>(S);
777      // Handle the previsit checks.
778      ExplodedNodeSet dstPrevisit;
779      getCheckerManager().runCheckersForPreStmt(dstPrevisit, Pred, C, *this);
780
781      // Handle the expression itself.
782      ExplodedNodeSet dstExpr;
783      for (ExplodedNodeSet::iterator i = dstPrevisit.begin(),
784                                     e = dstPrevisit.end(); i != e ; ++i) {
785        VisitCast(C, C->getSubExpr(), *i, dstExpr);
786      }
787
788      // Handle the postvisit checks.
789      getCheckerManager().runCheckersForPostStmt(Dst, dstExpr, C, *this);
790      Bldr.addNodes(Dst);
791      break;
792    }
793
794    case Expr::MaterializeTemporaryExprClass: {
795      Bldr.takeNodes(Pred);
796      const MaterializeTemporaryExpr *Materialize
797                                            = cast<MaterializeTemporaryExpr>(S);
798      if (!Materialize->getType()->isRecordType())
799        CreateCXXTemporaryObject(Materialize, Pred, Dst);
800      else
801        Visit(Materialize->GetTemporaryExpr(), Pred, Dst);
802      Bldr.addNodes(Dst);
803      break;
804    }
805
806    case Stmt::InitListExprClass:
807      Bldr.takeNodes(Pred);
808      VisitInitListExpr(cast<InitListExpr>(S), Pred, Dst);
809      Bldr.addNodes(Dst);
810      break;
811
812    case Stmt::MemberExprClass:
813      Bldr.takeNodes(Pred);
814      VisitMemberExpr(cast<MemberExpr>(S), Pred, Dst);
815      Bldr.addNodes(Dst);
816      break;
817
818    case Stmt::ObjCIvarRefExprClass:
819      Bldr.takeNodes(Pred);
820      VisitLvalObjCIvarRefExpr(cast<ObjCIvarRefExpr>(S), Pred, Dst);
821      Bldr.addNodes(Dst);
822      break;
823
824    case Stmt::ObjCForCollectionStmtClass:
825      Bldr.takeNodes(Pred);
826      VisitObjCForCollectionStmt(cast<ObjCForCollectionStmt>(S), Pred, Dst);
827      Bldr.addNodes(Dst);
828      break;
829
830    case Stmt::ObjCMessageExprClass:
831      Bldr.takeNodes(Pred);
832      VisitObjCMessage(cast<ObjCMessageExpr>(S), Pred, Dst);
833      Bldr.addNodes(Dst);
834      break;
835
836    case Stmt::ObjCAtThrowStmtClass: {
837      // FIXME: This is not complete.  We basically treat @throw as
838      // an abort.
839      Bldr.generateNode(S, Pred, Pred->getState());
840      break;
841    }
842
843    case Stmt::ReturnStmtClass:
844      Bldr.takeNodes(Pred);
845      VisitReturnStmt(cast<ReturnStmt>(S), Pred, Dst);
846      Bldr.addNodes(Dst);
847      break;
848
849    case Stmt::OffsetOfExprClass:
850      Bldr.takeNodes(Pred);
851      VisitOffsetOfExpr(cast<OffsetOfExpr>(S), Pred, Dst);
852      Bldr.addNodes(Dst);
853      break;
854
855    case Stmt::UnaryExprOrTypeTraitExprClass:
856      Bldr.takeNodes(Pred);
857      VisitUnaryExprOrTypeTraitExpr(cast<UnaryExprOrTypeTraitExpr>(S),
858                                    Pred, Dst);
859      Bldr.addNodes(Dst);
860      break;
861
862    case Stmt::StmtExprClass: {
863      const StmtExpr *SE = cast<StmtExpr>(S);
864
865      if (SE->getSubStmt()->body_empty()) {
866        // Empty statement expression.
867        assert(SE->getType() == getContext().VoidTy
868               && "Empty statement expression must have void type.");
869        break;
870      }
871
872      if (Expr *LastExpr = dyn_cast<Expr>(*SE->getSubStmt()->body_rbegin())) {
873        const ProgramState *state = Pred->getState();
874        Bldr.generateNode(SE, Pred,
875                          state->BindExpr(SE, state->getSVal(LastExpr)));
876      }
877      break;
878    }
879
880    case Stmt::StringLiteralClass: {
881      const ProgramState *state = Pred->getState();
882      SVal V = state->getLValue(cast<StringLiteral>(S));
883      Bldr.generateNode(S, Pred, state->BindExpr(S, V));
884      return;
885    }
886
887    case Stmt::UnaryOperatorClass: {
888      Bldr.takeNodes(Pred);
889      const UnaryOperator *U = cast<UnaryOperator>(S);
890      if (AMgr.shouldEagerlyAssume() && (U->getOpcode() == UO_LNot)) {
891        ExplodedNodeSet Tmp;
892        VisitUnaryOperator(U, Pred, Tmp);
893        evalEagerlyAssume(Dst, Tmp, U);
894      }
895      else
896        VisitUnaryOperator(U, Pred, Dst);
897      Bldr.addNodes(Dst);
898      break;
899    }
900
901    case Stmt::PseudoObjectExprClass: {
902      Bldr.takeNodes(Pred);
903      const ProgramState *state = Pred->getState();
904      const PseudoObjectExpr *PE = cast<PseudoObjectExpr>(S);
905      if (const Expr *Result = PE->getResultExpr()) {
906        SVal V = state->getSVal(Result);
907        Bldr.generateNode(S, Pred, state->BindExpr(S, V));
908      }
909      else
910        Bldr.generateNode(S, Pred, state->BindExpr(S, UnknownVal()));
911
912      Bldr.addNodes(Dst);
913      break;
914    }
915  }
916}
917
918/// Block entrance.  (Update counters).
919void ExprEngine::processCFGBlockEntrance(NodeBuilderWithSinks &nodeBuilder) {
920
921  // FIXME: Refactor this into a checker.
922  ExplodedNode *pred = nodeBuilder.getContext().getPred();
923
924  if (nodeBuilder.getContext().getCurrentBlockCount() >= AMgr.getMaxVisit()) {
925    static SimpleProgramPointTag tag("ExprEngine : Block count exceeded");
926    nodeBuilder.generateNode(pred->getState(), pred, &tag, true);
927  }
928}
929
930//===----------------------------------------------------------------------===//
931// Branch processing.
932//===----------------------------------------------------------------------===//
933
934const ProgramState *ExprEngine::MarkBranch(const ProgramState *state,
935                                        const Stmt *Terminator,
936                                        bool branchTaken) {
937
938  switch (Terminator->getStmtClass()) {
939    default:
940      return state;
941
942    case Stmt::BinaryOperatorClass: { // '&&' and '||'
943
944      const BinaryOperator* B = cast<BinaryOperator>(Terminator);
945      BinaryOperator::Opcode Op = B->getOpcode();
946
947      assert (Op == BO_LAnd || Op == BO_LOr);
948
949      // For &&, if we take the true branch, then the value of the whole
950      // expression is that of the RHS expression.
951      //
952      // For ||, if we take the false branch, then the value of the whole
953      // expression is that of the RHS expression.
954
955      const Expr *Ex = (Op == BO_LAnd && branchTaken) ||
956                       (Op == BO_LOr && !branchTaken)
957                       ? B->getRHS() : B->getLHS();
958
959      return state->BindExpr(B, UndefinedVal(Ex));
960    }
961
962    case Stmt::BinaryConditionalOperatorClass:
963    case Stmt::ConditionalOperatorClass: { // ?:
964      const AbstractConditionalOperator* C
965        = cast<AbstractConditionalOperator>(Terminator);
966
967      // For ?, if branchTaken == true then the value is either the LHS or
968      // the condition itself. (GNU extension).
969
970      const Expr *Ex;
971
972      if (branchTaken)
973        Ex = C->getTrueExpr();
974      else
975        Ex = C->getFalseExpr();
976
977      return state->BindExpr(C, UndefinedVal(Ex));
978    }
979
980    case Stmt::ChooseExprClass: { // ?:
981
982      const ChooseExpr *C = cast<ChooseExpr>(Terminator);
983
984      const Expr *Ex = branchTaken ? C->getLHS() : C->getRHS();
985      return state->BindExpr(C, UndefinedVal(Ex));
986    }
987  }
988}
989
990/// RecoverCastedSymbol - A helper function for ProcessBranch that is used
991/// to try to recover some path-sensitivity for casts of symbolic
992/// integers that promote their values (which are currently not tracked well).
993/// This function returns the SVal bound to Condition->IgnoreCasts if all the
994//  cast(s) did was sign-extend the original value.
995static SVal RecoverCastedSymbol(ProgramStateManager& StateMgr,
996                                const ProgramState *state,
997                                const Stmt *Condition,
998                                ASTContext &Ctx) {
999
1000  const Expr *Ex = dyn_cast<Expr>(Condition);
1001  if (!Ex)
1002    return UnknownVal();
1003
1004  uint64_t bits = 0;
1005  bool bitsInit = false;
1006
1007  while (const CastExpr *CE = dyn_cast<CastExpr>(Ex)) {
1008    QualType T = CE->getType();
1009
1010    if (!T->isIntegerType())
1011      return UnknownVal();
1012
1013    uint64_t newBits = Ctx.getTypeSize(T);
1014    if (!bitsInit || newBits < bits) {
1015      bitsInit = true;
1016      bits = newBits;
1017    }
1018
1019    Ex = CE->getSubExpr();
1020  }
1021
1022  // We reached a non-cast.  Is it a symbolic value?
1023  QualType T = Ex->getType();
1024
1025  if (!bitsInit || !T->isIntegerType() || Ctx.getTypeSize(T) > bits)
1026    return UnknownVal();
1027
1028  return state->getSVal(Ex);
1029}
1030
1031void ExprEngine::processBranch(const Stmt *Condition, const Stmt *Term,
1032                               NodeBuilderContext& BldCtx,
1033                               ExplodedNode *Pred,
1034                               ExplodedNodeSet &Dst,
1035                               const CFGBlock *DstT,
1036                               const CFGBlock *DstF) {
1037  currentBuilderContext = &BldCtx;
1038
1039  // Check for NULL conditions; e.g. "for(;;)"
1040  if (!Condition) {
1041    BranchNodeBuilder NullCondBldr(Pred, Dst, BldCtx, DstT, DstF);
1042    NullCondBldr.markInfeasible(false);
1043    NullCondBldr.generateNode(Pred->getState(), true, Pred);
1044    return;
1045  }
1046
1047  PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),
1048                                Condition->getLocStart(),
1049                                "Error evaluating branch");
1050
1051  ExplodedNodeSet CheckersOutSet;
1052  getCheckerManager().runCheckersForBranchCondition(Condition, CheckersOutSet,
1053                                                    Pred, *this);
1054  // We generated only sinks.
1055  if (CheckersOutSet.empty())
1056    return;
1057
1058  BranchNodeBuilder builder(CheckersOutSet, Dst, BldCtx, DstT, DstF);
1059  for (NodeBuilder::iterator I = CheckersOutSet.begin(),
1060                             E = CheckersOutSet.end(); E != I; ++I) {
1061    ExplodedNode *PredI = *I;
1062
1063    if (PredI->isSink())
1064      continue;
1065
1066    const ProgramState *PrevState = Pred->getState();
1067    SVal X = PrevState->getSVal(Condition);
1068
1069    if (X.isUnknownOrUndef()) {
1070      // Give it a chance to recover from unknown.
1071      if (const Expr *Ex = dyn_cast<Expr>(Condition)) {
1072        if (Ex->getType()->isIntegerType()) {
1073          // Try to recover some path-sensitivity.  Right now casts of symbolic
1074          // integers that promote their values are currently not tracked well.
1075          // If 'Condition' is such an expression, try and recover the
1076          // underlying value and use that instead.
1077          SVal recovered = RecoverCastedSymbol(getStateManager(),
1078                                               PrevState, Condition,
1079                                               getContext());
1080
1081          if (!recovered.isUnknown()) {
1082            X = recovered;
1083          }
1084        }
1085      }
1086    }
1087    // If the condition is still unknown, give up.
1088    if (X.isUnknownOrUndef()) {
1089      builder.generateNode(MarkBranch(PrevState, Term, true), true, PredI);
1090      builder.generateNode(MarkBranch(PrevState, Term, false), false, PredI);
1091      continue;
1092    }
1093
1094    DefinedSVal V = cast<DefinedSVal>(X);
1095
1096    // Process the true branch.
1097    if (builder.isFeasible(true)) {
1098      if (const ProgramState *state = PrevState->assume(V, true))
1099        builder.generateNode(MarkBranch(state, Term, true), true, PredI);
1100      else
1101        builder.markInfeasible(true);
1102    }
1103
1104    // Process the false branch.
1105    if (builder.isFeasible(false)) {
1106      if (const ProgramState *state = PrevState->assume(V, false))
1107        builder.generateNode(MarkBranch(state, Term, false), false, PredI);
1108      else
1109        builder.markInfeasible(false);
1110    }
1111  }
1112  currentBuilderContext = 0;
1113}
1114
1115/// processIndirectGoto - Called by CoreEngine.  Used to generate successor
1116///  nodes by processing the 'effects' of a computed goto jump.
1117void ExprEngine::processIndirectGoto(IndirectGotoNodeBuilder &builder) {
1118
1119  const ProgramState *state = builder.getState();
1120  SVal V = state->getSVal(builder.getTarget());
1121
1122  // Three possibilities:
1123  //
1124  //   (1) We know the computed label.
1125  //   (2) The label is NULL (or some other constant), or Undefined.
1126  //   (3) We have no clue about the label.  Dispatch to all targets.
1127  //
1128
1129  typedef IndirectGotoNodeBuilder::iterator iterator;
1130
1131  if (isa<loc::GotoLabel>(V)) {
1132    const LabelDecl *L = cast<loc::GotoLabel>(V).getLabel();
1133
1134    for (iterator I = builder.begin(), E = builder.end(); I != E; ++I) {
1135      if (I.getLabel() == L) {
1136        builder.generateNode(I, state);
1137        return;
1138      }
1139    }
1140
1141    llvm_unreachable("No block with label.");
1142  }
1143
1144  if (isa<loc::ConcreteInt>(V) || isa<UndefinedVal>(V)) {
1145    // Dispatch to the first target and mark it as a sink.
1146    //ExplodedNode* N = builder.generateNode(builder.begin(), state, true);
1147    // FIXME: add checker visit.
1148    //    UndefBranches.insert(N);
1149    return;
1150  }
1151
1152  // This is really a catch-all.  We don't support symbolics yet.
1153  // FIXME: Implement dispatch for symbolic pointers.
1154
1155  for (iterator I=builder.begin(), E=builder.end(); I != E; ++I)
1156    builder.generateNode(I, state);
1157}
1158
1159/// ProcessEndPath - Called by CoreEngine.  Used to generate end-of-path
1160///  nodes when the control reaches the end of a function.
1161void ExprEngine::processEndOfFunction(NodeBuilderContext& BC) {
1162  StateMgr.EndPath(BC.Pred->getState());
1163  ExplodedNodeSet Dst;
1164  getCheckerManager().runCheckersForEndPath(BC, Dst, *this);
1165  Engine.enqueueEndOfFunction(Dst);
1166}
1167
1168/// ProcessSwitch - Called by CoreEngine.  Used to generate successor
1169///  nodes by processing the 'effects' of a switch statement.
1170void ExprEngine::processSwitch(SwitchNodeBuilder& builder) {
1171  typedef SwitchNodeBuilder::iterator iterator;
1172  const ProgramState *state = builder.getState();
1173  const Expr *CondE = builder.getCondition();
1174  SVal  CondV_untested = state->getSVal(CondE);
1175
1176  if (CondV_untested.isUndef()) {
1177    //ExplodedNode* N = builder.generateDefaultCaseNode(state, true);
1178    // FIXME: add checker
1179    //UndefBranches.insert(N);
1180
1181    return;
1182  }
1183  DefinedOrUnknownSVal CondV = cast<DefinedOrUnknownSVal>(CondV_untested);
1184
1185  const ProgramState *DefaultSt = state;
1186
1187  iterator I = builder.begin(), EI = builder.end();
1188  bool defaultIsFeasible = I == EI;
1189
1190  for ( ; I != EI; ++I) {
1191    // Successor may be pruned out during CFG construction.
1192    if (!I.getBlock())
1193      continue;
1194
1195    const CaseStmt *Case = I.getCase();
1196
1197    // Evaluate the LHS of the case value.
1198    llvm::APSInt V1 = Case->getLHS()->EvaluateKnownConstInt(getContext());
1199    assert(V1.getBitWidth() == getContext().getTypeSize(CondE->getType()));
1200
1201    // Get the RHS of the case, if it exists.
1202    llvm::APSInt V2;
1203    if (const Expr *E = Case->getRHS())
1204      V2 = E->EvaluateKnownConstInt(getContext());
1205    else
1206      V2 = V1;
1207
1208    // FIXME: Eventually we should replace the logic below with a range
1209    //  comparison, rather than concretize the values within the range.
1210    //  This should be easy once we have "ranges" for NonLVals.
1211
1212    do {
1213      nonloc::ConcreteInt CaseVal(getBasicVals().getValue(V1));
1214      DefinedOrUnknownSVal Res = svalBuilder.evalEQ(DefaultSt ? DefaultSt : state,
1215                                               CondV, CaseVal);
1216
1217      // Now "assume" that the case matches.
1218      if (const ProgramState *stateNew = state->assume(Res, true)) {
1219        builder.generateCaseStmtNode(I, stateNew);
1220
1221        // If CondV evaluates to a constant, then we know that this
1222        // is the *only* case that we can take, so stop evaluating the
1223        // others.
1224        if (isa<nonloc::ConcreteInt>(CondV))
1225          return;
1226      }
1227
1228      // Now "assume" that the case doesn't match.  Add this state
1229      // to the default state (if it is feasible).
1230      if (DefaultSt) {
1231        if (const ProgramState *stateNew = DefaultSt->assume(Res, false)) {
1232          defaultIsFeasible = true;
1233          DefaultSt = stateNew;
1234        }
1235        else {
1236          defaultIsFeasible = false;
1237          DefaultSt = NULL;
1238        }
1239      }
1240
1241      // Concretize the next value in the range.
1242      if (V1 == V2)
1243        break;
1244
1245      ++V1;
1246      assert (V1 <= V2);
1247
1248    } while (true);
1249  }
1250
1251  if (!defaultIsFeasible)
1252    return;
1253
1254  // If we have switch(enum value), the default branch is not
1255  // feasible if all of the enum constants not covered by 'case:' statements
1256  // are not feasible values for the switch condition.
1257  //
1258  // Note that this isn't as accurate as it could be.  Even if there isn't
1259  // a case for a particular enum value as long as that enum value isn't
1260  // feasible then it shouldn't be considered for making 'default:' reachable.
1261  const SwitchStmt *SS = builder.getSwitch();
1262  const Expr *CondExpr = SS->getCond()->IgnoreParenImpCasts();
1263  if (CondExpr->getType()->getAs<EnumType>()) {
1264    if (SS->isAllEnumCasesCovered())
1265      return;
1266  }
1267
1268  builder.generateDefaultCaseNode(DefaultSt);
1269}
1270
1271//===----------------------------------------------------------------------===//
1272// Transfer functions: Loads and stores.
1273//===----------------------------------------------------------------------===//
1274
1275void ExprEngine::VisitCommonDeclRefExpr(const Expr *Ex, const NamedDecl *D,
1276                                        ExplodedNode *Pred,
1277                                        ExplodedNodeSet &Dst) {
1278  StmtNodeBuilder Bldr(Pred, Dst, *currentBuilderContext);
1279
1280  const ProgramState *state = Pred->getState();
1281
1282  if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
1283    assert(Ex->isLValue());
1284    SVal V = state->getLValue(VD, Pred->getLocationContext());
1285
1286    // For references, the 'lvalue' is the pointer address stored in the
1287    // reference region.
1288    if (VD->getType()->isReferenceType()) {
1289      if (const MemRegion *R = V.getAsRegion())
1290        V = state->getSVal(R);
1291      else
1292        V = UnknownVal();
1293    }
1294
1295    Bldr.generateNode(Ex, Pred, state->BindExpr(Ex, V), false, 0,
1296                      ProgramPoint::PostLValueKind);
1297    return;
1298  }
1299  if (const EnumConstantDecl *ED = dyn_cast<EnumConstantDecl>(D)) {
1300    assert(!Ex->isLValue());
1301    SVal V = svalBuilder.makeIntVal(ED->getInitVal());
1302    Bldr.generateNode(Ex, Pred, state->BindExpr(Ex, V));
1303    return;
1304  }
1305  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
1306    SVal V = svalBuilder.getFunctionPointer(FD);
1307    Bldr.generateNode(Ex, Pred, state->BindExpr(Ex, V), false, 0,
1308                      ProgramPoint::PostLValueKind);
1309    return;
1310  }
1311  assert (false &&
1312          "ValueDecl support for this ValueDecl not implemented.");
1313}
1314
1315/// VisitArraySubscriptExpr - Transfer function for array accesses
1316void ExprEngine::VisitLvalArraySubscriptExpr(const ArraySubscriptExpr *A,
1317                                             ExplodedNode *Pred,
1318                                             ExplodedNodeSet &Dst){
1319
1320  const Expr *Base = A->getBase()->IgnoreParens();
1321  const Expr *Idx  = A->getIdx()->IgnoreParens();
1322
1323
1324  ExplodedNodeSet checkerPreStmt;
1325  getCheckerManager().runCheckersForPreStmt(checkerPreStmt, Pred, A, *this);
1326
1327  StmtNodeBuilder Bldr(checkerPreStmt, Dst, *currentBuilderContext);
1328
1329  for (ExplodedNodeSet::iterator it = checkerPreStmt.begin(),
1330                                 ei = checkerPreStmt.end(); it != ei; ++it) {
1331    const ProgramState *state = (*it)->getState();
1332    SVal V = state->getLValue(A->getType(), state->getSVal(Idx),
1333                              state->getSVal(Base));
1334    assert(A->isLValue());
1335    Bldr.generateNode(A, *it, state->BindExpr(A, V),
1336                      false, 0, ProgramPoint::PostLValueKind);
1337  }
1338}
1339
1340/// VisitMemberExpr - Transfer function for member expressions.
1341void ExprEngine::VisitMemberExpr(const MemberExpr *M, ExplodedNode *Pred,
1342                                 ExplodedNodeSet &TopDst) {
1343
1344  StmtNodeBuilder Bldr(Pred, TopDst, *currentBuilderContext);
1345  ExplodedNodeSet Dst;
1346  Decl *member = M->getMemberDecl();
1347  if (VarDecl *VD = dyn_cast<VarDecl>(member)) {
1348    assert(M->isLValue());
1349    Bldr.takeNodes(Pred);
1350    VisitCommonDeclRefExpr(M, VD, Pred, Dst);
1351    Bldr.addNodes(Dst);
1352    return;
1353  }
1354
1355  FieldDecl *field = dyn_cast<FieldDecl>(member);
1356  if (!field) // FIXME: skipping member expressions for non-fields
1357    return;
1358
1359  Expr *baseExpr = M->getBase()->IgnoreParens();
1360  const ProgramState *state = Pred->getState();
1361  SVal baseExprVal = state->getSVal(baseExpr);
1362  if (isa<nonloc::LazyCompoundVal>(baseExprVal) ||
1363      isa<nonloc::CompoundVal>(baseExprVal) ||
1364      // FIXME: This can originate by conjuring a symbol for an unknown
1365      // temporary struct object, see test/Analysis/fields.c:
1366      // (p = getit()).x
1367      isa<nonloc::SymbolVal>(baseExprVal)) {
1368    Bldr.generateNode(M, Pred, state->BindExpr(M, UnknownVal()));
1369    return;
1370  }
1371
1372  // FIXME: Should we insert some assumption logic in here to determine
1373  // if "Base" is a valid piece of memory?  Before we put this assumption
1374  // later when using FieldOffset lvals (which we no longer have).
1375
1376  // For all other cases, compute an lvalue.
1377  SVal L = state->getLValue(field, baseExprVal);
1378  if (M->isLValue())
1379    Bldr.generateNode(M, Pred, state->BindExpr(M, L), false, 0,
1380                      ProgramPoint::PostLValueKind);
1381  else {
1382    Bldr.takeNodes(Pred);
1383    evalLoad(Dst, M, Pred, state, L);
1384    Bldr.addNodes(Dst);
1385  }
1386}
1387
1388/// evalBind - Handle the semantics of binding a value to a specific location.
1389///  This method is used by evalStore and (soon) VisitDeclStmt, and others.
1390void ExprEngine::evalBind(ExplodedNodeSet &Dst, const Stmt *StoreE,
1391                          ExplodedNode *Pred,
1392                          SVal location, SVal Val, bool atDeclInit,
1393                          ProgramPoint::Kind PointKind) {
1394
1395  // Do a previsit of the bind.
1396  ExplodedNodeSet CheckedSet;
1397  getCheckerManager().runCheckersForBind(CheckedSet, Pred, location, Val,
1398                                         StoreE, *this, PointKind);
1399
1400  // TODO:AZ Remove TmpDst after NB refactoring is done.
1401  ExplodedNodeSet TmpDst;
1402  StmtNodeBuilder Bldr(CheckedSet, TmpDst, *currentBuilderContext);
1403
1404  for (ExplodedNodeSet::iterator I = CheckedSet.begin(), E = CheckedSet.end();
1405       I!=E; ++I) {
1406    const ProgramState *state = (*I)->getState();
1407
1408    if (atDeclInit) {
1409      const VarRegion *VR =
1410        cast<VarRegion>(cast<loc::MemRegionVal>(location).getRegion());
1411
1412      state = state->bindDecl(VR, Val);
1413    } else {
1414      state = state->bindLoc(location, Val);
1415    }
1416
1417    Bldr.generateNode(StoreE, *I, state, false, 0, PointKind);
1418  }
1419
1420  Dst.insert(TmpDst);
1421}
1422
1423/// evalStore - Handle the semantics of a store via an assignment.
1424///  @param Dst The node set to store generated state nodes
1425///  @param AssignE The assignment expression if the store happens in an
1426///         assignment.
1427///  @param LocatioinE The location expression that is stored to.
1428///  @param state The current simulation state
1429///  @param location The location to store the value
1430///  @param Val The value to be stored
1431void ExprEngine::evalStore(ExplodedNodeSet &Dst, const Expr *AssignE,
1432                             const Expr *LocationE,
1433                             ExplodedNode *Pred,
1434                             const ProgramState *state, SVal location, SVal Val,
1435                             const ProgramPointTag *tag) {
1436  // Proceed with the store.  We use AssignE as the anchor for the PostStore
1437  // ProgramPoint if it is non-NULL, and LocationE otherwise.
1438  const Expr *StoreE = AssignE ? AssignE : LocationE;
1439
1440  if (isa<loc::ObjCPropRef>(location)) {
1441    loc::ObjCPropRef prop = cast<loc::ObjCPropRef>(location);
1442    return VisitObjCMessage(ObjCPropertySetter(prop.getPropRefExpr(),
1443                                               StoreE, Val), Pred, Dst);
1444  }
1445
1446  // Evaluate the location (checks for bad dereferences).
1447  ExplodedNodeSet Tmp;
1448  evalLocation(Tmp, LocationE, Pred, state, location, tag, false);
1449
1450  if (Tmp.empty())
1451    return;
1452
1453  if (location.isUndef())
1454    return;
1455
1456  for (ExplodedNodeSet::iterator NI=Tmp.begin(), NE=Tmp.end(); NI!=NE; ++NI)
1457    evalBind(Dst, StoreE, *NI, location, Val, false,
1458             ProgramPoint::PostStoreKind);
1459}
1460
1461void ExprEngine::evalLoad(ExplodedNodeSet &Dst, const Expr *Ex,
1462                            ExplodedNode *Pred,
1463                            const ProgramState *state, SVal location,
1464                            const ProgramPointTag *tag, QualType LoadTy) {
1465  assert(!isa<NonLoc>(location) && "location cannot be a NonLoc.");
1466
1467  if (isa<loc::ObjCPropRef>(location)) {
1468    loc::ObjCPropRef prop = cast<loc::ObjCPropRef>(location);
1469    return VisitObjCMessage(ObjCPropertyGetter(prop.getPropRefExpr(), Ex),
1470                            Pred, Dst);
1471  }
1472
1473  // Are we loading from a region?  This actually results in two loads; one
1474  // to fetch the address of the referenced value and one to fetch the
1475  // referenced value.
1476  if (const TypedValueRegion *TR =
1477        dyn_cast_or_null<TypedValueRegion>(location.getAsRegion())) {
1478
1479    QualType ValTy = TR->getValueType();
1480    if (const ReferenceType *RT = ValTy->getAs<ReferenceType>()) {
1481      static SimpleProgramPointTag
1482             loadReferenceTag("ExprEngine : Load Reference");
1483      ExplodedNodeSet Tmp;
1484      evalLoadCommon(Tmp, Ex, Pred, state, location, &loadReferenceTag,
1485                     getContext().getPointerType(RT->getPointeeType()));
1486
1487      // Perform the load from the referenced value.
1488      for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end() ; I!=E; ++I) {
1489        state = (*I)->getState();
1490        location = state->getSVal(Ex);
1491        evalLoadCommon(Dst, Ex, *I, state, location, tag, LoadTy);
1492      }
1493      return;
1494    }
1495  }
1496
1497  evalLoadCommon(Dst, Ex, Pred, state, location, tag, LoadTy);
1498}
1499
1500void ExprEngine::evalLoadCommon(ExplodedNodeSet &Dst, const Expr *Ex,
1501                                  ExplodedNode *Pred,
1502                                  const ProgramState *state, SVal location,
1503                                  const ProgramPointTag *tag, QualType LoadTy) {
1504
1505  // Evaluate the location (checks for bad dereferences).
1506  ExplodedNodeSet Tmp;
1507  evalLocation(Tmp, Ex, Pred, state, location, tag, true);
1508  if (Tmp.empty())
1509    return;
1510
1511  StmtNodeBuilder Bldr(Tmp, Dst, *currentBuilderContext);
1512  if (location.isUndef())
1513    return;
1514
1515  // Proceed with the load.
1516  for (ExplodedNodeSet::iterator NI=Tmp.begin(), NE=Tmp.end(); NI!=NE; ++NI) {
1517    state = (*NI)->getState();
1518
1519    if (location.isUnknown()) {
1520      // This is important.  We must nuke the old binding.
1521      Bldr.generateNode(Ex, *NI, state->BindExpr(Ex, UnknownVal()),
1522                        false, tag, ProgramPoint::PostLoadKind);
1523    }
1524    else {
1525      if (LoadTy.isNull())
1526        LoadTy = Ex->getType();
1527      SVal V = state->getSVal(cast<Loc>(location), LoadTy);
1528      Bldr.generateNode(Ex, *NI, state->bindExprAndLocation(Ex, location, V),
1529                        false, tag, ProgramPoint::PostLoadKind);
1530    }
1531  }
1532}
1533
1534void ExprEngine::evalLocation(ExplodedNodeSet &Dst, const Stmt *S,
1535                                ExplodedNode *Pred,
1536                                const ProgramState *state, SVal location,
1537                                const ProgramPointTag *tag, bool isLoad) {
1538  StmtNodeBuilder BldrTop(Pred, Dst, *currentBuilderContext);
1539  // Early checks for performance reason.
1540  if (location.isUnknown()) {
1541    return;
1542  }
1543
1544  ExplodedNodeSet Src;
1545  BldrTop.takeNodes(Pred);
1546  StmtNodeBuilder Bldr(Pred, Src, *currentBuilderContext);
1547  if (Pred->getState() != state) {
1548    // Associate this new state with an ExplodedNode.
1549    // FIXME: If I pass null tag, the graph is incorrect, e.g for
1550    //   int *p;
1551    //   p = 0;
1552    //   *p = 0xDEADBEEF;
1553    // "p = 0" is not noted as "Null pointer value stored to 'p'" but
1554    // instead "int *p" is noted as
1555    // "Variable 'p' initialized to a null pointer value"
1556
1557    // FIXME: why is 'tag' not used instead of etag?
1558    static SimpleProgramPointTag etag("ExprEngine: Location");
1559
1560    Bldr.generateNode(S, Pred, state, false, &etag);
1561  }
1562  ExplodedNodeSet Tmp;
1563  getCheckerManager().runCheckersForLocation(Tmp, Src, location, isLoad, S,
1564                                             *this);
1565  BldrTop.addNodes(Tmp);
1566}
1567
1568bool ExprEngine::InlineCall(ExplodedNodeSet &Dst, const CallExpr *CE,
1569                              ExplodedNode *Pred) {
1570  return false;
1571
1572  // Inlining isn't correct right now because we:
1573  // (a) don't generate CallExit nodes.
1574  // (b) we need a way to postpone doing post-visits of CallExprs until
1575  // the CallExit.  This means we need CallExits for the non-inline
1576  // cases as well.
1577
1578#if 0
1579  const ProgramState *state = Pred->getState();
1580  const Expr *Callee = CE->getCallee();
1581  SVal L = state->getSVal(Callee);
1582
1583  const FunctionDecl *FD = L.getAsFunctionDecl();
1584  if (!FD)
1585    return false;
1586
1587  // Specially handle CXXMethods.
1588  const CXXMethodDecl *methodDecl = 0;
1589
1590  switch (CE->getStmtClass()) {
1591    default: break;
1592    case Stmt::CXXOperatorCallExprClass: {
1593      const CXXOperatorCallExpr *opCall = cast<CXXOperatorCallExpr>(CE);
1594      methodDecl =
1595        dyn_cast_or_null<CXXMethodDecl>(opCall->getCalleeDecl());
1596      break;
1597    }
1598    case Stmt::CXXMemberCallExprClass: {
1599      const CXXMemberCallExpr *memberCall = cast<CXXMemberCallExpr>(CE);
1600      const MemberExpr *memberExpr =
1601        cast<MemberExpr>(memberCall->getCallee()->IgnoreParens());
1602      methodDecl = cast<CXXMethodDecl>(memberExpr->getMemberDecl());
1603      break;
1604    }
1605  }
1606
1607
1608
1609
1610  // Check if the function definition is in the same translation unit.
1611  if (FD->hasBody(FD)) {
1612    const StackFrameContext *stackFrame =
1613      AMgr.getStackFrame(AMgr.getAnalysisDeclContext(FD),
1614                         Pred->getLocationContext(),
1615                         CE, currentBuilderContext->getBlock(), currentStmtIdx);
1616    // Now we have the definition of the callee, create a CallEnter node.
1617    CallEnter Loc(CE, stackFrame, Pred->getLocationContext());
1618
1619    ExplodedNode *N = Builder->generateNode(Loc, state, Pred);
1620    Dst.Add(N);
1621    return true;
1622  }
1623
1624  // Check if we can find the function definition in other translation units.
1625  if (AMgr.hasIndexer()) {
1626    AnalysisDeclContext *C = AMgr.getAnalysisDeclContextInAnotherTU(FD);
1627    if (C == 0)
1628      return false;
1629    const StackFrameContext *stackFrame =
1630      AMgr.getStackFrame(C, Pred->getLocationContext(),
1631                         CE, currentBuilderContext->getBlock(), currentStmtIdx);
1632    CallEnter Loc(CE, stackFrame, Pred->getLocationContext());
1633    ExplodedNode *N = Builder->generateNode(Loc, state, Pred);
1634    Dst.Add(N);
1635    return true;
1636  }
1637
1638  // Generate the CallExit node.
1639
1640  return false;
1641#endif
1642}
1643
1644std::pair<const ProgramPointTag *, const ProgramPointTag*>
1645ExprEngine::getEagerlyAssumeTags() {
1646  static SimpleProgramPointTag
1647         EagerlyAssumeTrue("ExprEngine : Eagerly Assume True"),
1648         EagerlyAssumeFalse("ExprEngine : Eagerly Assume False");
1649  return std::make_pair(&EagerlyAssumeTrue, &EagerlyAssumeFalse);
1650}
1651
1652void ExprEngine::evalEagerlyAssume(ExplodedNodeSet &Dst, ExplodedNodeSet &Src,
1653                                   const Expr *Ex) {
1654  StmtNodeBuilder Bldr(Src, Dst, *currentBuilderContext);
1655
1656  for (ExplodedNodeSet::iterator I=Src.begin(), E=Src.end(); I!=E; ++I) {
1657    ExplodedNode *Pred = *I;
1658    // Test if the previous node was as the same expression.  This can happen
1659    // when the expression fails to evaluate to anything meaningful and
1660    // (as an optimization) we don't generate a node.
1661    ProgramPoint P = Pred->getLocation();
1662    if (!isa<PostStmt>(P) || cast<PostStmt>(P).getStmt() != Ex) {
1663      continue;
1664    }
1665
1666    const ProgramState *state = Pred->getState();
1667    SVal V = state->getSVal(Ex);
1668    nonloc::SymbolVal *SEV = dyn_cast<nonloc::SymbolVal>(&V);
1669    if (SEV && SEV->isExpression()) {
1670      const std::pair<const ProgramPointTag *, const ProgramPointTag*> &tags =
1671        getEagerlyAssumeTags();
1672
1673      // First assume that the condition is true.
1674      if (const ProgramState *StateTrue = state->assume(*SEV, true)) {
1675        SVal Val = svalBuilder.makeIntVal(1U, Ex->getType());
1676        StateTrue = StateTrue->BindExpr(Ex, Val);
1677        Bldr.generateNode(Ex, Pred, StateTrue, false, tags.first);
1678      }
1679
1680      // Next, assume that the condition is false.
1681      if (const ProgramState *StateFalse = state->assume(*SEV, false)) {
1682        SVal Val = svalBuilder.makeIntVal(0U, Ex->getType());
1683        StateFalse = StateFalse->BindExpr(Ex, Val);
1684        Bldr.generateNode(Ex, Pred, StateFalse, false, tags.second);
1685      }
1686    }
1687  }
1688}
1689
1690void ExprEngine::VisitAsmStmt(const AsmStmt *A, ExplodedNode *Pred,
1691                                ExplodedNodeSet &Dst) {
1692  VisitAsmStmtHelperOutputs(A, A->begin_outputs(), A->end_outputs(), Pred, Dst);
1693}
1694
1695void ExprEngine::VisitAsmStmtHelperOutputs(const AsmStmt *A,
1696                                             AsmStmt::const_outputs_iterator I,
1697                                             AsmStmt::const_outputs_iterator E,
1698                                     ExplodedNode *Pred, ExplodedNodeSet &Dst) {
1699  if (I == E) {
1700    VisitAsmStmtHelperInputs(A, A->begin_inputs(), A->end_inputs(), Pred, Dst);
1701    return;
1702  }
1703
1704  ExplodedNodeSet Tmp;
1705  Visit(*I, Pred, Tmp);
1706  ++I;
1707
1708  for (ExplodedNodeSet::iterator NI = Tmp.begin(), NE = Tmp.end();NI != NE;++NI)
1709    VisitAsmStmtHelperOutputs(A, I, E, *NI, Dst);
1710}
1711
1712void ExprEngine::VisitAsmStmtHelperInputs(const AsmStmt *A,
1713                                            AsmStmt::const_inputs_iterator I,
1714                                            AsmStmt::const_inputs_iterator E,
1715                                            ExplodedNode *Pred,
1716                                            ExplodedNodeSet &Dst) {
1717  if (I == E) {
1718    StmtNodeBuilder Bldr(Pred, Dst, *currentBuilderContext);
1719    // We have processed both the inputs and the outputs.  All of the outputs
1720    // should evaluate to Locs.  Nuke all of their values.
1721
1722    // FIXME: Some day in the future it would be nice to allow a "plug-in"
1723    // which interprets the inline asm and stores proper results in the
1724    // outputs.
1725
1726    const ProgramState *state = Pred->getState();
1727
1728    for (AsmStmt::const_outputs_iterator OI = A->begin_outputs(),
1729                                   OE = A->end_outputs(); OI != OE; ++OI) {
1730
1731      SVal X = state->getSVal(*OI);
1732      assert (!isa<NonLoc>(X));  // Should be an Lval, or unknown, undef.
1733
1734      if (isa<Loc>(X))
1735        state = state->bindLoc(cast<Loc>(X), UnknownVal());
1736    }
1737
1738    Bldr.generateNode(A, Pred, state);
1739    return;
1740  }
1741
1742  ExplodedNodeSet Tmp;
1743  Visit(*I, Pred, Tmp);
1744
1745  ++I;
1746
1747  for (ExplodedNodeSet::iterator NI = Tmp.begin(), NE = Tmp.end(); NI!=NE; ++NI)
1748    VisitAsmStmtHelperInputs(A, I, E, *NI, Dst);
1749}
1750
1751
1752//===----------------------------------------------------------------------===//
1753// Visualization.
1754//===----------------------------------------------------------------------===//
1755
1756#ifndef NDEBUG
1757static ExprEngine* GraphPrintCheckerState;
1758static SourceManager* GraphPrintSourceManager;
1759
1760namespace llvm {
1761template<>
1762struct DOTGraphTraits<ExplodedNode*> :
1763  public DefaultDOTGraphTraits {
1764
1765  DOTGraphTraits (bool isSimple=false) : DefaultDOTGraphTraits(isSimple) {}
1766
1767  // FIXME: Since we do not cache error nodes in ExprEngine now, this does not
1768  // work.
1769  static std::string getNodeAttributes(const ExplodedNode *N, void*) {
1770
1771#if 0
1772      // FIXME: Replace with a general scheme to tell if the node is
1773      // an error node.
1774    if (GraphPrintCheckerState->isImplicitNullDeref(N) ||
1775        GraphPrintCheckerState->isExplicitNullDeref(N) ||
1776        GraphPrintCheckerState->isUndefDeref(N) ||
1777        GraphPrintCheckerState->isUndefStore(N) ||
1778        GraphPrintCheckerState->isUndefControlFlow(N) ||
1779        GraphPrintCheckerState->isUndefResult(N) ||
1780        GraphPrintCheckerState->isBadCall(N) ||
1781        GraphPrintCheckerState->isUndefArg(N))
1782      return "color=\"red\",style=\"filled\"";
1783
1784    if (GraphPrintCheckerState->isNoReturnCall(N))
1785      return "color=\"blue\",style=\"filled\"";
1786#endif
1787    return "";
1788  }
1789
1790  static std::string getNodeLabel(const ExplodedNode *N, void*){
1791
1792    std::string sbuf;
1793    llvm::raw_string_ostream Out(sbuf);
1794
1795    // Program Location.
1796    ProgramPoint Loc = N->getLocation();
1797
1798    switch (Loc.getKind()) {
1799      case ProgramPoint::BlockEntranceKind:
1800        Out << "Block Entrance: B"
1801            << cast<BlockEntrance>(Loc).getBlock()->getBlockID();
1802        break;
1803
1804      case ProgramPoint::BlockExitKind:
1805        assert (false);
1806        break;
1807
1808      case ProgramPoint::CallEnterKind:
1809        Out << "CallEnter";
1810        break;
1811
1812      case ProgramPoint::CallExitKind:
1813        Out << "CallExit";
1814        break;
1815
1816      default: {
1817        if (StmtPoint *L = dyn_cast<StmtPoint>(&Loc)) {
1818          const Stmt *S = L->getStmt();
1819          SourceLocation SLoc = S->getLocStart();
1820
1821          Out << S->getStmtClassName() << ' ' << (void*) S << ' ';
1822          LangOptions LO; // FIXME.
1823          S->printPretty(Out, 0, PrintingPolicy(LO));
1824
1825          if (SLoc.isFileID()) {
1826            Out << "\\lline="
1827              << GraphPrintSourceManager->getExpansionLineNumber(SLoc)
1828              << " col="
1829              << GraphPrintSourceManager->getExpansionColumnNumber(SLoc)
1830              << "\\l";
1831          }
1832
1833          if (isa<PreStmt>(Loc))
1834            Out << "\\lPreStmt\\l;";
1835          else if (isa<PostLoad>(Loc))
1836            Out << "\\lPostLoad\\l;";
1837          else if (isa<PostStore>(Loc))
1838            Out << "\\lPostStore\\l";
1839          else if (isa<PostLValue>(Loc))
1840            Out << "\\lPostLValue\\l";
1841
1842#if 0
1843            // FIXME: Replace with a general scheme to determine
1844            // the name of the check.
1845          if (GraphPrintCheckerState->isImplicitNullDeref(N))
1846            Out << "\\|Implicit-Null Dereference.\\l";
1847          else if (GraphPrintCheckerState->isExplicitNullDeref(N))
1848            Out << "\\|Explicit-Null Dereference.\\l";
1849          else if (GraphPrintCheckerState->isUndefDeref(N))
1850            Out << "\\|Dereference of undefialied value.\\l";
1851          else if (GraphPrintCheckerState->isUndefStore(N))
1852            Out << "\\|Store to Undefined Loc.";
1853          else if (GraphPrintCheckerState->isUndefResult(N))
1854            Out << "\\|Result of operation is undefined.";
1855          else if (GraphPrintCheckerState->isNoReturnCall(N))
1856            Out << "\\|Call to function marked \"noreturn\".";
1857          else if (GraphPrintCheckerState->isBadCall(N))
1858            Out << "\\|Call to NULL/Undefined.";
1859          else if (GraphPrintCheckerState->isUndefArg(N))
1860            Out << "\\|Argument in call is undefined";
1861#endif
1862
1863          break;
1864        }
1865
1866        const BlockEdge &E = cast<BlockEdge>(Loc);
1867        Out << "Edge: (B" << E.getSrc()->getBlockID() << ", B"
1868            << E.getDst()->getBlockID()  << ')';
1869
1870        if (const Stmt *T = E.getSrc()->getTerminator()) {
1871
1872          SourceLocation SLoc = T->getLocStart();
1873
1874          Out << "\\|Terminator: ";
1875          LangOptions LO; // FIXME.
1876          E.getSrc()->printTerminator(Out, LO);
1877
1878          if (SLoc.isFileID()) {
1879            Out << "\\lline="
1880              << GraphPrintSourceManager->getExpansionLineNumber(SLoc)
1881              << " col="
1882              << GraphPrintSourceManager->getExpansionColumnNumber(SLoc);
1883          }
1884
1885          if (isa<SwitchStmt>(T)) {
1886            const Stmt *Label = E.getDst()->getLabel();
1887
1888            if (Label) {
1889              if (const CaseStmt *C = dyn_cast<CaseStmt>(Label)) {
1890                Out << "\\lcase ";
1891                LangOptions LO; // FIXME.
1892                C->getLHS()->printPretty(Out, 0, PrintingPolicy(LO));
1893
1894                if (const Stmt *RHS = C->getRHS()) {
1895                  Out << " .. ";
1896                  RHS->printPretty(Out, 0, PrintingPolicy(LO));
1897                }
1898
1899                Out << ":";
1900              }
1901              else {
1902                assert (isa<DefaultStmt>(Label));
1903                Out << "\\ldefault:";
1904              }
1905            }
1906            else
1907              Out << "\\l(implicit) default:";
1908          }
1909          else if (isa<IndirectGotoStmt>(T)) {
1910            // FIXME
1911          }
1912          else {
1913            Out << "\\lCondition: ";
1914            if (*E.getSrc()->succ_begin() == E.getDst())
1915              Out << "true";
1916            else
1917              Out << "false";
1918          }
1919
1920          Out << "\\l";
1921        }
1922
1923#if 0
1924          // FIXME: Replace with a general scheme to determine
1925          // the name of the check.
1926        if (GraphPrintCheckerState->isUndefControlFlow(N)) {
1927          Out << "\\|Control-flow based on\\lUndefined value.\\l";
1928        }
1929#endif
1930      }
1931    }
1932
1933    const ProgramState *state = N->getState();
1934    Out << "\\|StateID: " << (void*) state
1935        << " NodeID: " << (void*) N << "\\|";
1936    state->printDOT(Out, *N->getLocationContext()->getCFG());
1937
1938    Out << "\\l";
1939
1940    if (const ProgramPointTag *tag = Loc.getTag()) {
1941      Out << "\\|Tag: " << tag->getTagDescription();
1942      Out << "\\l";
1943    }
1944    return Out.str();
1945  }
1946};
1947} // end llvm namespace
1948#endif
1949
1950#ifndef NDEBUG
1951template <typename ITERATOR>
1952ExplodedNode *GetGraphNode(ITERATOR I) { return *I; }
1953
1954template <> ExplodedNode*
1955GetGraphNode<llvm::DenseMap<ExplodedNode*, Expr*>::iterator>
1956  (llvm::DenseMap<ExplodedNode*, Expr*>::iterator I) {
1957  return I->first;
1958}
1959#endif
1960
1961void ExprEngine::ViewGraph(bool trim) {
1962#ifndef NDEBUG
1963  if (trim) {
1964    std::vector<ExplodedNode*> Src;
1965
1966    // Flush any outstanding reports to make sure we cover all the nodes.
1967    // This does not cause them to get displayed.
1968    for (BugReporter::iterator I=BR.begin(), E=BR.end(); I!=E; ++I)
1969      const_cast<BugType*>(*I)->FlushReports(BR);
1970
1971    // Iterate through the reports and get their nodes.
1972    for (BugReporter::EQClasses_iterator
1973           EI = BR.EQClasses_begin(), EE = BR.EQClasses_end(); EI != EE; ++EI) {
1974      BugReportEquivClass& EQ = *EI;
1975      const BugReport &R = **EQ.begin();
1976      ExplodedNode *N = const_cast<ExplodedNode*>(R.getErrorNode());
1977      if (N) Src.push_back(N);
1978    }
1979
1980    ViewGraph(&Src[0], &Src[0]+Src.size());
1981  }
1982  else {
1983    GraphPrintCheckerState = this;
1984    GraphPrintSourceManager = &getContext().getSourceManager();
1985
1986    llvm::ViewGraph(*G.roots_begin(), "ExprEngine");
1987
1988    GraphPrintCheckerState = NULL;
1989    GraphPrintSourceManager = NULL;
1990  }
1991#endif
1992}
1993
1994void ExprEngine::ViewGraph(ExplodedNode** Beg, ExplodedNode** End) {
1995#ifndef NDEBUG
1996  GraphPrintCheckerState = this;
1997  GraphPrintSourceManager = &getContext().getSourceManager();
1998
1999  std::auto_ptr<ExplodedGraph> TrimmedG(G.Trim(Beg, End).first);
2000
2001  if (!TrimmedG.get())
2002    llvm::errs() << "warning: Trimmed ExplodedGraph is empty.\n";
2003  else
2004    llvm::ViewGraph(*TrimmedG->roots_begin(), "TrimmedExprEngine");
2005
2006  GraphPrintCheckerState = NULL;
2007  GraphPrintSourceManager = NULL;
2008#endif
2009}
2010