ExprEngine.cpp revision f540c54701e3eeb34cb619a3a4eb18f1ac70ef2d
15f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//=-- ExprEngine.cpp - Path-Sensitive Expression-Level Dataflow ---*- C++ -*-=
25f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
35f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//                     The LLVM Compiler Infrastructure
45f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
50bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// This file is distributed under the University of Illinois Open Source
60bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// License. See LICENSE.TXT for details.
75f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
85f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
95f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//  This file defines a meta-engine for path-sensitive dataflow analysis that
115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//  is built on GREngine, but provides the boilerplate to execute transfer
125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//  functions and build the ExplodedGraph at the expression level.
135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#define DEBUG_TYPE "ExprEngine"
1794deaf675ae60e11c2d9475c6dbfd0c7123160f5Anders Carlsson
185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "clang/StaticAnalyzer/Core/CheckerManager.h"
195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
20161755a09898c95d21bfff33707da9ca41cd53c5John McCall#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
215baba9d98364a3525d6afa15a04cdad82fd6dd30John McCall#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
22709210feee317b8d6690dd1d15c2b74cfe55e261Ted Kremenek#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
2371a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis#include "clang/AST/CharUnits.h"
24409c99edb8b623403fade6f3a9e9c86acda74455Anders Carlsson#include "clang/AST/ParentMap.h"
25f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne#include "clang/AST/StmtObjC.h"
265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "clang/AST/StmtCXX.h"
27525a05093a4816af961fe2bc6b8a81c17e2e26c2Chris Lattner#include "clang/Basic/Builtins.h"
283b8d116703db8018f855cbb4733ace426422623bNate Begeman#include "clang/Basic/SourceManager.h"
29b648023da23e8b227cdda57a241db4c6f368726bDaniel Dunbar#include "clang/Basic/PrettyStackTrace.h"
30403ba3522d1b1c97ae5fad81c1a2c4b3a754e1c1Nick Lewycky#include "llvm/Support/raw_ostream.h"
315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "llvm/ADT/ImmutableList.h"
325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "llvm/ADT/Statistic.h"
33590b6646ef747d2f7b42e5f40487ff07642d7b6fChris Lattner
34c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlsson#ifndef NDEBUG
35c4a1dea2dc56bd1357ec91b829a0b9e68229a13eDaniel Dunbar#include "llvm/Support/GraphWriter.h"
36c4a1dea2dc56bd1357ec91b829a0b9e68229a13eDaniel Dunbar#endif
37c4a1dea2dc56bd1357ec91b829a0b9e68229a13eDaniel Dunbar
388e9bebdea69c590dedfbf27374114cb76fe12fbdDouglas Gregorusing namespace clang;
39c4a1dea2dc56bd1357ec91b829a0b9e68229a13eDaniel Dunbarusing namespace ento;
4056ee6896f2efebffb4a2cce5a7610cdf1eddbbbeSteve Naroffusing llvm::APSInt;
41409c99edb8b623403fade6f3a9e9c86acda74455Anders Carlsson
4288a3514f36de96b19cdf50141c640df1a5f13f6cDouglas GregorSTATISTIC(NumRemoveDeadBindings,
4388a3514f36de96b19cdf50141c640df1a5f13f6cDouglas Gregor            "The # of times RemoveDeadBindings is called");
44f6a1648197562e0b133440d612d9af297d0a86ccJohn McCallSTATISTIC(NumMaxBlockCountReached,
4556ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall            "The # of aborted paths due to reaching the maximum block count in "
4688a3514f36de96b19cdf50141c640df1a5f13f6cDouglas Gregor            "a top level function");
477ab9d574d27ecee1f130e5755aa403e5ab529b6bAnders CarlssonSTATISTIC(NumMaxBlockCountReachedInInlined,
48686775deca8b8685eb90801495880e3abdd844c2Chris Lattner            "The # of aborted paths due to reaching the maximum block count in "
497ab9d574d27ecee1f130e5755aa403e5ab529b6bAnders Carlsson            "an inlined function");
505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid SpencerSTATISTIC(NumTimesRetriedWithoutInlining,
515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer            "The # of times we re-evaluated a call without inlining");
525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// Engine construction and deletion.
555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
56898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor
578e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCallExprEngine::ExprEngine(AnalysisManager &mgr, bool gcEnabled,
58f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall                       SetOfConstDecls *VisitedCallees,
59561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor                       FunctionSummariesTy *FS)
60561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor  : AMgr(mgr),
61561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor    AnalysisDeclContexts(mgr.getAnalysisDeclContextManager()),
628e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall    Engine(*this, VisitedCallees, FS),
638e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall    G(Engine.getGraph()),
64561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor    StateMgr(getContext(), mgr.getStoreManagerCreator(),
65f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall             mgr.getConstraintManagerCreator(), G.getAllocator(),
66f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall             *this),
67bebbe0d9b7568ce43a464286bee49429489ef483Douglas Gregor    SymMgr(StateMgr.getSymbolManager()),
68898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor    svalBuilder(StateMgr.getSValBuilder()),
69898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor    EntryNode(NULL),
70898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor    currentStmt(NULL), currentStmtIdx(0), currentBuilderContext(0),
710b7489194f9f89fac39d57211c1e7953ae50251fDouglas Gregor    NSExceptionII(NULL), NSExceptionInstanceRaiseSelectors(NULL),
720b7489194f9f89fac39d57211c1e7953ae50251fDouglas Gregor    RaiseSel(GetNullarySelector("raise", getContext())),
730b7489194f9f89fac39d57211c1e7953ae50251fDouglas Gregor    ObjCGCEnabled(gcEnabled), BR(mgr, *this) {
741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
75f7c2aa0b049272d8f318988c1965760dcb852578Douglas Gregor  if (mgr.shouldEagerlyTrimExplodedGraph()) {
761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    // Enable eager node reclaimation when constructing the ExplodedGraph.
779d293dfc0ad7c44ae0b5eb9517f1ed8c8d8b7ff7Douglas Gregor    G.enableNodeReclamation();
789d293dfc0ad7c44ae0b5eb9517f1ed8c8d8b7ff7Douglas Gregor  }
799d293dfc0ad7c44ae0b5eb9517f1ed8c8d8b7ff7Douglas Gregor}
809d293dfc0ad7c44ae0b5eb9517f1ed8c8d8b7ff7Douglas Gregor
819d293dfc0ad7c44ae0b5eb9517f1ed8c8d8b7ff7Douglas GregorExprEngine::~ExprEngine() {
829d293dfc0ad7c44ae0b5eb9517f1ed8c8d8b7ff7Douglas Gregor  BR.FlushReports();
839d293dfc0ad7c44ae0b5eb9517f1ed8c8d8b7ff7Douglas Gregor  delete [] NSExceptionInstanceRaiseSelectors;
84905d11d53aeb6b26744f44fedc2b2820c7a62df6Douglas Gregor}
858320aaaa01d931aa234fc3bce05b399ef41898d5Daniel Dunbar
86f7c2aa0b049272d8f318988c1965760dcb852578Douglas Gregor//===----------------------------------------------------------------------===//
871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump// Utility methods.
889d293dfc0ad7c44ae0b5eb9517f1ed8c8d8b7ff7Douglas Gregor//===----------------------------------------------------------------------===//
8977ed8e4edf6ed78c53fb20ec3210aff2a59c9d87Ted Kremenek
90898574e7496ba8fd76290079d3a9d06954992734Douglas GregorProgramStateRef ExprEngine::getInitialState(const LocationContext *InitLoc) {
91898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor  ProgramStateRef state = StateMgr.getInitialState(InitLoc);
92898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor  const Decl *D = InitLoc->getDecl();
931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
94898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor  // Preconditions.
95898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor  // FIXME: It would be nice if we had a more general mechanism to add
96898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor  // such preconditions.  Some day.
978e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall  do {
98898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor
990b7489194f9f89fac39d57211c1e7953ae50251fDouglas Gregor    if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
100561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor      // Precondition: the first argument of 'main' is an integer guaranteed
101561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor      //  to be > 0.
102561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor      const IdentifierInfo *II = FD->getIdentifier();
103561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor      if (!II || !(II->getName() == "main" && FD->getNumParams() > 0))
104561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor        break;
1050b7489194f9f89fac39d57211c1e7953ae50251fDouglas Gregor
106898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor      const ParmVarDecl *PD = FD->getParamDecl(0);
107898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor      QualType T = PD->getType();
108898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor      if (!T->isIntegerType())
109898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor        break;
110898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor
111898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor      const MemRegion *R = state->getRegion(PD, InitLoc);
1121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      if (!R)
113898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor        break;
114898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor
115898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor      SVal V = state->getSVal(loc::MemRegionVal(R));
116898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor      SVal Constraint_untested = evalBinOp(state, BO_GT, V,
1178e6285af719adc6f86d6faa235d22a08eb68ee3aJohn McCall                                           svalBuilder.makeZeroVal(T),
118898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor                                           getContext().IntTy);
1190b7489194f9f89fac39d57211c1e7953ae50251fDouglas Gregor
120561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor      DefinedOrUnknownSVal *Constraint =
121561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor        dyn_cast<DefinedOrUnknownSVal>(&Constraint_untested);
122561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor
123561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor      if (!Constraint)
124561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor        break;
125561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor
126561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor      if (ProgramStateRef newState = state->assume(*Constraint, true))
127561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor        state = newState;
128561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor    }
129561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor    break;
130561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor  }
131561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor  while (0);
132561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor
133561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor  if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
134561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor    // Precondition: 'self' is always non-null upon entry to an Objective-C
135561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor    // method.
136561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor    const ImplicitParamDecl *SelfD = MD->getSelfDecl();
137561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor    const MemRegion *R = state->getRegion(SelfD, InitLoc);
138561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor    SVal V = state->getSVal(loc::MemRegionVal(R));
139561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor
140561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor    if (const Loc *LV = dyn_cast<Loc>(&V)) {
141561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor      // Assume that the pointer value in 'self' is non-null.
142561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor      state = state->assume(*LV, true);
143561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor      assert(state && "'self' cannot be null");
144561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor    }
145561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor  }
146561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor
147561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor  if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) {
148561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor    if (!MD->isStatic()) {
149561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor      // Precondition: 'this' is always non-null upon entry to the
150561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor      // top-level function.  This is our starting assumption for
1510b7489194f9f89fac39d57211c1e7953ae50251fDouglas Gregor      // analyzing an "open" program.
152d0937224f383c7cc72c947119380f9713a070c73Douglas Gregor      const StackFrameContext *SFC = InitLoc->getCurrentStackFrame();
153d0937224f383c7cc72c947119380f9713a070c73Douglas Gregor      if (SFC->getParent() == 0) {
154d0937224f383c7cc72c947119380f9713a070c73Douglas Gregor        loc::MemRegionVal L = svalBuilder.getCXXThis(MD, SFC);
155d0937224f383c7cc72c947119380f9713a070c73Douglas Gregor        SVal V = state->getSVal(L);
156d0937224f383c7cc72c947119380f9713a070c73Douglas Gregor        if (const Loc *LV = dyn_cast<Loc>(&V)) {
157d0937224f383c7cc72c947119380f9713a070c73Douglas Gregor          state = state->assume(*LV, true);
158d0937224f383c7cc72c947119380f9713a070c73Douglas Gregor          assert(state && "'this' cannot be null");
159d0937224f383c7cc72c947119380f9713a070c73Douglas Gregor        }
160d0937224f383c7cc72c947119380f9713a070c73Douglas Gregor      }
161d0937224f383c7cc72c947119380f9713a070c73Douglas Gregor    }
162d0937224f383c7cc72c947119380f9713a070c73Douglas Gregor  }
163d0937224f383c7cc72c947119380f9713a070c73Douglas Gregor
164d0937224f383c7cc72c947119380f9713a070c73Douglas Gregor  return state;
165d0937224f383c7cc72c947119380f9713a070c73Douglas Gregor}
166d0937224f383c7cc72c947119380f9713a070c73Douglas Gregor
167d0937224f383c7cc72c947119380f9713a070c73Douglas Gregor//===----------------------------------------------------------------------===//
168d0937224f383c7cc72c947119380f9713a070c73Douglas Gregor// Top-level transfer function logic (Dispatcher).
169d0937224f383c7cc72c947119380f9713a070c73Douglas Gregor//===----------------------------------------------------------------------===//
170bebbe0d9b7568ce43a464286bee49429489ef483Douglas Gregor
171bebbe0d9b7568ce43a464286bee49429489ef483Douglas Gregor/// evalAssume - Called by ConstraintManager. Used to call checker-specific
172bebbe0d9b7568ce43a464286bee49429489ef483Douglas Gregor///  logic for handling assumptions on symbolic values.
173bebbe0d9b7568ce43a464286bee49429489ef483Douglas GregorProgramStateRef ExprEngine::processAssume(ProgramStateRef state,
174bebbe0d9b7568ce43a464286bee49429489ef483Douglas Gregor                                              SVal cond, bool assumption) {
175bebbe0d9b7568ce43a464286bee49429489ef483Douglas Gregor  return getCheckerManager().runCheckersForEvalAssume(state, cond, assumption);
1765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
1775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
17863c00d7f35fa060c0a446c9df3a4402d9c7757feJohn McCallbool ExprEngine::wantsRegionChangeUpdate(ProgramStateRef state) {
1791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  return getCheckerManager().wantsRegionChangeUpdate(state);
180026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner}
181026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner
182026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris LattnerProgramStateRef
183026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris LattnerExprEngine::processRegionChanges(ProgramStateRef state,
184026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner                            const StoreManager::InvalidatedSymbols *invalidated,
185df317bf71653eeb235da8337b1e8e790f9653aa4Mike Stump                                 ArrayRef<const MemRegion *> Explicits,
1861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                 ArrayRef<const MemRegion *> Regions,
1877eb0a9eb0cde8444b97f9c5b713d9be7a6f1e607John McCall                                 const CallEvent *Call) {
1887eb0a9eb0cde8444b97f9c5b713d9be7a6f1e607John McCall  return getCheckerManager().runCheckersForRegionChanges(state, invalidated,
1897eb0a9eb0cde8444b97f9c5b713d9be7a6f1e607John McCall                                                      Explicits, Regions, Call);
1907eb0a9eb0cde8444b97f9c5b713d9be7a6f1e607John McCall}
1917eb0a9eb0cde8444b97f9c5b713d9be7a6f1e607John McCall
1927eb0a9eb0cde8444b97f9c5b713d9be7a6f1e607John McCallvoid ExprEngine::printState(raw_ostream &Out, ProgramStateRef State,
1935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                            const char *NL, const char *Sep) {
1947eb0a9eb0cde8444b97f9c5b713d9be7a6f1e607John McCall  getCheckerManager().runCheckersForPrintState(Out, State, NL, Sep);
1957eb0a9eb0cde8444b97f9c5b713d9be7a6f1e607John McCall}
1967eb0a9eb0cde8444b97f9c5b713d9be7a6f1e607John McCall
1977eb0a9eb0cde8444b97f9c5b713d9be7a6f1e607John McCallvoid ExprEngine::processEndWorklist(bool hasWorkRemaining) {
1987eb0a9eb0cde8444b97f9c5b713d9be7a6f1e607John McCall  getCheckerManager().runCheckersForEndAnalysis(G, BR, *this);
1997eb0a9eb0cde8444b97f9c5b713d9be7a6f1e607John McCall}
2007eb0a9eb0cde8444b97f9c5b713d9be7a6f1e607John McCall
2017eb0a9eb0cde8444b97f9c5b713d9be7a6f1e607John McCallvoid ExprEngine::processCFGElement(const CFGElement E, ExplodedNode *Pred,
2027eb0a9eb0cde8444b97f9c5b713d9be7a6f1e607John McCall                                   unsigned StmtIdx, NodeBuilderContext *Ctx) {
2037eb0a9eb0cde8444b97f9c5b713d9be7a6f1e607John McCall  currentStmtIdx = StmtIdx;
2047eb0a9eb0cde8444b97f9c5b713d9be7a6f1e607John McCall  currentBuilderContext = Ctx;
2057eb0a9eb0cde8444b97f9c5b713d9be7a6f1e607John McCall
2065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  switch (E.getKind()) {
2075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    case CFGElement::Invalid:
2085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      llvm_unreachable("Unexpected CFGElement kind.");
209fec0b49c3fa621fbf63e420f3d54a5bb3a0265d2Steve Naroff    case CFGElement::Statement:
21086f194083504938df72135b5b66bf0c5cafd9498Douglas Gregor      ProcessStmt(const_cast<Stmt*>(E.getAs<CFGStmt>()->getStmt()), Pred);
211077f490d0a514dcc448475f33f799934252b85a7Fariborz Jahanian      return;
2122514a309204341798f96912ce7a90841bea59727Fariborz Jahanian    case CFGElement::Initializer:
213e9ff443040cb571ae2c5c2626c4dc9a9a812d84aFariborz Jahanian      ProcessInitializer(E.getAs<CFGInitializer>()->getInitializer(), Pred);
214e873fb74219f48407ae0b8fa083aa7f0b6ff1427Douglas Gregor      return;
2155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    case CFGElement::AutomaticObjectDtor:
2167eb0a9eb0cde8444b97f9c5b713d9be7a6f1e607John McCall    case CFGElement::BaseDtor:
2177eb0a9eb0cde8444b97f9c5b713d9be7a6f1e607John McCall    case CFGElement::MemberDtor:
21853202857c60214d80950a975e6e52aebf30bd16aEli Friedman    case CFGElement::TemporaryDtor:
2195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      ProcessImplicitDtor(*E.getAs<CFGImplicitDtor>(), Pred);
2205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      return;
2211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  }
2225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  currentBuilderContext = 0;
2235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
22444e35f7b2b5da1eb338639e46bf0b5522e75c5f3Daniel Dunbar
22544e35f7b2b5da1eb338639e46bf0b5522e75c5f3Daniel Dunbarstatic bool shouldRemoveDeadBindings(AnalysisManager &AMgr,
22644e35f7b2b5da1eb338639e46bf0b5522e75c5f3Daniel Dunbar                                     const CFGStmt S,
22744e35f7b2b5da1eb338639e46bf0b5522e75c5f3Daniel Dunbar                                     const ExplodedNode *Pred,
2285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                                     const LocationContext *LC) {
2295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Are we never purging state values?
2315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (AMgr.getPurgeMode() == PurgeNone)
232fec0b49c3fa621fbf63e420f3d54a5bb3a0265d2Steve Naroff    return false;
2335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
234ca354faa7e9b99af17070c82b9662a5fca76422cChris Lattner  // Is this the beginning of a basic block?
2355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (isa<BlockEntrance>(Pred->getLocation()))
2365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return true;
2374f6a7d7ead09b439216c32f2de806a998aeb222aSteve Naroff
2385daf570d0ce027e18ed5f9d66e6b2a14a40b720dFariborz Jahanian  // Is this on a non-expression?
239ba8d2d684e74a20bef03828c21c991d222c7e9e5Fariborz Jahanian  if (!isa<Expr>(S.getStmt()))
24086f194083504938df72135b5b66bf0c5cafd9498Douglas Gregor    return true;
2412514a309204341798f96912ce7a90841bea59727Fariborz Jahanian
242e9ff443040cb571ae2c5c2626c4dc9a9a812d84aFariborz Jahanian  // Run before processing a call.
243077f490d0a514dcc448475f33f799934252b85a7Fariborz Jahanian  if (CallEvent::mayBeInlined(S.getStmt()))
244e873fb74219f48407ae0b8fa083aa7f0b6ff1427Douglas Gregor    return true;
2455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
24644e35f7b2b5da1eb338639e46bf0b5522e75c5f3Daniel Dunbar  // Is this an expression that is consumed by another expression?  If so,
24744e35f7b2b5da1eb338639e46bf0b5522e75c5f3Daniel Dunbar  // postpone cleaning out the state.
2481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  ParentMap &PM = LC->getAnalysisDeclContext()->getParentMap();
2492111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl  return !PM.isConsumedExpr(cast<Expr>(S.getStmt()));
2502111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl}
2512111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl
2522111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redlvoid ExprEngine::removeDead(ExplodedNode *Pred, ExplodedNodeSet &Out,
2532111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl                            const Stmt *ReferenceStmt,
2542111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl                            const LocationContext *LC,
2552111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl                            const Stmt *DiagnosticStmt,
2562111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl                            ProgramPoint::Kind K) {
2572111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl  assert((K == ProgramPoint::PreStmtPurgeDeadSymbolsKind ||
2582111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl          ReferenceStmt == 0) && "PreStmt is not generally supported by "
2591c860d5640e8eebb11a5d515a761242b66761b0bPeter Collingbourne                                 "the SymbolReaper yet");
2602111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl  NumRemoveDeadBindings++;
2612111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl  CleanedState = Pred->getState();
2622111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl  SymbolReaper SymReaper(LC, ReferenceStmt, SymMgr, getStoreManager());
2632111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl
264077f490d0a514dcc448475f33f799934252b85a7Fariborz Jahanian  getCheckerManager().runCheckersForLiveSymbols(CleanedState, SymReaper);
2652111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl
2662111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl  // Create a state in which dead bindings are removed from the environment
2672111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl  // and the store. TODO: The function should just return new env and store,
2682111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl  // not a new state.
2692111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl  const StackFrameContext *SFC = LC->getCurrentStackFrame();
2702111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl  CleanedState = StateMgr.removeDeadBindings(CleanedState, SFC, SymReaper);
2712111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl
2722111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl  // Process any special transfer function for dead symbols.
2732111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl  // A tag to track convenience transitions, which can be removed at cleanup.
2742111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl  static SimpleProgramPointTag cleanupTag("ExprEngine : Clean Node");
2752111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl  if (!SymReaper.hasDeadSymbols()) {
2762111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl    // Generate a CleanedNode that has the environment and store cleaned
2772111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl    // up. Since no symbols are dead, we can optimize and not clean out
2782111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl    // the constraint manager.
2792111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl    StmtNodeBuilder Bldr(Pred, Out, *currentBuilderContext);
2802111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl    Bldr.generateNode(DiagnosticStmt, Pred, CleanedState, false, &cleanupTag,K);
2812111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl
2822111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl  } else {
2832111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl    // Call checkers with the non-cleaned state so that they could query the
2842111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl    // values of the soon to be dead symbols.
2852111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl    ExplodedNodeSet CheckedSet;
2862111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl    getCheckerManager().runCheckersForDeadSymbols(CheckedSet, Pred, SymReaper,
2872111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl                                                  DiagnosticStmt, *this, K);
2882111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl
2892111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl    // For each node in CheckedSet, generate CleanedNodes that have the
2902111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl    // environment, the store, and the constraints cleaned up but have the
2912111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl    // user-supplied states as the predecessors.
2922111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl    StmtNodeBuilder Bldr(CheckedSet, Out, *currentBuilderContext);
2932111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl    for (ExplodedNodeSet::const_iterator
2942111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl          I = CheckedSet.begin(), E = CheckedSet.end(); I != E; ++I) {
2952111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl      ProgramStateRef CheckerState = (*I)->getState();
2962111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl
2972111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl      // The constraint manager has not been cleaned up yet, so clean up now.
2982111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl      CheckerState = getConstraintManager().removeDeadBindings(CheckerState,
2992111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl                                                               SymReaper);
3002111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl
3012111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl      assert(StateMgr.haveEqualEnvironments(CheckerState, Pred->getState()) &&
3022111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl        "Checkers are not allowed to modify the Environment as a part of "
3032111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl        "checkDeadSymbols processing.");
3042111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl      assert(StateMgr.haveEqualStores(CheckerState, Pred->getState()) &&
3052c9a03f3b249e4d9d76eadf758a33142adc4d0a4Douglas Gregor        "Checkers are not allowed to modify the Store as a part of "
3062c9a03f3b249e4d9d76eadf758a33142adc4d0a4Douglas Gregor        "checkDeadSymbols processing.");
3072c9a03f3b249e4d9d76eadf758a33142adc4d0a4Douglas Gregor
3082c9a03f3b249e4d9d76eadf758a33142adc4d0a4Douglas Gregor      // Create a state based on CleanedState with CheckerState GDM and
3092c9a03f3b249e4d9d76eadf758a33142adc4d0a4Douglas Gregor      // generate a transition to that state.
3102c9a03f3b249e4d9d76eadf758a33142adc4d0a4Douglas Gregor      ProgramStateRef CleanedCheckerSt =
3112111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl        StateMgr.getPersistentStateWithGDM(CleanedState, CheckerState);
312369e51fa400aeb5835bb9af4634ea516c11429a7Sebastian Redl      Bldr.generateNode(DiagnosticStmt, *I, CleanedCheckerSt, false,
3132111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl                        &cleanupTag, K);
3142111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl    }
3152111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl  }
3162111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl}
3172111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl
3182111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redlvoid ExprEngine::ProcessStmt(const CFGStmt S,
3192111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl                             ExplodedNode *Pred) {
3202111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl  // Reclaim any unnecessary nodes in the ExplodedGraph.
3212111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl  G.reclaimRecentlyAllocatedNodes();
3222111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl
3232111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl  currentStmt = S.getStmt();
3242111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl  PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),
3252111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl                                currentStmt->getLocStart(),
3262111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl                                "Error evaluating statement");
3272111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl
328369e51fa400aeb5835bb9af4634ea516c11429a7Sebastian Redl  // Remove dead bindings and symbols.
3292111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl  EntryNode = Pred;
3302111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl  ExplodedNodeSet CleanedStates;
3312111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl  if (shouldRemoveDeadBindings(AMgr, S, Pred, EntryNode->getLocationContext())){
3322111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl    removeDead(EntryNode, CleanedStates, currentStmt,
3332111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl               Pred->getLocationContext(), currentStmt);
3342111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl  } else
3352111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl    CleanedStates.Add(EntryNode);
3362111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl
3372111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl  // Visit the statement.
3382111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl  ExplodedNodeSet Dst;
3392111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl  for (ExplodedNodeSet::iterator I = CleanedStates.begin(),
340f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall                                 E = CleanedStates.end(); I != E; ++I) {
341f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall    ExplodedNodeSet DstI;
342f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall    // Visit the statement.
343f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall    Visit(currentStmt, *I, DstI);
3440943168ac126b8047f30f6bd215fbe7db14d61baJohn McCall    Dst.insert(DstI);
3450943168ac126b8047f30f6bd215fbe7db14d61baJohn McCall  }
3460943168ac126b8047f30f6bd215fbe7db14d61baJohn McCall
3470943168ac126b8047f30f6bd215fbe7db14d61baJohn McCall  // Enqueue the new nodes onto the work list.
348f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall  Engine.enqueue(Dst, currentBuilderContext->getBlock(), currentStmtIdx);
349f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall
350f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall  // NULL out these variables to cleanup.
351f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall  CleanedState = NULL;
352f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall  EntryNode = NULL;
353f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall  currentStmt = 0;
354f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall}
355f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall
356f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCallvoid ExprEngine::ProcessInitializer(const CFGInitializer Init,
357f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall                                    ExplodedNode *Pred) {
358f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall  ExplodedNodeSet Dst;
359f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall  NodeBuilder Bldr(Pred, Dst, *currentBuilderContext);
360f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall
361f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall  ProgramStateRef State = Pred->getState();
362f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall
36356ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall  // We don't set EntryNode and currentStmt. And we don't clean up state.
36456ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall  const CXXCtorInitializer *BMI = Init.getInitializer();
36556ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall  const StackFrameContext *stackFrame =
36656ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall                           cast<StackFrameContext>(Pred->getLocationContext());
36756ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall  const CXXConstructorDecl *decl =
368f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall                           cast<CXXConstructorDecl>(stackFrame->getDecl());
369f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall  SVal thisVal = State->getSVal(svalBuilder.getCXXThis(decl, stackFrame));
370f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall
371f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall  // Evaluate the initializer, if necessary
372f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall  if (BMI->isAnyMemberInitializer()) {
373f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall    // Constructors build the object directly in the field,
3742111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl    // but non-objects must be copied in from the initializer.
3752111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl    if (!isa<CXXConstructExpr>(BMI->getInit())) {
3762111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl      SVal FieldLoc;
3772111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl      if (BMI->isIndirectMemberInitializer())
3782111c855343a0530e236bf0862358ec8d67b28f3Sebastian Redl        FieldLoc = State->getLValue(BMI->getIndirectMember(), thisVal);
37933bbbc5ec8269bc2cde5b84f970fa49319a30267Douglas Gregor      else
38033bbbc5ec8269bc2cde5b84f970fa49319a30267Douglas Gregor        FieldLoc = State->getLValue(BMI->getMember(), thisVal);
38133bbbc5ec8269bc2cde5b84f970fa49319a30267Douglas Gregor
3825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      SVal InitVal = State->getSVal(BMI->getInit(), stackFrame);
38338d068e8f13a119b89a3b8b0f79f35cab1ffd09aAnders Carlsson      State = State->bindLoc(FieldLoc, InitVal);
38438d068e8f13a119b89a3b8b0f79f35cab1ffd09aAnders Carlsson    }
38538d068e8f13a119b89a3b8b0f79f35cab1ffd09aAnders Carlsson  } else {
3861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    assert(BMI->isBaseInitializer());
387f6a1648197562e0b133440d612d9af297d0a86ccJohn McCall    // We already did all the work when visiting the CXXConstructExpr.
388f6a1648197562e0b133440d612d9af297d0a86ccJohn McCall  }
389f6a1648197562e0b133440d612d9af297d0a86ccJohn McCall
390f6a1648197562e0b133440d612d9af297d0a86ccJohn McCall  // Construct a PostInitializer node whether the state changed or not,
391093802675b1548f2a5f44c29938d65cce00d58bbAnders Carlsson  // so that the diagnostics don't get confused.
392093802675b1548f2a5f44c29938d65cce00d58bbAnders Carlsson  PostInitializer PP(BMI, stackFrame);
3934919dfd54e2296ca997e3d1c9dab85976bba8e95John McCall  // Builder automatically add the generated node to the deferred set,
3944919dfd54e2296ca997e3d1c9dab85976bba8e95John McCall  // which are processed in the builder's dtor.
3954919dfd54e2296ca997e3d1c9dab85976bba8e95John McCall  Bldr.generateNode(PP, State, Pred);
3964919dfd54e2296ca997e3d1c9dab85976bba8e95John McCall
3974919dfd54e2296ca997e3d1c9dab85976bba8e95John McCall  // Enqueue the new nodes onto the work list.
3984919dfd54e2296ca997e3d1c9dab85976bba8e95John McCall  Engine.enqueue(Dst, currentBuilderContext->getBlock(), currentStmtIdx);
3994919dfd54e2296ca997e3d1c9dab85976bba8e95John McCall}
4004919dfd54e2296ca997e3d1c9dab85976bba8e95John McCall
40185def357129b6cdfd69a66ad0e6994506418a2a9John McCallvoid ExprEngine::ProcessImplicitDtor(const CFGImplicitDtor D,
4024919dfd54e2296ca997e3d1c9dab85976bba8e95John McCall                                     ExplodedNode *Pred) {
4034919dfd54e2296ca997e3d1c9dab85976bba8e95John McCall  ExplodedNodeSet Dst;
4044919dfd54e2296ca997e3d1c9dab85976bba8e95John McCall  switch (D.getKind()) {
4054919dfd54e2296ca997e3d1c9dab85976bba8e95John McCall  case CFGElement::AutomaticObjectDtor:
406c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt    ProcessAutomaticObjDtor(cast<CFGAutomaticObjDtor>(D), Pred, Dst);
4072b334bb3126a67895813e49e6228dad4aec0b4d6Chris Lattner    break;
4082b334bb3126a67895813e49e6228dad4aec0b4d6Chris Lattner  case CFGElement::BaseDtor:
4092b334bb3126a67895813e49e6228dad4aec0b4d6Chris Lattner    ProcessBaseDtor(cast<CFGBaseDtor>(D), Pred, Dst);
4102b334bb3126a67895813e49e6228dad4aec0b4d6Chris Lattner    break;
4112b334bb3126a67895813e49e6228dad4aec0b4d6Chris Lattner  case CFGElement::MemberDtor:
412c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt    ProcessMemberDtor(cast<CFGMemberDtor>(D), Pred, Dst);
4135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    break;
4145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  case CFGElement::TemporaryDtor:
4155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    ProcessTemporaryDtor(cast<CFGTemporaryDtor>(D), Pred, Dst);
4165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    break;
417590b6646ef747d2f7b42e5f40487ff07642d7b6fChris Lattner  default:
418590b6646ef747d2f7b42e5f40487ff07642d7b6fChris Lattner    llvm_unreachable("Unexpected dtor kind.");
4195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
420590b6646ef747d2f7b42e5f40487ff07642d7b6fChris Lattner
4218070a8497c0fb3e6f70a557f788405d8945b1208Daniel Dunbar  // Enqueue the new nodes onto the work list.
422590b6646ef747d2f7b42e5f40487ff07642d7b6fChris Lattner  Engine.enqueue(Dst, currentBuilderContext->getBlock(), currentStmtIdx);
4235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
424c9e8f606787b0bc0c3b08e566b87cc1751694168Eli Friedman
425c9e8f606787b0bc0c3b08e566b87cc1751694168Eli Friedmanvoid ExprEngine::ProcessAutomaticObjDtor(const CFGAutomaticObjDtor Dtor,
4264204f07fc8bffe6d320b2de95fea274ccf37a17bJohn McCall                                         ExplodedNode *Pred,
4271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                         ExplodedNodeSet &Dst) {
4281e12c59e8f9bb76c23628c4e0d0a1dfced0b1fa0Richard Smith  ProgramStateRef state = Pred->getState();
4291e12c59e8f9bb76c23628c4e0d0a1dfced0b1fa0Richard Smith  const VarDecl *varDecl = Dtor.getVarDecl();
43094deaf675ae60e11c2d9475c6dbfd0c7123160f5Anders Carlsson
43194deaf675ae60e11c2d9475c6dbfd0c7123160f5Anders Carlsson  QualType varType = varDecl->getType();
43294deaf675ae60e11c2d9475c6dbfd0c7123160f5Anders Carlsson
4331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  if (const ReferenceType *refType = varType->getAs<ReferenceType>())
43494deaf675ae60e11c2d9475c6dbfd0c7123160f5Anders Carlsson    varType = refType->getPointeeType();
43594deaf675ae60e11c2d9475c6dbfd0c7123160f5Anders Carlsson
43694deaf675ae60e11c2d9475c6dbfd0c7123160f5Anders Carlsson  Loc dest = state->getLValue(varDecl, Pred->getLocationContext());
43794deaf675ae60e11c2d9475c6dbfd0c7123160f5Anders Carlsson
43894deaf675ae60e11c2d9475c6dbfd0c7123160f5Anders Carlsson  VisitCXXDestructor(varType, cast<loc::MemRegionVal>(dest).getRegion(),
43994deaf675ae60e11c2d9475c6dbfd0c7123160f5Anders Carlsson                     Dtor.getTriggerStmt(), Pred, Dst);
44094deaf675ae60e11c2d9475c6dbfd0c7123160f5Anders Carlsson}
44194deaf675ae60e11c2d9475c6dbfd0c7123160f5Anders Carlsson
44294deaf675ae60e11c2d9475c6dbfd0c7123160f5Anders Carlssonvoid ExprEngine::ProcessBaseDtor(const CFGBaseDtor D,
44394deaf675ae60e11c2d9475c6dbfd0c7123160f5Anders Carlsson                                 ExplodedNode *Pred, ExplodedNodeSet &Dst) {
44494deaf675ae60e11c2d9475c6dbfd0c7123160f5Anders Carlsson  const LocationContext *LCtx = Pred->getLocationContext();
4451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  ProgramStateRef State = Pred->getState();
4461e12c59e8f9bb76c23628c4e0d0a1dfced0b1fa0Richard Smith
447e17a6436b429e4b18a5e157061fb13bbc677b3b0Abramo Bagnara  const CXXDestructorDecl *CurDtor = cast<CXXDestructorDecl>(LCtx->getDecl());
448e17a6436b429e4b18a5e157061fb13bbc677b3b0Abramo Bagnara  Loc ThisPtr = getSValBuilder().getCXXThis(CurDtor,
449e17a6436b429e4b18a5e157061fb13bbc677b3b0Abramo Bagnara                                            LCtx->getCurrentStackFrame());
450e17a6436b429e4b18a5e157061fb13bbc677b3b0Abramo Bagnara  SVal ThisVal = Pred->getState()->getSVal(ThisPtr);
451e17a6436b429e4b18a5e157061fb13bbc677b3b0Abramo Bagnara
452e17a6436b429e4b18a5e157061fb13bbc677b3b0Abramo Bagnara  // Create the base object region.
45394deaf675ae60e11c2d9475c6dbfd0c7123160f5Anders Carlsson  QualType BaseTy = D.getBaseSpecifier()->getType();
45494deaf675ae60e11c2d9475c6dbfd0c7123160f5Anders Carlsson  SVal BaseVal = getStoreManager().evalDerivedToBase(ThisVal, BaseTy);
4551e12c59e8f9bb76c23628c4e0d0a1dfced0b1fa0Richard Smith
4561e12c59e8f9bb76c23628c4e0d0a1dfced0b1fa0Richard Smith  VisitCXXDestructor(BaseTy, cast<loc::MemRegionVal>(BaseVal).getRegion(),
4571e12c59e8f9bb76c23628c4e0d0a1dfced0b1fa0Richard Smith                     CurDtor->getBody(), Pred, Dst);
4581e12c59e8f9bb76c23628c4e0d0a1dfced0b1fa0Richard Smith}
4591e12c59e8f9bb76c23628c4e0d0a1dfced0b1fa0Richard Smith
4601e12c59e8f9bb76c23628c4e0d0a1dfced0b1fa0Richard Smithvoid ExprEngine::ProcessMemberDtor(const CFGMemberDtor D,
4611e12c59e8f9bb76c23628c4e0d0a1dfced0b1fa0Richard Smith                                   ExplodedNode *Pred, ExplodedNodeSet &Dst) {
4621e12c59e8f9bb76c23628c4e0d0a1dfced0b1fa0Richard Smith  const FieldDecl *Member = D.getFieldDecl();
4631e12c59e8f9bb76c23628c4e0d0a1dfced0b1fa0Richard Smith  ProgramStateRef State = Pred->getState();
4641e12c59e8f9bb76c23628c4e0d0a1dfced0b1fa0Richard Smith  const LocationContext *LCtx = Pred->getLocationContext();
4656ee7aa154e8bbb21a21254293410b944f78b0bfeChris Lattner
466019f4e858e78587f2241ff1a76c747d7bcd7578cChris Lattner  const CXXDestructorDecl *CurDtor = cast<CXXDestructorDecl>(LCtx->getDecl());
467019f4e858e78587f2241ff1a76c747d7bcd7578cChris Lattner  Loc ThisVal = getSValBuilder().getCXXThis(CurDtor,
468019f4e858e78587f2241ff1a76c747d7bcd7578cChris Lattner                                            LCtx->getCurrentStackFrame());
4694ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad  SVal FieldVal = State->getLValue(Member, cast<Loc>(State->getSVal(ThisVal)));
4705b45d4ef1ea3f04ec863daf8aa29be6c6e021750Anders Carlsson
471cd7a445c6b46c5585580dfb652300c8483c0cb6bJohn McCall  VisitCXXDestructor(Member->getType(),
472cd7a445c6b46c5585580dfb652300c8483c0cb6bJohn McCall                     cast<loc::MemRegionVal>(FieldVal).getRegion(),
473a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith                     CurDtor->getBody(), Pred, Dst);
474a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith}
4754ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad
476cd7a445c6b46c5585580dfb652300c8483c0cb6bJohn McCallvoid ExprEngine::ProcessTemporaryDtor(const CFGTemporaryDtor D,
477a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith                                      ExplodedNode *Pred,
478a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith                                      ExplodedNodeSet &Dst) {}
479a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith
480a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smithvoid ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
4816ee7aa154e8bbb21a21254293410b944f78b0bfeChris Lattner                       ExplodedNodeSet &DstTop) {
48245b6b9d080ac56917337d73d8f1cd6374b27b05dChris Lattner  PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),
4834ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad                                S->getLocStart(),
484c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlsson                                "Error evaluating statement");
4856ddf4784a22b994b954ed74c6061d4603d474639Fariborz Jahanian  ExplodedNodeSet Dst;
486138d6a6890c171068ac60430431eaadb3fcef9abGabor Greif  StmtNodeBuilder Bldr(Pred, DstTop, *currentBuilderContext);
4876ddf4784a22b994b954ed74c6061d4603d474639Fariborz Jahanian
4886ddf4784a22b994b954ed74c6061d4603d474639Fariborz Jahanian  // Expressions to ignore.
4894ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad  if (const Expr *Ex = dyn_cast<Expr>(S))
490c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt    S = Ex->IgnoreParens();
491a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith
49251fe996231b1d7199f76e4005ff4c943d5deeecdAnders Carlsson  // FIXME: add metadata to the CFG so that we can disable
493a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith  //  this check when we KNOW that there is no block-level subexpression.
49451fe996231b1d7199f76e4005ff4c943d5deeecdAnders Carlsson  //  The motivation is that this check requires a hashtable lookup.
495b2f295c8050fb8c141bf2cf38eed0a56e99d0092Eli Friedman
496b2f295c8050fb8c141bf2cf38eed0a56e99d0092Eli Friedman  if (S != currentStmt && Pred->getLocationContext()->getCFG()->isBlkExpr(S))
4974ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad    return;
4981b78276a75a5a0f496a82429c1ff9604d622a76dAnders Carlsson
499e17a6436b429e4b18a5e157061fb13bbc677b3b0Abramo Bagnara  switch (S->getStmtClass()) {
5004ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad    // C++ and ARC stuff we don't support yet.
501e17a6436b429e4b18a5e157061fb13bbc677b3b0Abramo Bagnara    case Expr::ObjCIndirectCopyRestoreExprClass:
50282214a80c0163e01e4d8dec1426023c89277dbb4Chandler Carruth    case Stmt::CXXDependentScopeMemberExprClass:
50382214a80c0163e01e4d8dec1426023c89277dbb4Chandler Carruth    case Stmt::CXXPseudoDestructorExprClass:
50482214a80c0163e01e4d8dec1426023c89277dbb4Chandler Carruth    case Stmt::CXXTryStmtClass:
50582214a80c0163e01e4d8dec1426023c89277dbb4Chandler Carruth    case Stmt::CXXTypeidExprClass:
50682214a80c0163e01e4d8dec1426023c89277dbb4Chandler Carruth    case Stmt::CXXUuidofExprClass:
50782214a80c0163e01e4d8dec1426023c89277dbb4Chandler Carruth    case Stmt::CXXUnresolvedConstructExprClass:
50882214a80c0163e01e4d8dec1426023c89277dbb4Chandler Carruth    case Stmt::DependentScopeDeclRefExprClass:
50982214a80c0163e01e4d8dec1426023c89277dbb4Chandler Carruth    case Stmt::UnaryTypeTraitExprClass:
51082214a80c0163e01e4d8dec1426023c89277dbb4Chandler Carruth    case Stmt::BinaryTypeTraitExprClass:
51182214a80c0163e01e4d8dec1426023c89277dbb4Chandler Carruth    case Stmt::TypeTraitExprClass:
51282214a80c0163e01e4d8dec1426023c89277dbb4Chandler Carruth    case Stmt::ArrayTypeTraitExprClass:
51382214a80c0163e01e4d8dec1426023c89277dbb4Chandler Carruth    case Stmt::ExpressionTraitExprClass:
51482214a80c0163e01e4d8dec1426023c89277dbb4Chandler Carruth    case Stmt::UnresolvedLookupExprClass:
51582214a80c0163e01e4d8dec1426023c89277dbb4Chandler Carruth    case Stmt::UnresolvedMemberExprClass:
51682214a80c0163e01e4d8dec1426023c89277dbb4Chandler Carruth    case Stmt::CXXNoexceptExprClass:
51782214a80c0163e01e4d8dec1426023c89277dbb4Chandler Carruth    case Stmt::PackExpansionExprClass:
518ce94049b69f75b44c18584fe79cd238978b6b0d5Douglas Gregor    case Stmt::SubstNonTypeTemplateParmPackExprClass:
519ce94049b69f75b44c18584fe79cd238978b6b0d5Douglas Gregor    case Stmt::SEHTryStmtClass:
520ce94049b69f75b44c18584fe79cd238978b6b0d5Douglas Gregor    case Stmt::SEHExceptStmtClass:
521ce94049b69f75b44c18584fe79cd238978b6b0d5Douglas Gregor    case Stmt::LambdaExprClass:
522ce94049b69f75b44c18584fe79cd238978b6b0d5Douglas Gregor    case Stmt::SEHFinallyStmtClass: {
523c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt      const ExplodedNode *node = Bldr.generateNode(S, Pred, Pred->getState(),
524ce94049b69f75b44c18584fe79cd238978b6b0d5Douglas Gregor                                                   /* sink */ true);
525ce94049b69f75b44c18584fe79cd238978b6b0d5Douglas Gregor      Engine.addAbortedBlock(node, currentBuilderContext->getBlock());
526ce94049b69f75b44c18584fe79cd238978b6b0d5Douglas Gregor      break;
527c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt    }
528ce94049b69f75b44c18584fe79cd238978b6b0d5Douglas Gregor
529ce94049b69f75b44c18584fe79cd238978b6b0d5Douglas Gregor    // We don't handle default arguments either yet, but we can fake it
530ce94049b69f75b44c18584fe79cd238978b6b0d5Douglas Gregor    // for now by just skipping them.
531ce94049b69f75b44c18584fe79cd238978b6b0d5Douglas Gregor    case Stmt::SubstNonTypeTemplateParmExprClass:
532c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt    case Stmt::CXXDefaultArgExprClass:
53382214a80c0163e01e4d8dec1426023c89277dbb4Chandler Carruth      break;
53482214a80c0163e01e4d8dec1426023c89277dbb4Chandler Carruth
53582214a80c0163e01e4d8dec1426023c89277dbb4Chandler Carruth    case Stmt::ParenExprClass:
53682214a80c0163e01e4d8dec1426023c89277dbb4Chandler Carruth      llvm_unreachable("ParenExprs already handled.");
53782214a80c0163e01e4d8dec1426023c89277dbb4Chandler Carruth    case Stmt::GenericSelectionExprClass:
53882214a80c0163e01e4d8dec1426023c89277dbb4Chandler Carruth      llvm_unreachable("GenericSelectionExprs already handled.");
539efa9b3877ef298bcb792600ac33521827e1f7fafAnders Carlsson    // Cases that should never be evaluated simply because they shouldn't
54044baa8abba2a1552b6b50bf750a8750ab9da9f76Fariborz Jahanian    // appear in the CFG.
5411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    case Stmt::BreakStmtClass:
542102e390bcb5a1fb1a8fdbc8505e6dfd905374bbdFariborz Jahanian    case Stmt::CaseStmtClass:
5431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    case Stmt::CompoundStmtClass:
54411ab79030938209f50691acae0ddb65e72a58ca9Argyrios Kyrtzidis    case Stmt::ContinueStmtClass:
54511ab79030938209f50691acae0ddb65e72a58ca9Argyrios Kyrtzidis    case Stmt::CXXForRangeStmtClass:
54611ab79030938209f50691acae0ddb65e72a58ca9Argyrios Kyrtzidis    case Stmt::DefaultStmtClass:
547864c041e118155c2b1ce0ba36942a3da5a4a055eJohn McCall    case Stmt::DoStmtClass:
548864c041e118155c2b1ce0ba36942a3da5a4a055eJohn McCall    case Stmt::ForStmtClass:
549864c041e118155c2b1ce0ba36942a3da5a4a055eJohn McCall    case Stmt::GotoStmtClass:
550864c041e118155c2b1ce0ba36942a3da5a4a055eJohn McCall    case Stmt::IfStmtClass:
551864c041e118155c2b1ce0ba36942a3da5a4a055eJohn McCall    case Stmt::IndirectGotoStmtClass:
552369e51fa400aeb5835bb9af4634ea516c11429a7Sebastian Redl    case Stmt::LabelStmtClass:
553369e51fa400aeb5835bb9af4634ea516c11429a7Sebastian Redl    case Stmt::AttributedStmtClass:
554369e51fa400aeb5835bb9af4634ea516c11429a7Sebastian Redl    case Stmt::NoStmtClass:
555369e51fa400aeb5835bb9af4634ea516c11429a7Sebastian Redl    case Stmt::NullStmtClass:
556369e51fa400aeb5835bb9af4634ea516c11429a7Sebastian Redl    case Stmt::SwitchStmtClass:
557369e51fa400aeb5835bb9af4634ea516c11429a7Sebastian Redl    case Stmt::WhileStmtClass:
558369e51fa400aeb5835bb9af4634ea516c11429a7Sebastian Redl    case Expr::MSDependentExistsStmtClass:
559369e51fa400aeb5835bb9af4634ea516c11429a7Sebastian Redl      llvm_unreachable("Stmt should not be in analyzer evaluation loop");
560369e51fa400aeb5835bb9af4634ea516c11429a7Sebastian Redl
561369e51fa400aeb5835bb9af4634ea516c11429a7Sebastian Redl    case Stmt::ObjCSubscriptRefExprClass:
56291a5755ad73c5dc1dfb167e448fdd74e75a6df56John McCall    case Stmt::ObjCPropertyRefExprClass:
56391a5755ad73c5dc1dfb167e448fdd74e75a6df56John McCall      llvm_unreachable("These are handled by PseudoObjectExpr");
56491a5755ad73c5dc1dfb167e448fdd74e75a6df56John McCall
56591a5755ad73c5dc1dfb167e448fdd74e75a6df56John McCall    case Stmt::GNUNullExprClass: {
5667e5e5f4cc36fe50f46ad76dca7a266434c94f475John McCall      // GNU __null is a pointer-width integer, not an actual pointer.
5677e5e5f4cc36fe50f46ad76dca7a266434c94f475John McCall      ProgramStateRef state = Pred->getState();
5687e5e5f4cc36fe50f46ad76dca7a266434c94f475John McCall      state = state->BindExpr(S, Pred->getLocationContext(),
5697e5e5f4cc36fe50f46ad76dca7a266434c94f475John McCall                              svalBuilder.makeIntValWithPtrWidth(0, false));
5704e99a5fc3b203397a91136c6e695e405fb8fc606Ted Kremenek      Bldr.generateNode(S, Pred, state);
5711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      break;
5724e99a5fc3b203397a91136c6e695e405fb8fc606Ted Kremenek    }
5734e99a5fc3b203397a91136c6e695e405fb8fc606Ted Kremenek
5742b334bb3126a67895813e49e6228dad4aec0b4d6Chris Lattner    case Stmt::ObjCAtSynchronizedStmtClass:
57556f349400c5932a196509c0480ff6f99a9a0b48fChris Lattner      Bldr.takeNodes(Pred);
57656f349400c5932a196509c0480ff6f99a9a0b48fChris Lattner      VisitObjCAtSynchronizedStmt(cast<ObjCAtSynchronizedStmt>(S), Pred, Dst);
57727c8dc06f65d7abcf6a7e7f64a7960c9a150ca01Douglas Gregor      Bldr.addNodes(Dst);
57856f349400c5932a196509c0480ff6f99a9a0b48fChris Lattner      break;
5791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5802fc46bf1a9bc31d50f82de37c70ea257d3cded27John McCall    case Stmt::ExprWithCleanupsClass:
5812fc46bf1a9bc31d50f82de37c70ea257d3cded27John McCall      // Handled due to fully linearised CFG.
5822fc46bf1a9bc31d50f82de37c70ea257d3cded27John McCall      break;
5832fc46bf1a9bc31d50f82de37c70ea257d3cded27John McCall
5842f072b442879b8bba8c5dea11d7c61bedb1924aeHans Wennborg    // Cases not handled yet; but will handle some day.
5852f072b442879b8bba8c5dea11d7c61bedb1924aeHans Wennborg    case Stmt::DesignatedInitExprClass:
5862f072b442879b8bba8c5dea11d7c61bedb1924aeHans Wennborg    case Stmt::ExtVectorElementExprClass:
5872f072b442879b8bba8c5dea11d7c61bedb1924aeHans Wennborg    case Stmt::ImaginaryLiteralClass:
5882f072b442879b8bba8c5dea11d7c61bedb1924aeHans Wennborg    case Stmt::ObjCAtCatchStmtClass:
5892f072b442879b8bba8c5dea11d7c61bedb1924aeHans Wennborg    case Stmt::ObjCAtFinallyStmtClass:
5902f072b442879b8bba8c5dea11d7c61bedb1924aeHans Wennborg    case Stmt::ObjCAtTryStmtClass:
5912f072b442879b8bba8c5dea11d7c61bedb1924aeHans Wennborg    case Stmt::ObjCAutoreleasePoolStmtClass:
5924d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek    case Stmt::ObjCEncodeExprClass:
5934d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek    case Stmt::ObjCIsaExprClass:
5944d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek    case Stmt::ObjCProtocolExprClass:
595f6a1648197562e0b133440d612d9af297d0a86ccJohn McCall    case Stmt::ObjCSelectorExprClass:
596f6a1648197562e0b133440d612d9af297d0a86ccJohn McCall    case Stmt::ParenListExprClass:
597f6a1648197562e0b133440d612d9af297d0a86ccJohn McCall    case Stmt::PredefinedExprClass:
598f6a1648197562e0b133440d612d9af297d0a86ccJohn McCall    case Stmt::ShuffleVectorExprClass:
599f6a1648197562e0b133440d612d9af297d0a86ccJohn McCall    case Stmt::VAArgExprClass:
600f6a1648197562e0b133440d612d9af297d0a86ccJohn McCall    case Stmt::CUDAKernelCallExprClass:
601f6a1648197562e0b133440d612d9af297d0a86ccJohn McCall    case Stmt::OpaqueValueExprClass:
602f6a1648197562e0b133440d612d9af297d0a86ccJohn McCall    case Stmt::AsTypeExprClass:
6034d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek    case Stmt::AtomicExprClass:
604ecdd84147c0765caa999ddc22dde25b42712bb4dChris Lattner      // Fall through.
605ecdd84147c0765caa999ddc22dde25b42712bb4dChris Lattner
606ecdd84147c0765caa999ddc22dde25b42712bb4dChris Lattner    // Currently all handling of 'throw' just falls to the CFG.  We
607ecdd84147c0765caa999ddc22dde25b42712bb4dChris Lattner    // can consider doing more if necessary.
6081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    case Stmt::CXXThrowExprClass:
6096eef519fc8a97bb7ca6066f23d35e10f06b2c1b5Douglas Gregor      // Fall through.
6106eef519fc8a97bb7ca6066f23d35e10f06b2c1b5Douglas Gregor
6116eef519fc8a97bb7ca6066f23d35e10f06b2c1b5Douglas Gregor    // Cases we intentionally don't evaluate, since they don't need
612c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt    // to be explicitly evaluated.
6136eef519fc8a97bb7ca6066f23d35e10f06b2c1b5Douglas Gregor    case Stmt::AddrLabelExprClass:
6146eef519fc8a97bb7ca6066f23d35e10f06b2c1b5Douglas Gregor    case Stmt::IntegerLiteralClass:
6156eef519fc8a97bb7ca6066f23d35e10f06b2c1b5Douglas Gregor    case Stmt::CharacterLiteralClass:
6166eef519fc8a97bb7ca6066f23d35e10f06b2c1b5Douglas Gregor    case Stmt::ImplicitValueInitExprClass:
617c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt    case Stmt::CXXScalarValueInitExprClass:
618558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall    case Stmt::CXXBoolLiteralExprClass:
619558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall    case Stmt::ObjCBoolLiteralExprClass:
620558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall    case Stmt::FloatingLiteralClass:
6212f59979a7cc7929f53c9984423b0abeb83113442Douglas Gregor    case Stmt::SizeOfPackExprClass:
62275e85048e73fcde2ce9d8a48dfdb1220e132eb59Douglas Gregor    case Stmt::StringLiteralClass:
62375e85048e73fcde2ce9d8a48dfdb1220e132eb59Douglas Gregor    case Stmt::ObjCStringLiteralClass:
62491a5755ad73c5dc1dfb167e448fdd74e75a6df56John McCall    case Stmt::CXXBindTemporaryExprClass:
62591a5755ad73c5dc1dfb167e448fdd74e75a6df56John McCall    case Stmt::CXXNullPtrLiteralExprClass: {
62691a5755ad73c5dc1dfb167e448fdd74e75a6df56John McCall      Bldr.takeNodes(Pred);
62791a5755ad73c5dc1dfb167e448fdd74e75a6df56John McCall      ExplodedNodeSet preVisit;
6282b334bb3126a67895813e49e6228dad4aec0b4d6Chris Lattner      getCheckerManager().runCheckersForPreStmt(preVisit, Pred, S, *this);
6294e99a5fc3b203397a91136c6e695e405fb8fc606Ted Kremenek      getCheckerManager().runCheckersForPostStmt(Dst, preVisit, S, *this);
6304e99a5fc3b203397a91136c6e695e405fb8fc606Ted Kremenek      Bldr.addNodes(Dst);
63156f349400c5932a196509c0480ff6f99a9a0b48fChris Lattner      break;
63256f349400c5932a196509c0480ff6f99a9a0b48fChris Lattner    }
63356f349400c5932a196509c0480ff6f99a9a0b48fChris Lattner
634ecdd84147c0765caa999ddc22dde25b42712bb4dChris Lattner    case Expr::ObjCArrayLiteralClass:
635ecdd84147c0765caa999ddc22dde25b42712bb4dChris Lattner    case Expr::ObjCDictionaryLiteralClass:
636ecdd84147c0765caa999ddc22dde25b42712bb4dChris Lattner      // FIXME: explicitly model with a region and the actual contents
6371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      // of the container.  For now, conjure a symbol.
638898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor    case Expr::ObjCBoxedExprClass: {
639898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor      Bldr.takeNodes(Pred);
640898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor
6411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      ExplodedNodeSet preVisit;
6425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      getCheckerManager().runCheckersForPreStmt(preVisit, Pred, S, *this);
6431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
6445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      ExplodedNodeSet Tmp;
6455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      StmtNodeBuilder Bldr2(preVisit, Tmp, *currentBuilderContext);
6465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      const Expr *Ex = cast<Expr>(S);
6481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      QualType resultType = Ex->getType();
6495549976193e34417d4474a5f4a514268ef6666c7Ted Kremenek
6505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      for (ExplodedNodeSet::iterator it = preVisit.begin(), et = preVisit.end();
6515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer           it != et; ++it) {
6525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer        ExplodedNode *N = *it;
65356ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall        const LocationContext *LCtx = N->getLocationContext();
65456ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall        SVal result =
65556ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall          svalBuilder.getConjuredSymbolVal(0, Ex, LCtx, resultType,
65656ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall                                 currentBuilderContext->getCurrentBlockCount());
65756ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall        ProgramStateRef state = N->getState()->BindExpr(Ex, LCtx, result);
65856ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall        Bldr2.generateNode(S, N, state);
65956ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall      }
66056ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall
66156ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall      getCheckerManager().runCheckersForPostStmt(Dst, Tmp, S, *this);
66256ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall      Bldr.addNodes(Dst);
66356ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall      break;
66456ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall    }
66556ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall
66656ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall    case Stmt::ArraySubscriptExprClass:
667561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor      Bldr.takeNodes(Pred);
668561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor      VisitLvalArraySubscriptExpr(cast<ArraySubscriptExpr>(S), Pred, Dst);
669561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor      Bldr.addNodes(Dst);
67056ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall      break;
67156ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall
67256ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall    case Stmt::AsmStmtClass:
67356ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall      Bldr.takeNodes(Pred);
67456ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall      VisitAsmStmt(cast<AsmStmt>(S), Pred, Dst);
67556ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall      Bldr.addNodes(Dst);
67656ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall      break;
67756ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall
67856ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall    case Stmt::MSAsmStmtClass:
67956ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall      Bldr.takeNodes(Pred);
68056ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall      VisitMSAsmStmt(cast<MSAsmStmt>(S), Pred, Dst);
68156ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall      Bldr.addNodes(Dst);
68256ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall      break;
68356ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall
68456ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall    case Stmt::BlockExprClass:
68556ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall      Bldr.takeNodes(Pred);
68656ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall      VisitBlockExpr(cast<BlockExpr>(S), Pred, Dst);
68756ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall      Bldr.addNodes(Dst);
68856ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall      break;
68956ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall
69056ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall    case Stmt::BinaryOperatorClass: {
69156ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall      const BinaryOperator* B = cast<BinaryOperator>(S);
69256ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall      if (B->isLogicalOp()) {
69356ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall        Bldr.takeNodes(Pred);
69456ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall        VisitLogicalExpr(B, Pred, Dst);
69556ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall        Bldr.addNodes(Dst);
69656ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall        break;
69756ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall      }
69856ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall      else if (B->getOpcode() == BO_Comma) {
69956ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall        ProgramStateRef state = Pred->getState();
70056ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall        Bldr.generateNode(B, Pred,
70156ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall                          state->BindExpr(B, Pred->getLocationContext(),
70256ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall                                          state->getSVal(B->getRHS(),
70356ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall                                                  Pred->getLocationContext())));
70456ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall        break;
70556ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall      }
70656ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall
70756ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall      Bldr.takeNodes(Pred);
70856ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall
70956ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall      if (AMgr.shouldEagerlyAssume() &&
71056ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall          (B->isRelationalOp() || B->isEqualityOp())) {
71156ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall        ExplodedNodeSet Tmp;
712cb66cff8fdf641f57f85dedb515a5f3240e3a9bbChandler Carruth        VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Tmp);
713cb66cff8fdf641f57f85dedb515a5f3240e3a9bbChandler Carruth        evalEagerlyAssume(Dst, Tmp, cast<Expr>(S));
714cb66cff8fdf641f57f85dedb515a5f3240e3a9bbChandler Carruth      }
715cb66cff8fdf641f57f85dedb515a5f3240e3a9bbChandler Carruth      else
716cb66cff8fdf641f57f85dedb515a5f3240e3a9bbChandler Carruth        VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Dst);
717cb66cff8fdf641f57f85dedb515a5f3240e3a9bbChandler Carruth
718cb66cff8fdf641f57f85dedb515a5f3240e3a9bbChandler Carruth      Bldr.addNodes(Dst);
719cb66cff8fdf641f57f85dedb515a5f3240e3a9bbChandler Carruth      break;
720cb66cff8fdf641f57f85dedb515a5f3240e3a9bbChandler Carruth    }
721cb66cff8fdf641f57f85dedb515a5f3240e3a9bbChandler Carruth
722cb66cff8fdf641f57f85dedb515a5f3240e3a9bbChandler Carruth    case Stmt::CallExprClass:
723cb66cff8fdf641f57f85dedb515a5f3240e3a9bbChandler Carruth    case Stmt::CXXOperatorCallExprClass:
724cb66cff8fdf641f57f85dedb515a5f3240e3a9bbChandler Carruth    case Stmt::CXXMemberCallExprClass:
7253aa8140bde5b9bedf13e46ec0a668daa54814196Chandler Carruth    case Stmt::UserDefinedLiteralClass: {
7263aa8140bde5b9bedf13e46ec0a668daa54814196Chandler Carruth      Bldr.takeNodes(Pred);
7273aa8140bde5b9bedf13e46ec0a668daa54814196Chandler Carruth      VisitCallExpr(cast<CallExpr>(S), Pred, Dst);
7283aa8140bde5b9bedf13e46ec0a668daa54814196Chandler Carruth      Bldr.addNodes(Dst);
729cb66cff8fdf641f57f85dedb515a5f3240e3a9bbChandler Carruth      break;
730cb66cff8fdf641f57f85dedb515a5f3240e3a9bbChandler Carruth    }
731cb66cff8fdf641f57f85dedb515a5f3240e3a9bbChandler Carruth
7325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    case Stmt::CXXCatchStmtClass: {
733cb66cff8fdf641f57f85dedb515a5f3240e3a9bbChandler Carruth      Bldr.takeNodes(Pred);
734cb66cff8fdf641f57f85dedb515a5f3240e3a9bbChandler Carruth      VisitCXXCatchStmt(cast<CXXCatchStmt>(S), Pred, Dst);
7352577743c5650c646fb705df01403707e94f2df04Abramo Bagnara      Bldr.addNodes(Dst);
736cb66cff8fdf641f57f85dedb515a5f3240e3a9bbChandler Carruth      break;
7375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    }
7389e922b1663ecb95dc7eee03002fd66ed18fb3192Argyrios Kyrtzidis
739cb66cff8fdf641f57f85dedb515a5f3240e3a9bbChandler Carruth    case Stmt::CXXTemporaryObjectExprClass:
740cb66cff8fdf641f57f85dedb515a5f3240e3a9bbChandler Carruth    case Stmt::CXXConstructExprClass: {
7412577743c5650c646fb705df01403707e94f2df04Abramo Bagnara      Bldr.takeNodes(Pred);
7422577743c5650c646fb705df01403707e94f2df04Abramo Bagnara      VisitCXXConstructExpr(cast<CXXConstructExpr>(S), Pred, Dst);
7436857c3e12c86fd0271eb46baab5b18756a94f4cbChandler Carruth      Bldr.addNodes(Dst);
7446857c3e12c86fd0271eb46baab5b18756a94f4cbChandler Carruth      break;
7457e740bd36772aae16b5cc5e605998ccc5eaf26dbChandler Carruth    }
7466857c3e12c86fd0271eb46baab5b18756a94f4cbChandler Carruth
747a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor    case Stmt::CXXNewExprClass: {
748cb66cff8fdf641f57f85dedb515a5f3240e3a9bbChandler Carruth      Bldr.takeNodes(Pred);
7496857c3e12c86fd0271eb46baab5b18756a94f4cbChandler Carruth      const CXXNewExpr *NE = cast<CXXNewExpr>(S);
7506857c3e12c86fd0271eb46baab5b18756a94f4cbChandler Carruth      VisitCXXNewExpr(NE, Pred, Dst);
7516857c3e12c86fd0271eb46baab5b18756a94f4cbChandler Carruth      Bldr.addNodes(Dst);
752a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor      break;
753096832c5ed5b9106fa177ebc148489760c3bc496John McCall    }
7543aa8140bde5b9bedf13e46ec0a668daa54814196Chandler Carruth
7553aa8140bde5b9bedf13e46ec0a668daa54814196Chandler Carruth    case Stmt::CXXDeleteExprClass: {
7563aa8140bde5b9bedf13e46ec0a668daa54814196Chandler Carruth      Bldr.takeNodes(Pred);
7573aa8140bde5b9bedf13e46ec0a668daa54814196Chandler Carruth      const CXXDeleteExpr *CDE = cast<CXXDeleteExpr>(S);
7583aa8140bde5b9bedf13e46ec0a668daa54814196Chandler Carruth      VisitCXXDeleteExpr(CDE, Pred, Dst);
7593aa8140bde5b9bedf13e46ec0a668daa54814196Chandler Carruth      Bldr.addNodes(Dst);
7603aa8140bde5b9bedf13e46ec0a668daa54814196Chandler Carruth      break;
7613aa8140bde5b9bedf13e46ec0a668daa54814196Chandler Carruth    }
7623aa8140bde5b9bedf13e46ec0a668daa54814196Chandler Carruth      // FIXME: ChooseExpr is really a constant.  We need to fix
7633aa8140bde5b9bedf13e46ec0a668daa54814196Chandler Carruth      //        the CFG do not model them as explicit control-flow.
7643aa8140bde5b9bedf13e46ec0a668daa54814196Chandler Carruth
7653aa8140bde5b9bedf13e46ec0a668daa54814196Chandler Carruth    case Stmt::ChooseExprClass: { // __builtin_choose_expr
7663aa8140bde5b9bedf13e46ec0a668daa54814196Chandler Carruth      Bldr.takeNodes(Pred);
7673aa8140bde5b9bedf13e46ec0a668daa54814196Chandler Carruth      const ChooseExpr *C = cast<ChooseExpr>(S);
7683aa8140bde5b9bedf13e46ec0a668daa54814196Chandler Carruth      VisitGuardedExpr(C, C->getLHS(), C->getRHS(), Pred, Dst);
7693aa8140bde5b9bedf13e46ec0a668daa54814196Chandler Carruth      Bldr.addNodes(Dst);
7703aa8140bde5b9bedf13e46ec0a668daa54814196Chandler Carruth      break;
7713aa8140bde5b9bedf13e46ec0a668daa54814196Chandler Carruth    }
7723aa8140bde5b9bedf13e46ec0a668daa54814196Chandler Carruth
7737e740bd36772aae16b5cc5e605998ccc5eaf26dbChandler Carruth    case Stmt::CompoundAssignOperatorClass:
7742577743c5650c646fb705df01403707e94f2df04Abramo Bagnara      Bldr.takeNodes(Pred);
7753aa8140bde5b9bedf13e46ec0a668daa54814196Chandler Carruth      VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Dst);
7762577743c5650c646fb705df01403707e94f2df04Abramo Bagnara      Bldr.addNodes(Dst);
777f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall      break;
7782577743c5650c646fb705df01403707e94f2df04Abramo Bagnara
779663e380d7b2de2bbf20e886e05371195bea9adc4Argyrios Kyrtzidis    case Stmt::CompoundLiteralExprClass:
780663e380d7b2de2bbf20e886e05371195bea9adc4Argyrios Kyrtzidis      Bldr.takeNodes(Pred);
781663e380d7b2de2bbf20e886e05371195bea9adc4Argyrios Kyrtzidis      VisitCompoundLiteralExpr(cast<CompoundLiteralExpr>(S), Pred, Dst);
7827e740bd36772aae16b5cc5e605998ccc5eaf26dbChandler Carruth      Bldr.addNodes(Dst);
7830da76df9218d7c27b471b0a4d83a5b29fe24e5b4Douglas Gregor      break;
7840da76df9218d7c27b471b0a4d83a5b29fe24e5b4Douglas Gregor
7850da76df9218d7c27b471b0a4d83a5b29fe24e5b4Douglas Gregor    case Stmt::BinaryConditionalOperatorClass:
7869e922b1663ecb95dc7eee03002fd66ed18fb3192Argyrios Kyrtzidis    case Stmt::ConditionalOperatorClass: { // '?' operator
7875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      Bldr.takeNodes(Pred);
7885b8968cc599eb6100bb73ae87be9d6cd2577ac9eDouglas Gregor      const AbstractConditionalOperator *C
7895b8968cc599eb6100bb73ae87be9d6cd2577ac9eDouglas Gregor        = cast<AbstractConditionalOperator>(S);
790561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor      VisitGuardedExpr(C, C->getTrueExpr(), C->getFalseExpr(), Pred, Dst);
7915b8968cc599eb6100bb73ae87be9d6cd2577ac9eDouglas Gregor      Bldr.addNodes(Dst);
792cb66cff8fdf641f57f85dedb515a5f3240e3a9bbChandler Carruth      break;
793cb66cff8fdf641f57f85dedb515a5f3240e3a9bbChandler Carruth    }
7943aa8140bde5b9bedf13e46ec0a668daa54814196Chandler Carruth
7957cc58b4c927fca539d43eaa58e00dca95946eb7cAbramo Bagnara    case Stmt::CXXThisExprClass:
7960da76df9218d7c27b471b0a4d83a5b29fe24e5b4Douglas Gregor      Bldr.takeNodes(Pred);
7970da76df9218d7c27b471b0a4d83a5b29fe24e5b4Douglas Gregor      VisitCXXThisExpr(cast<CXXThisExpr>(S), Pred, Dst);
7981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      Bldr.addNodes(Dst);
799a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor      break;
80040d96a69c0e1e8c10f92d450c305a7aae696ca9cDouglas Gregor
801dbd872f273a8dbf22e089b3def6c09f0a460965dJohn McCall    case Stmt::DeclRefExprClass: {
802a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor      Bldr.takeNodes(Pred);
803f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall      const DeclRefExpr *DE = cast<DeclRefExpr>(S);
8043aa8140bde5b9bedf13e46ec0a668daa54814196Chandler Carruth      VisitCommonDeclRefExpr(DE, DE->getDecl(), Pred, Dst);
8050da76df9218d7c27b471b0a4d83a5b29fe24e5b4Douglas Gregor      Bldr.addNodes(Dst);
806663e380d7b2de2bbf20e886e05371195bea9adc4Argyrios Kyrtzidis      break;
8072577743c5650c646fb705df01403707e94f2df04Abramo Bagnara    }
80840d96a69c0e1e8c10f92d450c305a7aae696ca9cDouglas Gregor
8092577743c5650c646fb705df01403707e94f2df04Abramo Bagnara    case Stmt::DeclStmtClass:
8102577743c5650c646fb705df01403707e94f2df04Abramo Bagnara      Bldr.takeNodes(Pred);
811f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall      VisitDeclStmt(cast<DeclStmt>(S), Pred, Dst);
8123aa8140bde5b9bedf13e46ec0a668daa54814196Chandler Carruth      Bldr.addNodes(Dst);
8132577743c5650c646fb705df01403707e94f2df04Abramo Bagnara      break;
8142577743c5650c646fb705df01403707e94f2df04Abramo Bagnara
815663e380d7b2de2bbf20e886e05371195bea9adc4Argyrios Kyrtzidis    case Stmt::ImplicitCastExprClass:
816663e380d7b2de2bbf20e886e05371195bea9adc4Argyrios Kyrtzidis    case Stmt::CStyleCastExprClass:
8173aa8140bde5b9bedf13e46ec0a668daa54814196Chandler Carruth    case Stmt::CXXStaticCastExprClass:
8183aa8140bde5b9bedf13e46ec0a668daa54814196Chandler Carruth    case Stmt::CXXDynamicCastExprClass:
819def0354384d9c4431f7b58b664b59896d4623028Douglas Gregor    case Stmt::CXXReinterpretCastExprClass:
820def0354384d9c4431f7b58b664b59896d4623028Douglas Gregor    case Stmt::CXXConstCastExprClass:
8217e740bd36772aae16b5cc5e605998ccc5eaf26dbChandler Carruth    case Stmt::CXXFunctionalCastExprClass:
822cb66cff8fdf641f57f85dedb515a5f3240e3a9bbChandler Carruth    case Stmt::ObjCBridgedCastExprClass: {
823cb66cff8fdf641f57f85dedb515a5f3240e3a9bbChandler Carruth      Bldr.takeNodes(Pred);
824cb66cff8fdf641f57f85dedb515a5f3240e3a9bbChandler Carruth      const CastExpr *C = cast<CastExpr>(S);
825904eed3f6148758d39a2d3c88f3133274460d645Douglas Gregor      // Handle the previsit checks.
8262577743c5650c646fb705df01403707e94f2df04Abramo Bagnara      ExplodedNodeSet dstPrevisit;
8272577743c5650c646fb705df01403707e94f2df04Abramo Bagnara      getCheckerManager().runCheckersForPreStmt(dstPrevisit, Pred, C, *this);
8282577743c5650c646fb705df01403707e94f2df04Abramo Bagnara
8292577743c5650c646fb705df01403707e94f2df04Abramo Bagnara      // Handle the expression itself.
8309e922b1663ecb95dc7eee03002fd66ed18fb3192Argyrios Kyrtzidis      ExplodedNodeSet dstExpr;
8310b7489194f9f89fac39d57211c1e7953ae50251fDouglas Gregor      for (ExplodedNodeSet::iterator i = dstPrevisit.begin(),
83263c00d7f35fa060c0a446c9df3a4402d9c7757feJohn McCall                                     e = dstPrevisit.end(); i != e ; ++i) {
8331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        VisitCast(C, C->getSubExpr(), *i, dstExpr);
834a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor      }
835a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor
836cb66cff8fdf641f57f85dedb515a5f3240e3a9bbChandler Carruth      // Handle the postvisit checks.
8377e740bd36772aae16b5cc5e605998ccc5eaf26dbChandler Carruth      getCheckerManager().runCheckersForPostStmt(Dst, dstExpr, C, *this);
8387e740bd36772aae16b5cc5e605998ccc5eaf26dbChandler Carruth      Bldr.addNodes(Dst);
839a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor      break;
840a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor    }
841a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor
842a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor    case Expr::MaterializeTemporaryExprClass: {
8437e740bd36772aae16b5cc5e605998ccc5eaf26dbChandler Carruth      Bldr.takeNodes(Pred);
8446857c3e12c86fd0271eb46baab5b18756a94f4cbChandler Carruth      const MaterializeTemporaryExpr *Materialize
845a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor                                            = cast<MaterializeTemporaryExpr>(S);
84640d96a69c0e1e8c10f92d450c305a7aae696ca9cDouglas Gregor      if (Materialize->getType()->isRecordType())
8477e740bd36772aae16b5cc5e605998ccc5eaf26dbChandler Carruth        Dst.Add(Pred);
84840d96a69c0e1e8c10f92d450c305a7aae696ca9cDouglas Gregor      else
84940d96a69c0e1e8c10f92d450c305a7aae696ca9cDouglas Gregor        CreateCXXTemporaryObject(Materialize, Pred, Dst);
85040d96a69c0e1e8c10f92d450c305a7aae696ca9cDouglas Gregor      Bldr.addNodes(Dst);
85140d96a69c0e1e8c10f92d450c305a7aae696ca9cDouglas Gregor      break;
8527e740bd36772aae16b5cc5e605998ccc5eaf26dbChandler Carruth    }
8536857c3e12c86fd0271eb46baab5b18756a94f4cbChandler Carruth
85440d96a69c0e1e8c10f92d450c305a7aae696ca9cDouglas Gregor    case Stmt::InitListExprClass:
85540d96a69c0e1e8c10f92d450c305a7aae696ca9cDouglas Gregor      Bldr.takeNodes(Pred);
8563aa8140bde5b9bedf13e46ec0a668daa54814196Chandler Carruth      VisitInitListExpr(cast<InitListExpr>(S), Pred, Dst);
8573aa8140bde5b9bedf13e46ec0a668daa54814196Chandler Carruth      Bldr.addNodes(Dst);
8583aa8140bde5b9bedf13e46ec0a668daa54814196Chandler Carruth      break;
8593aa8140bde5b9bedf13e46ec0a668daa54814196Chandler Carruth
8603aa8140bde5b9bedf13e46ec0a668daa54814196Chandler Carruth    case Stmt::MemberExprClass:
8613aa8140bde5b9bedf13e46ec0a668daa54814196Chandler Carruth      Bldr.takeNodes(Pred);
8623aa8140bde5b9bedf13e46ec0a668daa54814196Chandler Carruth      VisitMemberExpr(cast<MemberExpr>(S), Pred, Dst);
8633aa8140bde5b9bedf13e46ec0a668daa54814196Chandler Carruth      Bldr.addNodes(Dst);
8643aa8140bde5b9bedf13e46ec0a668daa54814196Chandler Carruth      break;
8653aa8140bde5b9bedf13e46ec0a668daa54814196Chandler Carruth
8663aa8140bde5b9bedf13e46ec0a668daa54814196Chandler Carruth    case Stmt::ObjCIvarRefExprClass:
8673aa8140bde5b9bedf13e46ec0a668daa54814196Chandler Carruth      Bldr.takeNodes(Pred);
8683aa8140bde5b9bedf13e46ec0a668daa54814196Chandler Carruth      VisitLvalObjCIvarRefExpr(cast<ObjCIvarRefExpr>(S), Pred, Dst);
8693aa8140bde5b9bedf13e46ec0a668daa54814196Chandler Carruth      Bldr.addNodes(Dst);
8703aa8140bde5b9bedf13e46ec0a668daa54814196Chandler Carruth      break;
8717e740bd36772aae16b5cc5e605998ccc5eaf26dbChandler Carruth
8727e740bd36772aae16b5cc5e605998ccc5eaf26dbChandler Carruth    case Stmt::ObjCForCollectionStmtClass:
873096832c5ed5b9106fa177ebc148489760c3bc496John McCall      Bldr.takeNodes(Pred);
874cb66cff8fdf641f57f85dedb515a5f3240e3a9bbChandler Carruth      VisitObjCForCollectionStmt(cast<ObjCForCollectionStmt>(S), Pred, Dst);
875096832c5ed5b9106fa177ebc148489760c3bc496John McCall      Bldr.addNodes(Dst);
8767e740bd36772aae16b5cc5e605998ccc5eaf26dbChandler Carruth      break;
877096832c5ed5b9106fa177ebc148489760c3bc496John McCall
878096832c5ed5b9106fa177ebc148489760c3bc496John McCall    case Stmt::ObjCMessageExprClass: {
879b0c3e0909bb04af0bfb82ad01ab6909649d68ccaArgyrios Kyrtzidis      Bldr.takeNodes(Pred);
880096832c5ed5b9106fa177ebc148489760c3bc496John McCall      VisitObjCMessage(ObjCMethodCall(cast<ObjCMessageExpr>(S),
8813aa8140bde5b9bedf13e46ec0a668daa54814196Chandler Carruth                                      Pred->getState(),
882b0c3e0909bb04af0bfb82ad01ab6909649d68ccaArgyrios Kyrtzidis                                      Pred->getLocationContext()),
8833aa8140bde5b9bedf13e46ec0a668daa54814196Chandler Carruth                       Pred, Dst);
8843aa8140bde5b9bedf13e46ec0a668daa54814196Chandler Carruth      Bldr.addNodes(Dst);
8853aa8140bde5b9bedf13e46ec0a668daa54814196Chandler Carruth      break;
886b0c3e0909bb04af0bfb82ad01ab6909649d68ccaArgyrios Kyrtzidis    }
8873aa8140bde5b9bedf13e46ec0a668daa54814196Chandler Carruth
8887e740bd36772aae16b5cc5e605998ccc5eaf26dbChandler Carruth    case Stmt::ObjCAtThrowStmtClass: {
889b0c3e0909bb04af0bfb82ad01ab6909649d68ccaArgyrios Kyrtzidis      // FIXME: This is not complete.  We basically treat @throw as
890096832c5ed5b9106fa177ebc148489760c3bc496John McCall      // an abort.
8917e740bd36772aae16b5cc5e605998ccc5eaf26dbChandler Carruth      Bldr.generateNode(S, Pred, Pred->getState());
892096832c5ed5b9106fa177ebc148489760c3bc496John McCall      break;
893096832c5ed5b9106fa177ebc148489760c3bc496John McCall    }
894b0c3e0909bb04af0bfb82ad01ab6909649d68ccaArgyrios Kyrtzidis
895096832c5ed5b9106fa177ebc148489760c3bc496John McCall    case Stmt::ReturnStmtClass:
896a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor      Bldr.takeNodes(Pred);
897d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall      VisitReturnStmt(cast<ReturnStmt>(S), Pred, Dst);
898096832c5ed5b9106fa177ebc148489760c3bc496John McCall      Bldr.addNodes(Dst);
899096832c5ed5b9106fa177ebc148489760c3bc496John McCall      break;
900096832c5ed5b9106fa177ebc148489760c3bc496John McCall
901b0c3e0909bb04af0bfb82ad01ab6909649d68ccaArgyrios Kyrtzidis    case Stmt::OffsetOfExprClass:
902096832c5ed5b9106fa177ebc148489760c3bc496John McCall      Bldr.takeNodes(Pred);
903096832c5ed5b9106fa177ebc148489760c3bc496John McCall      VisitOffsetOfExpr(cast<OffsetOfExpr>(S), Pred, Dst);
904096832c5ed5b9106fa177ebc148489760c3bc496John McCall      Bldr.addNodes(Dst);
9057e740bd36772aae16b5cc5e605998ccc5eaf26dbChandler Carruth      break;
906d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall
907d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall    case Stmt::UnaryExprOrTypeTraitExprClass:
908d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall      Bldr.takeNodes(Pred);
909096832c5ed5b9106fa177ebc148489760c3bc496John McCall      VisitUnaryExprOrTypeTraitExpr(cast<UnaryExprOrTypeTraitExpr>(S),
910096832c5ed5b9106fa177ebc148489760c3bc496John McCall                                    Pred, Dst);
911d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall      Bldr.addNodes(Dst);
9127e740bd36772aae16b5cc5e605998ccc5eaf26dbChandler Carruth      break;
913a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor
914a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor    case Stmt::StmtExprClass: {
915a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor      const StmtExpr *SE = cast<StmtExpr>(S);
916096832c5ed5b9106fa177ebc148489760c3bc496John McCall
917a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor      if (SE->getSubStmt()->body_empty()) {
9187e740bd36772aae16b5cc5e605998ccc5eaf26dbChandler Carruth        // Empty statement expression.
919096832c5ed5b9106fa177ebc148489760c3bc496John McCall        assert(SE->getType() == getContext().VoidTy
920a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor               && "Empty statement expression must have void type.");
9217e740bd36772aae16b5cc5e605998ccc5eaf26dbChandler Carruth        break;
922a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor      }
923a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor
924833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall      if (Expr *LastExpr = dyn_cast<Expr>(*SE->getSubStmt()->body_rbegin())) {
925096832c5ed5b9106fa177ebc148489760c3bc496John McCall        ProgramStateRef state = Pred->getState();
926a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor        Bldr.generateNode(SE, Pred,
9277e740bd36772aae16b5cc5e605998ccc5eaf26dbChandler Carruth                          state->BindExpr(SE, Pred->getLocationContext(),
928096832c5ed5b9106fa177ebc148489760c3bc496John McCall                                          state->getSVal(LastExpr,
929a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor                                                  Pred->getLocationContext())));
9307e740bd36772aae16b5cc5e605998ccc5eaf26dbChandler Carruth      }
931a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor      break;
932a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor    }
933a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor
934096832c5ed5b9106fa177ebc148489760c3bc496John McCall    case Stmt::UnaryOperatorClass: {
935a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor      Bldr.takeNodes(Pred);
9367e740bd36772aae16b5cc5e605998ccc5eaf26dbChandler Carruth      const UnaryOperator *U = cast<UnaryOperator>(S);
937096832c5ed5b9106fa177ebc148489760c3bc496John McCall      if (AMgr.shouldEagerlyAssume() && (U->getOpcode() == UO_LNot)) {
938a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor        ExplodedNodeSet Tmp;
9397e740bd36772aae16b5cc5e605998ccc5eaf26dbChandler Carruth        VisitUnaryOperator(U, Pred, Tmp);
940a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor        evalEagerlyAssume(Dst, Tmp, U);
941a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor      }
942a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor      else
943096832c5ed5b9106fa177ebc148489760c3bc496John McCall        VisitUnaryOperator(U, Pred, Dst);
944a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor      Bldr.addNodes(Dst);
9457e740bd36772aae16b5cc5e605998ccc5eaf26dbChandler Carruth      break;
946096832c5ed5b9106fa177ebc148489760c3bc496John McCall    }
947a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor
9487e740bd36772aae16b5cc5e605998ccc5eaf26dbChandler Carruth    case Stmt::PseudoObjectExprClass: {
9497cc58b4c927fca539d43eaa58e00dca95946eb7cAbramo Bagnara      Bldr.takeNodes(Pred);
9507cc58b4c927fca539d43eaa58e00dca95946eb7cAbramo Bagnara      ProgramStateRef state = Pred->getState();
9517cc58b4c927fca539d43eaa58e00dca95946eb7cAbramo Bagnara      const PseudoObjectExpr *PE = cast<PseudoObjectExpr>(S);
9527cc58b4c927fca539d43eaa58e00dca95946eb7cAbramo Bagnara      if (const Expr *Result = PE->getResultExpr()) {
9537cc58b4c927fca539d43eaa58e00dca95946eb7cAbramo Bagnara        SVal V = state->getSVal(Result, Pred->getLocationContext());
9547cc58b4c927fca539d43eaa58e00dca95946eb7cAbramo Bagnara        Bldr.generateNode(S, Pred,
9557cc58b4c927fca539d43eaa58e00dca95946eb7cAbramo Bagnara                          state->BindExpr(S, Pred->getLocationContext(), V));
9567cc58b4c927fca539d43eaa58e00dca95946eb7cAbramo Bagnara      }
9577cc58b4c927fca539d43eaa58e00dca95946eb7cAbramo Bagnara      else
9587cc58b4c927fca539d43eaa58e00dca95946eb7cAbramo Bagnara        Bldr.generateNode(S, Pred,
9597cc58b4c927fca539d43eaa58e00dca95946eb7cAbramo Bagnara                          state->BindExpr(S, Pred->getLocationContext(),
9607cc58b4c927fca539d43eaa58e00dca95946eb7cAbramo Bagnara                                                   UnknownVal()));
9611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
96299e9b4d172f6877e6ba5ebe75bb8238721f5e01cDouglas Gregor      Bldr.addNodes(Dst);
9635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      break;
9645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    }
9651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  }
96677ed8e4edf6ed78c53fb20ec3210aff2a59c9d87Ted Kremenek}
96763c00d7f35fa060c0a446c9df3a4402d9c7757feJohn McCall
9687e740bd36772aae16b5cc5e605998ccc5eaf26dbChandler Carruthbool ExprEngine::replayWithoutInlining(ExplodedNode *N,
96960adf4acf40b72227740bf966fb87eebddff3f37Sebastian Redl                                       const LocationContext *CalleeLC) {
9703397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl  const StackFrameContext *CalleeSF = CalleeLC->getCurrentStackFrame();
9715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  const StackFrameContext *CallerSF = CalleeSF->getParent()->getCurrentStackFrame();
9725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  assert(CalleeSF && CallerSF);
973d9f6910f4ef37c0e8eeee2a01287d9572c3176efChris Lattner  ExplodedNode *BeforeProcessingCall = 0;
974d9f6910f4ef37c0e8eeee2a01287d9572c3176efChris Lattner  const Stmt *CE = CalleeSF->getCallSite();
975227426661be33ff3e21f2b6b9f97971da2da044fAnders Carlsson
976227426661be33ff3e21f2b6b9f97971da2da044fAnders Carlsson  // Find the first node before we started processing the call expression.
977227426661be33ff3e21f2b6b9f97971da2da044fAnders Carlsson  while (N) {
978227426661be33ff3e21f2b6b9f97971da2da044fAnders Carlsson    ProgramPoint L = N->getLocation();
979848fa64143fbe5ae62a601ad61277f741e54dfabAnders Carlsson    BeforeProcessingCall = N;
980848fa64143fbe5ae62a601ad61277f741e54dfabAnders Carlsson    N = N->pred_empty() ? NULL : *(N->pred_begin());
981848fa64143fbe5ae62a601ad61277f741e54dfabAnders Carlsson
982848fa64143fbe5ae62a601ad61277f741e54dfabAnders Carlsson    // Skip the nodes corresponding to the inlined code.
983227426661be33ff3e21f2b6b9f97971da2da044fAnders Carlsson    if (L.getLocationContext()->getCurrentStackFrame() != CallerSF)
9841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      continue;
985227426661be33ff3e21f2b6b9f97971da2da044fAnders Carlsson    // We reached the caller. Find the node right before we started
986227426661be33ff3e21f2b6b9f97971da2da044fAnders Carlsson    // processing the call.
987227426661be33ff3e21f2b6b9f97971da2da044fAnders Carlsson    if (L.isPurgeKind())
988227426661be33ff3e21f2b6b9f97971da2da044fAnders Carlsson      continue;
9891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    if (isa<PreImplicitCall>(&L))
990f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall      continue;
991bebbe0d9b7568ce43a464286bee49429489ef483Douglas Gregor    if (isa<CallEnter>(&L))
992561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor      continue;
993bebbe0d9b7568ce43a464286bee49429489ef483Douglas Gregor    if (const StmtPoint *SP = dyn_cast<StmtPoint>(&L))
994f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall      if (SP->getStmt() == CE)
9951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        continue;
99617fc223395d51be582fc666bb6ea21bd1dff26dcDouglas Gregor    break;
9971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  }
99817fc223395d51be582fc666bb6ea21bd1dff26dcDouglas Gregor
99917fc223395d51be582fc666bb6ea21bd1dff26dcDouglas Gregor  if (!BeforeProcessingCall)
1000227426661be33ff3e21f2b6b9f97971da2da044fAnders Carlsson    return false;
100117fc223395d51be582fc666bb6ea21bd1dff26dcDouglas Gregor
100217fc223395d51be582fc666bb6ea21bd1dff26dcDouglas Gregor  // TODO: Clean up the unneeded nodes.
100317fc223395d51be582fc666bb6ea21bd1dff26dcDouglas Gregor
100417fc223395d51be582fc666bb6ea21bd1dff26dcDouglas Gregor  // Build an Epsilon node from which we will restart the analyzes.
100517fc223395d51be582fc666bb6ea21bd1dff26dcDouglas Gregor  // Note that CE is permitted to be NULL!
1006848fa64143fbe5ae62a601ad61277f741e54dfabAnders Carlsson  ProgramPoint NewNodeLoc =
10073a082d81006e7a2e01a6e431a22e21c78490ff8fAnders Carlsson               EpsilonPoint(BeforeProcessingCall->getLocationContext(), CE);
100863c00d7f35fa060c0a446c9df3a4402d9c7757feJohn McCall  // Add the special flag to GDM to signal retrying with no inlining.
1009227426661be33ff3e21f2b6b9f97971da2da044fAnders Carlsson  // Note, changing the state ensures that we are not going to cache out.
10101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  ProgramStateRef NewNodeState = BeforeProcessingCall->getState();
10111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  NewNodeState = NewNodeState->set<ReplayWithoutInlining>((void*)CE);
1012227426661be33ff3e21f2b6b9f97971da2da044fAnders Carlsson
1013d9f6910f4ef37c0e8eeee2a01287d9572c3176efChris Lattner  // Make the new node a successor of BeforeProcessingCall.
10141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  bool IsNew = false;
101577ed8e4edf6ed78c53fb20ec3210aff2a59c9d87Ted Kremenek  ExplodedNode *NewNode = G.getNode(NewNodeLoc, NewNodeState, false, &IsNew);
101663c00d7f35fa060c0a446c9df3a4402d9c7757feJohn McCall  // We cached out at this point. Caching out is common due to us backtracking
1017227426661be33ff3e21f2b6b9f97971da2da044fAnders Carlsson  // from the inlined function, which might spawn several paths.
1018227426661be33ff3e21f2b6b9f97971da2da044fAnders Carlsson  if (!IsNew)
10199996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis    return true;
10209996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis
10219996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis  NewNode->addPredecessor(BeforeProcessingCall, G);
10229996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis
10239996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis  // Add the new node to the work list.
10249996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis  Engine.enqueueStmtNode(NewNode, CalleeSF->getCallSiteBlock(),
10259996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis                                  CalleeSF->getIndex());
10269996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis  NumTimesRetriedWithoutInlining++;
10279996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis  return true;
10289996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis}
10299996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis
10309996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis/// Block entrance.  (Update counters).
10319996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidisvoid ExprEngine::processCFGBlockEntrance(const BlockEdge &L,
10329996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis                                         NodeBuilderWithSinks &nodeBuilder) {
10339996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis
10349996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis  // FIXME: Refactor this into a checker.
10359996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis  ExplodedNode *pred = nodeBuilder.getContext().getPred();
10369996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis
10379996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis  if (nodeBuilder.getContext().getCurrentBlockCount() >= AMgr.getMaxVisit()) {
10389996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis    static SimpleProgramPointTag tag("ExprEngine : Block count exceeded");
10399996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis    const ExplodedNode *Sink =
10409996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis                   nodeBuilder.generateNode(pred->getState(), pred, &tag, true);
10419996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis
10429996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis    // Check if we stopped at the top level function or not.
10439996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis    // Root node should have the location context of the top most function.
10449996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis    const LocationContext *CalleeLC = pred->getLocation().getLocationContext();
10459996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis    const LocationContext *CalleeSF = CalleeLC->getCurrentStackFrame();
10469996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis    const LocationContext *RootLC =
10479996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis                        (*G.roots_begin())->getLocation().getLocationContext();
10489996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis    if (RootLC->getCurrentStackFrame() != CalleeSF) {
10499996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis      Engine.FunctionSummaries->markReachedMaxBlockCount(CalleeSF->getDecl());
10509996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis
10519996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis      // Re-run the call evaluation without inlining it, by storing the
10529996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis      // no-inlining policy in the state and enqueuing the new work item on
10539996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis      // the list. Replay should almost never fail. Use the stats to catch it
10549996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis      // if it does.
10559996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis      if ((!AMgr.NoRetryExhausted && replayWithoutInlining(pred, CalleeLC)))
10569996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis        return;
10579996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis      NumMaxBlockCountReachedInInlined++;
10589996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis    } else
10599996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis      NumMaxBlockCountReached++;
10609996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis
10619996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis    // Make sink nodes as exhausted(for stats) only if retry failed.
10629996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis    Engine.blocksExhausted.push_back(std::make_pair(L, Sink));
10639996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis  }
10649996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis}
10659996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis
10665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
10679996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis// Branch processing.
10685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
10699996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis
10709996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis/// RecoverCastedSymbol - A helper function for ProcessBranch that is used
10719996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis/// to try to recover some path-sensitivity for casts of symbolic
10729996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis/// integers that promote their values (which are currently not tracked well).
10739996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis/// This function returns the SVal bound to Condition->IgnoreCasts if all the
10745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//  cast(s) did was sign-extend the original value.
10751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstatic SVal RecoverCastedSymbol(ProgramStateManager& StateMgr,
10765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                                ProgramStateRef state,
10779996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis                                const Stmt *Condition,
10789996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis                                const LocationContext *LCtx,
1079bebbe0d9b7568ce43a464286bee49429489ef483Douglas Gregor                                ASTContext &Ctx) {
1080561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor
1081f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall  const Expr *Ex = dyn_cast<Expr>(Condition);
10825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (!Ex)
10831dd986dff9ddfbec687975700770bb377988e9edRichard Trieu    return UnknownVal();
10841dd986dff9ddfbec687975700770bb377988e9edRichard Trieu
10859996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis  uint64_t bits = 0;
10865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool bitsInit = false;
1087a135fb43eb94524a6529768596a4533eed9aa70dAnders Carlsson
10881dd986dff9ddfbec687975700770bb377988e9edRichard Trieu  while (const CastExpr *CE = dyn_cast<CastExpr>(Ex)) {
10891dd986dff9ddfbec687975700770bb377988e9edRichard Trieu    QualType T = CE->getType();
10901dd986dff9ddfbec687975700770bb377988e9edRichard Trieu
10911dd986dff9ddfbec687975700770bb377988e9edRichard Trieu    if (!T->isIntegerType())
10929996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis      return UnknownVal();
10939996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis
10941dd986dff9ddfbec687975700770bb377988e9edRichard Trieu    uint64_t newBits = Ctx.getTypeSize(T);
10959996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis    if (!bitsInit || newBits < bits) {
10960b7489194f9f89fac39d57211c1e7953ae50251fDouglas Gregor      bitsInit = true;
10979996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis      bits = newBits;
109863c00d7f35fa060c0a446c9df3a4402d9c7757feJohn McCall    }
10995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1100313a81dd820c9b2c0203bdcd974c781a81e4f0cfDouglas Gregor    Ex = CE->getSubExpr();
1101313a81dd820c9b2c0203bdcd974c781a81e4f0cfDouglas Gregor  }
1102313a81dd820c9b2c0203bdcd974c781a81e4f0cfDouglas Gregor
11039996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis  // We reached a non-cast.  Is it a symbolic value?
11040b7489194f9f89fac39d57211c1e7953ae50251fDouglas Gregor  QualType T = Ex->getType();
11050b7489194f9f89fac39d57211c1e7953ae50251fDouglas Gregor
11061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  if (!bitsInit || !T->isIntegerType() || Ctx.getTypeSize(T) > bits)
11071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return UnknownVal();
11085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
11095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  return state->getSVal(Ex, LCtx);
11101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump}
111177ed8e4edf6ed78c53fb20ec3210aff2a59c9d87Ted Kremenek
111263c00d7f35fa060c0a446c9df3a4402d9c7757feJohn McCallstatic const Stmt *ResolveCondition(const Stmt *Condition,
11135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                                    const CFGBlock *B) {
11145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (const Expr *Ex = dyn_cast<Expr>(Condition))
11155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Condition = Ex->IgnoreParens();
11165cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor
11175cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor  const BinaryOperator *BO = dyn_cast<BinaryOperator>(Condition);
11185cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor  if (!BO || !BO->isLogicalOp())
11195cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    return Condition;
11205cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor
11215cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor  // For logical operations, we still have the case where some branches
11225cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor  // use the traditional "merge" approach and others sink the branch
11235cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor  // directly into the basic blocks representing the logical operation.
11245cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor  // We need to distinguish between those two cases here.
11255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
11265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // The invariants are still shifting, but it is possible that the
11275cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor  // last element in a CFGBlock is not a CFGStmt.  Look for the last
11285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // CFGStmt as the value of the condition.
11295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  CFGBlock::const_reverse_iterator I = B->rbegin(), E = B->rend();
11305cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor  for (; I != E; ++I) {
11315cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    CFGElement Elem = *I;
1132bebbe0d9b7568ce43a464286bee49429489ef483Douglas Gregor    CFGStmt *CS = dyn_cast<CFGStmt>(&Elem);
1133561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor    if (!CS)
11345cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor      continue;
11355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    if (CS->getStmt() != Condition)
11360b7489194f9f89fac39d57211c1e7953ae50251fDouglas Gregor      break;
11370b7489194f9f89fac39d57211c1e7953ae50251fDouglas Gregor    return Condition;
11380b7489194f9f89fac39d57211c1e7953ae50251fDouglas Gregor  }
11390b7489194f9f89fac39d57211c1e7953ae50251fDouglas Gregor
1140018d8e0596dd57401eeddcf11ac84ff0a065fbbeChris Lattner  assert(I != E);
11415cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor
11421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  while (Condition) {
114363c00d7f35fa060c0a446c9df3a4402d9c7757feJohn McCall    BO = dyn_cast<BinaryOperator>(Condition);
11441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    if (!BO || !BO->isLogicalOp())
11455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      return Condition;
11465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Condition = BO->getRHS()->IgnoreParens();
11470b7489194f9f89fac39d57211c1e7953ae50251fDouglas Gregor  }
11485cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor  llvm_unreachable("could not resolve condition");
11490b7489194f9f89fac39d57211c1e7953ae50251fDouglas Gregor}
11500b7489194f9f89fac39d57211c1e7953ae50251fDouglas Gregor
11511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpvoid ExprEngine::processBranch(const Stmt *Condition, const Stmt *Term,
11521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                               NodeBuilderContext& BldCtx,
11535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                               ExplodedNode *Pred,
11545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                               ExplodedNodeSet &Dst,
115577ed8e4edf6ed78c53fb20ec3210aff2a59c9d87Ted Kremenek                               const CFGBlock *DstT,
115677ed8e4edf6ed78c53fb20ec3210aff2a59c9d87Ted Kremenek                               const CFGBlock *DstF) {
115763c00d7f35fa060c0a446c9df3a4402d9c7757feJohn McCall  currentBuilderContext = &BldCtx;
11585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
11595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Check for NULL conditions; e.g. "for(;;)"
11605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (!Condition) {
11619996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis    BranchNodeBuilder NullCondBldr(Pred, Dst, BldCtx, DstT, DstF);
1162720c4ec57b6110873cd533ad434853a27e7c3f4aTed Kremenek    NullCondBldr.markInfeasible(false);
11635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    NullCondBldr.generateNode(Pred->getState(), true, Pred);
11649996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis    return;
11659996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis  }
1166720c4ec57b6110873cd533ad434853a27e7c3f4aTed Kremenek
1167bebbe0d9b7568ce43a464286bee49429489ef483Douglas Gregor
1168561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor  // Resolve the condition in the precense of nested '||' and '&&'.
11699996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis  if (const Expr *Ex = dyn_cast<Expr>(Condition))
11709996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis    Condition = Ex->IgnoreParens();
11719996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis
11725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  Condition = ResolveCondition(Condition, BldCtx.getBlock());
117317fc223395d51be582fc666bb6ea21bd1dff26dcDouglas Gregor  PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),
11741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                Condition->getLocStart(),
11759996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis                                "Error evaluating branch");
117617fc223395d51be582fc666bb6ea21bd1dff26dcDouglas Gregor
11779996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis  ExplodedNodeSet CheckersOutSet;
11789996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis  getCheckerManager().runCheckersForBranchCondition(Condition, CheckersOutSet,
11799996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis                                                    Pred, *this);
11809996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis  // We generated only sinks.
11819996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis  if (CheckersOutSet.empty())
11829996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis    return;
11839996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis
11849996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis  BranchNodeBuilder builder(CheckersOutSet, Dst, BldCtx, DstT, DstF);
11859996a7f06a3c5b4554692e7177930cf4e8ef09afArgyrios Kyrtzidis  for (NodeBuilder::iterator I = CheckersOutSet.begin(),
118617fc223395d51be582fc666bb6ea21bd1dff26dcDouglas Gregor                             E = CheckersOutSet.end(); E != I; ++I) {
1187720c4ec57b6110873cd533ad434853a27e7c3f4aTed Kremenek    ExplodedNode *PredI = *I;
118817fc223395d51be582fc666bb6ea21bd1dff26dcDouglas Gregor
1189c9bec4bfea9090a08dd83a7b213f0c8adf8d78ecChris Lattner    if (PredI->isSink())
1190da8249e57f3badecf925571881fe57243935c6c1Chris Lattner      continue;
1191da8249e57f3badecf925571881fe57243935c6c1Chris Lattner
1192da8249e57f3badecf925571881fe57243935c6c1Chris Lattner    ProgramStateRef PrevState = Pred->getState();
1193da8249e57f3badecf925571881fe57243935c6c1Chris Lattner    SVal X = PrevState->getSVal(Condition, Pred->getLocationContext());
11941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
119517fc223395d51be582fc666bb6ea21bd1dff26dcDouglas Gregor    if (X.isUnknownOrUndef()) {
119617fc223395d51be582fc666bb6ea21bd1dff26dcDouglas Gregor      // Give it a chance to recover from unknown.
119717fc223395d51be582fc666bb6ea21bd1dff26dcDouglas Gregor      if (const Expr *Ex = dyn_cast<Expr>(Condition)) {
119863c00d7f35fa060c0a446c9df3a4402d9c7757feJohn McCall        if (Ex->getType()->isIntegerType()) {
11995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer          // Try to recover some path-sensitivity.  Right now casts of symbolic
12001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump          // integers that promote their values are currently not tracked well.
12011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump          // If 'Condition' is such an expression, try and recover the
12025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer          // underlying value and use that instead.
12035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer          SVal recovered = RecoverCastedSymbol(getStateManager(),
12041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                               PrevState, Condition,
120577ed8e4edf6ed78c53fb20ec3210aff2a59c9d87Ted Kremenek                                               Pred->getLocationContext(),
120663c00d7f35fa060c0a446c9df3a4402d9c7757feJohn McCall                                               getContext());
12075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
12085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer          if (!recovered.isUnknown()) {
12095d66145eed1c319df5a69977cb8ff74f597ea544Chris Lattner            X = recovered;
12105d66145eed1c319df5a69977cb8ff74f597ea544Chris Lattner          }
12115d66145eed1c319df5a69977cb8ff74f597ea544Chris Lattner        }
12125d66145eed1c319df5a69977cb8ff74f597ea544Chris Lattner      }
12135d66145eed1c319df5a69977cb8ff74f597ea544Chris Lattner    }
12145d66145eed1c319df5a69977cb8ff74f597ea544Chris Lattner
12155549976193e34417d4474a5f4a514268ef6666c7Ted Kremenek    // If the condition is still unknown, give up.
12165d66145eed1c319df5a69977cb8ff74f597ea544Chris Lattner    if (X.isUnknownOrUndef()) {
12175d66145eed1c319df5a69977cb8ff74f597ea544Chris Lattner      builder.generateNode(PrevState, true, PredI);
1218bebbe0d9b7568ce43a464286bee49429489ef483Douglas Gregor      builder.generateNode(PrevState, false, PredI);
1219561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor      continue;
1220f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall    }
12211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1222cb2ca73c1d7e76cc1358ce51457d2d5837d84f9bDouglas Gregor    DefinedSVal V = cast<DefinedSVal>(X);
12231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1224cb2ca73c1d7e76cc1358ce51457d2d5837d84f9bDouglas Gregor    // Process the true branch.
1225cb2ca73c1d7e76cc1358ce51457d2d5837d84f9bDouglas Gregor    if (builder.isFeasible(true)) {
12265549976193e34417d4474a5f4a514268ef6666c7Ted Kremenek      if (ProgramStateRef state = PrevState->assume(V, true))
12275549976193e34417d4474a5f4a514268ef6666c7Ted Kremenek        builder.generateNode(state, true, PredI);
1228cb2ca73c1d7e76cc1358ce51457d2d5837d84f9bDouglas Gregor      else
1229cb2ca73c1d7e76cc1358ce51457d2d5837d84f9bDouglas Gregor        builder.markInfeasible(true);
123063c00d7f35fa060c0a446c9df3a4402d9c7757feJohn McCall    }
12311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
12321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    // Process the false branch.
12335d66145eed1c319df5a69977cb8ff74f597ea544Chris Lattner    if (builder.isFeasible(false)) {
12345d66145eed1c319df5a69977cb8ff74f597ea544Chris Lattner      if (ProgramStateRef state = PrevState->assume(V, false))
12351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        builder.generateNode(state, false, PredI);
12365d66145eed1c319df5a69977cb8ff74f597ea544Chris Lattner      else
123763c00d7f35fa060c0a446c9df3a4402d9c7757feJohn McCall        builder.markInfeasible(false);
12385d66145eed1c319df5a69977cb8ff74f597ea544Chris Lattner    }
12395d66145eed1c319df5a69977cb8ff74f597ea544Chris Lattner  }
1240e6a82b2c29ad05534841e5f8fd033fb17b6f61e2Ted Kremenek  currentBuilderContext = 0;
1241e6a82b2c29ad05534841e5f8fd033fb17b6f61e2Ted Kremenek}
1242e6a82b2c29ad05534841e5f8fd033fb17b6f61e2Ted Kremenek
1243a7ad98ff0919d6a24ea7c46634ea29bea551c1a0Chris Lattner/// processIndirectGoto - Called by CoreEngine.  Used to generate successor
1244c4a09c189981b4561428e4b56fd250718e2717bbChris Lattner///  nodes by processing the 'effects' of a computed goto jump.
1245c4a09c189981b4561428e4b56fd250718e2717bbChris Lattnervoid ExprEngine::processIndirectGoto(IndirectGotoNodeBuilder &builder) {
1246690398188ea5b428f06aa13c7d4ce6eb741ad4f9Chris Lattner
1247690398188ea5b428f06aa13c7d4ce6eb741ad4f9Chris Lattner  ProgramStateRef state = builder.getState();
12488bea7c0ee44c71c817de7dc2be932b73bec90c9fChris Lattner  SVal V = state->getSVal(builder.getTarget(), builder.getLocationContext());
1249690398188ea5b428f06aa13c7d4ce6eb741ad4f9Chris Lattner
1250c4a09c189981b4561428e4b56fd250718e2717bbChris Lattner  // Three possibilities:
1251c4a09c189981b4561428e4b56fd250718e2717bbChris Lattner  //
1252c4a09c189981b4561428e4b56fd250718e2717bbChris Lattner  //   (1) We know the computed label.
1253c4a09c189981b4561428e4b56fd250718e2717bbChris Lattner  //   (2) The label is NULL (or some other constant), or Undefined.
1254c4a09c189981b4561428e4b56fd250718e2717bbChris Lattner  //   (3) We have no clue about the label.  Dispatch to all targets.
1255c4a09c189981b4561428e4b56fd250718e2717bbChris Lattner  //
12565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
12575cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor  typedef IndirectGotoNodeBuilder::iterator iterator;
12585cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor
12595cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor  if (isa<loc::GotoLabel>(V)) {
12605cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    const LabelDecl *L = cast<loc::GotoLabel>(V).getLabel();
12615cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor
12625cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    for (iterator I = builder.begin(), E = builder.end(); I != E; ++I) {
12635cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor      if (I.getLabel() == L) {
12645cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor        builder.generateNode(I, state);
12655cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor        return;
12665cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor      }
12673e2193ce5feb2feb092e5ae615e85148e06e9fd2Anders Carlsson    }
12683e2193ce5feb2feb092e5ae615e85148e06e9fd2Anders Carlsson
12695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    llvm_unreachable("No block with label.");
12705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
1271726e168dc09fb23f53c7b004f8e919421ee91806Chris Lattner
12725cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor  if (isa<loc::ConcreteInt>(V) || isa<UndefinedVal>(V)) {
12735cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    // Dispatch to the first target and mark it as a sink.
1274726e168dc09fb23f53c7b004f8e919421ee91806Chris Lattner    //ExplodedNode* N = builder.generateNode(builder.begin(), state, true);
12752085fd6cd22ec5c268175251db10d7c60caf7aaaChris Lattner    // FIXME: add checker visit.
1276f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall    //    UndefBranches.insert(N);
1277561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor    return;
1278561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor  }
12791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
12805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // This is really a catch-all.  We don't support symbolics yet.
12812085fd6cd22ec5c268175251db10d7c60caf7aaaChris Lattner  // FIXME: Implement dispatch for symbolic pointers.
12822085fd6cd22ec5c268175251db10d7c60caf7aaaChris Lattner
12835cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor  for (iterator I=builder.begin(), E=builder.end(); I != E; ++I)
128465aa6885818d4b4eea2e5a9d12085b2398148662Jay Foad    builder.generateNode(I, state);
1285a135fb43eb94524a6529768596a4533eed9aa70dAnders Carlsson}
12862085fd6cd22ec5c268175251db10d7c60caf7aaaChris Lattner
12872085fd6cd22ec5c268175251db10d7c60caf7aaaChris Lattner/// ProcessEndPath - Called by CoreEngine.  Used to generate end-of-path
12885cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor///  nodes when the control reaches the end of a function.
12895cee1195584fa8672253139c86e922daeda69b9eDouglas Gregorvoid ExprEngine::processEndOfFunction(NodeBuilderContext& BC) {
12905cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor  StateMgr.EndPath(BC.Pred->getState());
12915cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor  ExplodedNodeSet Dst;
12922085fd6cd22ec5c268175251db10d7c60caf7aaaChris Lattner  getCheckerManager().runCheckersForEndPath(BC, Dst, *this);
1293a135fb43eb94524a6529768596a4533eed9aa70dAnders Carlsson  Engine.enqueueEndOfFunction(Dst);
1294673ecd6a4a9f7c12fb6f76f84f654dbdcdc89e76Douglas Gregor}
1295673ecd6a4a9f7c12fb6f76f84f654dbdcdc89e76Douglas Gregor
1296673ecd6a4a9f7c12fb6f76f84f654dbdcdc89e76Douglas Gregor/// ProcessSwitch - Called by CoreEngine.  Used to generate successor
1297686775deca8b8685eb90801495880e3abdd844c2Chris Lattner///  nodes by processing the 'effects' of a switch statement.
1298686775deca8b8685eb90801495880e3abdd844c2Chris Lattnervoid ExprEngine::processSwitch(SwitchNodeBuilder& builder) {
1299b648023da23e8b227cdda57a241db4c6f368726bDaniel Dunbar  typedef SwitchNodeBuilder::iterator iterator;
13002f4eaef37476ae6891ede8ba215d0f6fd093629bBenjamin Kramer  ProgramStateRef state = builder.getState();
13015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  const Expr *CondE = builder.getCondition();
1302673ecd6a4a9f7c12fb6f76f84f654dbdcdc89e76Douglas Gregor  SVal  CondV_untested = state->getSVal(CondE, builder.getLocationContext());
1303673ecd6a4a9f7c12fb6f76f84f654dbdcdc89e76Douglas Gregor
1304686775deca8b8685eb90801495880e3abdd844c2Chris Lattner  if (CondV_untested.isUndef()) {
1305673ecd6a4a9f7c12fb6f76f84f654dbdcdc89e76Douglas Gregor    //ExplodedNode* N = builder.generateDefaultCaseNode(state, true);
13065cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    // FIXME: add checker
13075cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    //UndefBranches.insert(N);
13085cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor
13095cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    return;
13105cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor  }
13115cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor  DefinedOrUnknownSVal CondV = cast<DefinedOrUnknownSVal>(CondV_untested);
13123e2193ce5feb2feb092e5ae615e85148e06e9fd2Anders Carlsson
13135cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor  ProgramStateRef DefaultSt = state;
13148d4141f83d9de379547cf05bd75d4c6cf894b189Steve Naroff
1315686775deca8b8685eb90801495880e3abdd844c2Chris Lattner  iterator I = builder.begin(), EI = builder.end();
1316b648023da23e8b227cdda57a241db4c6f368726bDaniel Dunbar  bool defaultIsFeasible = I == EI;
1317b648023da23e8b227cdda57a241db4c6f368726bDaniel Dunbar
131833fdb738a6c125f4c788733897021b7c1a062b0cSteve Naroff  for ( ; I != EI; ++I) {
131933fdb738a6c125f4c788733897021b7c1a062b0cSteve Naroff    // Successor may be pruned out during CFG construction.
132033fdb738a6c125f4c788733897021b7c1a062b0cSteve Naroff    if (!I.getBlock())
1321726e168dc09fb23f53c7b004f8e919421ee91806Chris Lattner      continue;
1322726e168dc09fb23f53c7b004f8e919421ee91806Chris Lattner
1323726e168dc09fb23f53c7b004f8e919421ee91806Chris Lattner    const CaseStmt *Case = I.getCase();
13241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1325726e168dc09fb23f53c7b004f8e919421ee91806Chris Lattner    // Evaluate the LHS of the case value.
1326726e168dc09fb23f53c7b004f8e919421ee91806Chris Lattner    llvm::APSInt V1 = Case->getLHS()->EvaluateKnownConstInt(getContext());
1327726e168dc09fb23f53c7b004f8e919421ee91806Chris Lattner    assert(V1.getBitWidth() == getContext().getTypeSize(CondE->getType()));
1328726e168dc09fb23f53c7b004f8e919421ee91806Chris Lattner
13291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    // Get the RHS of the case, if it exists.
1330673ecd6a4a9f7c12fb6f76f84f654dbdcdc89e76Douglas Gregor    llvm::APSInt V2;
1331673ecd6a4a9f7c12fb6f76f84f654dbdcdc89e76Douglas Gregor    if (const Expr *E = Case->getRHS())
1332673ecd6a4a9f7c12fb6f76f84f654dbdcdc89e76Douglas Gregor      V2 = E->EvaluateKnownConstInt(getContext());
133308f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner    else
133408f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner      V2 = V1;
133508f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner
133608f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner    // FIXME: Eventually we should replace the logic below with a range
133708f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner    //  comparison, rather than concretize the values within the range.
133808f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner    //  This should be easy once we have "ranges" for NonLVals.
133908f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner
134008f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner    do {
134108f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner      nonloc::ConcreteInt CaseVal(getBasicVals().getValue(V1));
134208f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner      DefinedOrUnknownSVal Res = svalBuilder.evalEQ(DefaultSt ? DefaultSt : state,
134308f92e3a5dead1f1ee656678a7f06e43279d6e50Chris Lattner                                               CondV, CaseVal);
1344673ecd6a4a9f7c12fb6f76f84f654dbdcdc89e76Douglas Gregor
1345b137299ce5bb6c36fbba651858600857fda4dd50Chris Lattner      // Now "assume" that the case matches.
1346b137299ce5bb6c36fbba651858600857fda4dd50Chris Lattner      if (ProgramStateRef stateNew = state->assume(Res, true)) {
1347b137299ce5bb6c36fbba651858600857fda4dd50Chris Lattner        builder.generateCaseStmtNode(I, stateNew);
13485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
134963c00d7f35fa060c0a446c9df3a4402d9c7757feJohn McCall        // If CondV evaluates to a constant, then we know that this
13501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        // is the *only* case that we can take, so stop evaluating the
13515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer        // others.
13521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        if (isa<nonloc::ConcreteInt>(CondV))
13531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump          return;
13545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      }
13555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
13561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      // Now "assume" that the case doesn't match.  Add this state
135777ed8e4edf6ed78c53fb20ec3210aff2a59c9d87Ted Kremenek      // to the default state (if it is feasible).
135863c00d7f35fa060c0a446c9df3a4402d9c7757feJohn McCall      if (DefaultSt) {
13595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer        if (ProgramStateRef stateNew = DefaultSt->assume(Res, false)) {
13605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer          defaultIsFeasible = true;
13615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer          DefaultSt = stateNew;
13625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer        }
13635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer        else {
13645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer          defaultIsFeasible = false;
13655549976193e34417d4474a5f4a514268ef6666c7Ted Kremenek          DefaultSt = NULL;
13665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer        }
13675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      }
1368898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor
1369f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall      // Concretize the next value in the range.
1370bebbe0d9b7568ce43a464286bee49429489ef483Douglas Gregor      if (V1 == V2)
1371561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor        break;
1372bebbe0d9b7568ce43a464286bee49429489ef483Douglas Gregor
1373898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor      ++V1;
13741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      assert (V1 <= V2);
1375c04db4feefa2b0dbbc6876cb4eeeee108aa6791dDouglas Gregor
13761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    } while (true);
1377c04db4feefa2b0dbbc6876cb4eeeee108aa6791dDouglas Gregor  }
1378c04db4feefa2b0dbbc6876cb4eeeee108aa6791dDouglas Gregor
13795549976193e34417d4474a5f4a514268ef6666c7Ted Kremenek  if (!defaultIsFeasible)
13805549976193e34417d4474a5f4a514268ef6666c7Ted Kremenek    return;
1381c04db4feefa2b0dbbc6876cb4eeeee108aa6791dDouglas Gregor
1382c04db4feefa2b0dbbc6876cb4eeeee108aa6791dDouglas Gregor  // If we have switch(enum value), the default branch is not
138363c00d7f35fa060c0a446c9df3a4402d9c7757feJohn McCall  // feasible if all of the enum constants not covered by 'case:' statements
13845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // are not feasible values for the switch condition.
1385313a81dd820c9b2c0203bdcd974c781a81e4f0cfDouglas Gregor  //
1386313a81dd820c9b2c0203bdcd974c781a81e4f0cfDouglas Gregor  // Note that this isn't as accurate as it could be.  Even if there isn't
1387c04db4feefa2b0dbbc6876cb4eeeee108aa6791dDouglas Gregor  // a case for a particular enum value as long as that enum value isn't
1388313a81dd820c9b2c0203bdcd974c781a81e4f0cfDouglas Gregor  // feasible then it shouldn't be considered for making 'default:' reachable.
1389313a81dd820c9b2c0203bdcd974c781a81e4f0cfDouglas Gregor  const SwitchStmt *SS = builder.getSwitch();
1390313a81dd820c9b2c0203bdcd974c781a81e4f0cfDouglas Gregor  const Expr *CondExpr = SS->getCond()->IgnoreParenImpCasts();
1391c04db4feefa2b0dbbc6876cb4eeeee108aa6791dDouglas Gregor  if (CondExpr->getType()->getAs<EnumType>()) {
1392313a81dd820c9b2c0203bdcd974c781a81e4f0cfDouglas Gregor    if (SS->isAllEnumCasesCovered())
13931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      return;
13941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  }
13955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
13965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  builder.generateDefaultCaseNode(DefaultSt);
13971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump}
139877ed8e4edf6ed78c53fb20ec3210aff2a59c9d87Ted Kremenek
139963c00d7f35fa060c0a446c9df3a4402d9c7757feJohn McCall//===----------------------------------------------------------------------===//
14005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// Transfer functions: Loads and stores.
14015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
14025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
14030518999d3adcc289997bd974dce90cc97f5c1c44Sebastian Redlvoid ExprEngine::VisitCommonDeclRefExpr(const Expr *Ex, const NamedDecl *D,
14040518999d3adcc289997bd974dce90cc97f5c1c44Sebastian Redl                                        ExplodedNode *Pred,
14055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                                        ExplodedNodeSet &Dst) {
1406dbb36971c68ea944ac4b1fbe2d97fe7cca3b20acChris Lattner  StmtNodeBuilder Bldr(Pred, Dst, *currentBuilderContext);
1407dbb36971c68ea944ac4b1fbe2d97fe7cca3b20acChris Lattner
1408dbb36971c68ea944ac4b1fbe2d97fe7cca3b20acChris Lattner  ProgramStateRef state = Pred->getState();
1409dbb36971c68ea944ac4b1fbe2d97fe7cca3b20acChris Lattner  const LocationContext *LCtx = Pred->getLocationContext();
1410dbb36971c68ea944ac4b1fbe2d97fe7cca3b20acChris Lattner
1411dbb36971c68ea944ac4b1fbe2d97fe7cca3b20acChris Lattner  if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
1412dbb36971c68ea944ac4b1fbe2d97fe7cca3b20acChris Lattner    assert(Ex->isGLValue());
14135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    SVal V = state->getLValue(VD, Pred->getLocationContext());
14145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
14155baba9d98364a3525d6afa15a04cdad82fd6dd30John McCall    // For references, the 'lvalue' is the pointer address stored in the
14165baba9d98364a3525d6afa15a04cdad82fd6dd30John McCall    // reference region.
14175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    if (VD->getType()->isReferenceType()) {
14180799c53fc2bb7acf937c8a8e165033dba1a5aba3John McCall      if (const MemRegion *R = V.getAsRegion())
14195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer        V = state->getSVal(R);
14200799c53fc2bb7acf937c8a8e165033dba1a5aba3John McCall      else
14211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        V = UnknownVal();
14225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    }
1423f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall
1424f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall    Bldr.generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V), false, 0,
1425f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall                      ProgramPoint::PostLValueKind);
1426de7e66256b1bdfcf6526994825a8c8fced52a31cEli Friedman    return;
1427bebbe0d9b7568ce43a464286bee49429489ef483Douglas Gregor  }
1428561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor  if (const EnumConstantDecl *ED = dyn_cast<EnumConstantDecl>(D)) {
1429561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor    assert(!Ex->isGLValue());
1430bebbe0d9b7568ce43a464286bee49429489ef483Douglas Gregor    SVal V = svalBuilder.makeIntVal(ED->getInitVal());
14310799c53fc2bb7acf937c8a8e165033dba1a5aba3John McCall    Bldr.generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V));
14325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return;
14330b0b77fa29c74c99a77548ed86ca8a04f7cf6b02Douglas Gregor  }
14341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
14352de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    SVal V = svalBuilder.getFunctionPointer(FD);
14360b0b77fa29c74c99a77548ed86ca8a04f7cf6b02Douglas Gregor    Bldr.generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V), false, 0,
14370799c53fc2bb7acf937c8a8e165033dba1a5aba3John McCall                      ProgramPoint::PostLValueKind);
14380b0b77fa29c74c99a77548ed86ca8a04f7cf6b02Douglas Gregor    return;
14390b0b77fa29c74c99a77548ed86ca8a04f7cf6b02Douglas Gregor  }
14405549976193e34417d4474a5f4a514268ef6666c7Ted Kremenek  if (isa<FieldDecl>(D)) {
14410b0b77fa29c74c99a77548ed86ca8a04f7cf6b02Douglas Gregor    // FIXME: Compute lvalue of fields.
14420b0b77fa29c74c99a77548ed86ca8a04f7cf6b02Douglas Gregor    Bldr.generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, UnknownVal()),
14435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer		      false, 0, ProgramPoint::PostLValueKind);
14445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return;
14450b0b77fa29c74c99a77548ed86ca8a04f7cf6b02Douglas Gregor  }
14460b0b77fa29c74c99a77548ed86ca8a04f7cf6b02Douglas Gregor
14475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  assert (false &&
14482085fd6cd22ec5c268175251db10d7c60caf7aaaChris Lattner          "ValueDecl support for this ValueDecl not implemented.");
14492de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall}
14502085fd6cd22ec5c268175251db10d7c60caf7aaaChris Lattner
14515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// VisitArraySubscriptExpr - Transfer function for array accesses
1452cc7bd10c0de9449b795bda3c5dcc6d83cc48436bZhanyong Wanvoid ExprEngine::VisitLvalArraySubscriptExpr(const ArraySubscriptExpr *A,
14532085fd6cd22ec5c268175251db10d7c60caf7aaaChris Lattner                                             ExplodedNode *Pred,
14542de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall                                             ExplodedNodeSet &Dst){
14552085fd6cd22ec5c268175251db10d7c60caf7aaaChris Lattner
14565a56ac30d04e8f0431a08980885662a47a6308aaTed Kremenek  const Expr *Base = A->getBase()->IgnoreParens();
14570799c53fc2bb7acf937c8a8e165033dba1a5aba3John McCall  const Expr *Idx  = A->getIdx()->IgnoreParens();
14580799c53fc2bb7acf937c8a8e165033dba1a5aba3John McCall
14592de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall
1460993cdca0fed7deb646e4654dfb2607227a497faaBenjamin Kramer  ExplodedNodeSet checkerPreStmt;
14612de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  getCheckerManager().runCheckersForPreStmt(checkerPreStmt, Pred, A, *this);
14622de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall
1463993cdca0fed7deb646e4654dfb2607227a497faaBenjamin Kramer  StmtNodeBuilder Bldr(checkerPreStmt, Dst, *currentBuilderContext);
14642de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall
14652de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall  for (ExplodedNodeSet::iterator it = checkerPreStmt.begin(),
14662de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall                                 ei = checkerPreStmt.end(); it != ei; ++it) {
14672de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall    const LocationContext *LCtx = (*it)->getLocationContext();
14680799c53fc2bb7acf937c8a8e165033dba1a5aba3John McCall    ProgramStateRef state = (*it)->getState();
14691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    SVal V = state->getLValue(A->getType(),
14705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                              state->getSVal(Idx, LCtx),
14715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                              state->getSVal(Base, LCtx));
14725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    assert(A->isGLValue());
14735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Bldr.generateNode(A, *it, state->BindExpr(A, LCtx, V),
1474bc736fceca6f0bca31d16003a7587857190408fbDouglas Gregor                      false, 0, ProgramPoint::PostLValueKind);
1475bc736fceca6f0bca31d16003a7587857190408fbDouglas Gregor  }
1476bc736fceca6f0bca31d16003a7587857190408fbDouglas Gregor}
1477bc736fceca6f0bca31d16003a7587857190408fbDouglas Gregor
1478bc736fceca6f0bca31d16003a7587857190408fbDouglas Gregor/// VisitMemberExpr - Transfer function for member expressions.
1479bc736fceca6f0bca31d16003a7587857190408fbDouglas Gregorvoid ExprEngine::VisitMemberExpr(const MemberExpr *M, ExplodedNode *Pred,
1480bc736fceca6f0bca31d16003a7587857190408fbDouglas Gregor                                 ExplodedNodeSet &TopDst) {
1481bc736fceca6f0bca31d16003a7587857190408fbDouglas Gregor
148263c00d7f35fa060c0a446c9df3a4402d9c7757feJohn McCall  StmtNodeBuilder Bldr(Pred, TopDst, *currentBuilderContext);
14835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ExplodedNodeSet Dst;
14845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  Decl *member = M->getMemberDecl();
14855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
14865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  if (VarDecl *VD = dyn_cast<VarDecl>(member)) {
14875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    assert(M->isGLValue());
148863c00d7f35fa060c0a446c9df3a4402d9c7757feJohn McCall    Bldr.takeNodes(Pred);
14891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    VisitCommonDeclRefExpr(M, VD, Pred, Dst);
14901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    Bldr.addNodes(Dst);
14911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return;
14925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
14935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
14941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  // Handle C++ method calls.
149577ed8e4edf6ed78c53fb20ec3210aff2a59c9d87Ted Kremenek  if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(member)) {
149663c00d7f35fa060c0a446c9df3a4402d9c7757feJohn McCall    Bldr.takeNodes(Pred);
14975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    SVal MDVal = svalBuilder.getFunctionPointer(MD);
14985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    ProgramStateRef state =
14998ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor      Pred->getState()->BindExpr(M, Pred->getLocationContext(), MDVal);
15008ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor    Bldr.generateNode(M, Pred, state);
15018ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor    return;
15028ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor  }
15038ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor
1504c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt
15058ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor  FieldDecl *field = dyn_cast<FieldDecl>(member);
15068ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor  if (!field) // FIXME: skipping member expressions for non-fields
15078ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor    return;
15088ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor
15098ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor  Expr *baseExpr = M->getBase()->IgnoreParens();
15108ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor  ProgramStateRef state = Pred->getState();
1511c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt  const LocationContext *LCtx = Pred->getLocationContext();
15128ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor  SVal baseExprVal = state->getSVal(baseExpr, Pred->getLocationContext());
15138ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor  if (isa<nonloc::LazyCompoundVal>(baseExprVal) ||
15148ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor      isa<nonloc::CompoundVal>(baseExprVal) ||
15158ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor      // FIXME: This can originate by conjuring a symbol for an unknown
15168ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor      // temporary struct object, see test/Analysis/fields.c:
15178ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor      // (p = getit()).x
15188ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor      isa<nonloc::SymbolVal>(baseExprVal)) {
15198ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor    Bldr.generateNode(M, Pred, state->BindExpr(M, LCtx, UnknownVal()));
1520cc8a5d5f90bbbbcb46f342117b851b7e07ec34f1Douglas Gregor    return;
15218ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor  }
1522cc8a5d5f90bbbbcb46f342117b851b7e07ec34f1Douglas Gregor
15238ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor  // FIXME: Should we insert some assumption logic in here to determine
1524cc8a5d5f90bbbbcb46f342117b851b7e07ec34f1Douglas Gregor  // if "Base" is a valid piece of memory?  Before we put this assumption
1525cc8a5d5f90bbbbcb46f342117b851b7e07ec34f1Douglas Gregor  // later when using FieldOffset lvals (which we no longer have).
1526cc8a5d5f90bbbbcb46f342117b851b7e07ec34f1Douglas Gregor
1527cc8a5d5f90bbbbcb46f342117b851b7e07ec34f1Douglas Gregor  // For all other cases, compute an lvalue.
1528cc8a5d5f90bbbbcb46f342117b851b7e07ec34f1Douglas Gregor  SVal L = state->getLValue(field, baseExprVal);
15298ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor  if (M->isGLValue())
15308ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor    Bldr.generateNode(M, Pred, state->BindExpr(M, LCtx, L), false, 0,
15318ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor                      ProgramPoint::PostLValueKind);
15328ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor  else {
1533c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt    Bldr.takeNodes(Pred);
15348ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor    evalLoad(Dst, M, M, Pred, state, L);
15358ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor    Bldr.addNodes(Dst);
1536c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt  }
15378ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor}
15388ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor
1539c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt/// evalBind - Handle the semantics of binding a value to a specific location.
15408ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor///  This method is used by evalStore and (soon) VisitDeclStmt, and others.
15418ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregorvoid ExprEngine::evalBind(ExplodedNodeSet &Dst, const Stmt *StoreE,
15428ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor                          ExplodedNode *Pred,
15438ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor                          SVal location, SVal Val, bool atDeclInit) {
1544c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt
1545cc8a5d5f90bbbbcb46f342117b851b7e07ec34f1Douglas Gregor  // Do a previsit of the bind.
15468ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor  ExplodedNodeSet CheckedSet;
1547c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt  getCheckerManager().runCheckersForBind(CheckedSet, Pred, location, Val,
15488ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor                                         StoreE, *this,
15498ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor                                         ProgramPoint::PostStmtKind);
1550c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt
15518ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor  ExplodedNodeSet TmpDst;
15528ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor  StmtNodeBuilder Bldr(CheckedSet, TmpDst, *currentBuilderContext);
1553c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt
15548ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor  const LocationContext *LC = Pred->getLocationContext();
1555c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt  for (ExplodedNodeSet::iterator I = CheckedSet.begin(), E = CheckedSet.end();
15568ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor       I!=E; ++I) {
1557c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt    ExplodedNode *PredI = *I;
15588ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor    ProgramStateRef state = PredI->getState();
1559c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt
15608ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor    if (atDeclInit) {
15618ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor      const VarRegion *VR =
15628ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor        cast<VarRegion>(cast<loc::MemRegionVal>(location).getRegion());
1563c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt
15648ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor      state = state->bindDecl(VR, Val);
1565cc8a5d5f90bbbbcb46f342117b851b7e07ec34f1Douglas Gregor    } else {
1566cc8a5d5f90bbbbcb46f342117b851b7e07ec34f1Douglas Gregor      state = state->bindLoc(location, Val);
1567cc8a5d5f90bbbbcb46f342117b851b7e07ec34f1Douglas Gregor    }
1568cc8a5d5f90bbbbcb46f342117b851b7e07ec34f1Douglas Gregor
1569c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt    const MemRegion *LocReg = 0;
15708ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor    if (loc::MemRegionVal *LocRegVal = dyn_cast<loc::MemRegionVal>(&location))
1571c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt      LocReg = LocRegVal->getRegion();
15728ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor
15738ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor    const ProgramPoint L = PostStore(StoreE, LC, LocReg, 0);
1574c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt    Bldr.generateNode(L, PredI, state, false);
15758ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor  }
15768ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor
15778ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor  Dst.insert(TmpDst);
15788ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor}
15798ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor
15808ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor/// evalStore - Handle the semantics of a store via an assignment.
15818ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor///  @param Dst The node set to store generated state nodes
15828ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor///  @param AssignE The assignment expression if the store happens in an
15838ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor///         assignment.
15848ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor///  @param LocationE The location expression that is stored to.
1585cc8a5d5f90bbbbcb46f342117b851b7e07ec34f1Douglas Gregor///  @param state The current simulation state
15868ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor///  @param location The location to store the value
1587c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt///  @param Val The value to be stored
15888ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregorvoid ExprEngine::evalStore(ExplodedNodeSet &Dst, const Expr *AssignE,
15898ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor                             const Expr *LocationE,
15908ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor                             ExplodedNode *Pred,
1591c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt                             ProgramStateRef state, SVal location, SVal Val,
1592cc8a5d5f90bbbbcb46f342117b851b7e07ec34f1Douglas Gregor                             const ProgramPointTag *tag) {
1593cc8a5d5f90bbbbcb46f342117b851b7e07ec34f1Douglas Gregor  // Proceed with the store.  We use AssignE as the anchor for the PostStore
1594cc8a5d5f90bbbbcb46f342117b851b7e07ec34f1Douglas Gregor  // ProgramPoint if it is non-NULL, and LocationE otherwise.
1595c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt  const Expr *StoreE = AssignE ? AssignE : LocationE;
1596cc8a5d5f90bbbbcb46f342117b851b7e07ec34f1Douglas Gregor
1597c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt  // Evaluate the location (checks for bad dereferences).
15988ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor  ExplodedNodeSet Tmp;
15998ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor  evalLocation(Tmp, AssignE, LocationE, Pred, state, location, tag, false);
16008ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor
16018ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor  if (Tmp.empty())
1602c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt    return;
16038ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor
160406dec892b5300b43263d25c5476b506c9d6cfbadAbramo Bagnara  if (location.isUndef())
16058ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor    return;
16068ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor
16078ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor  for (ExplodedNodeSet::iterator NI=Tmp.begin(), NE=Tmp.end(); NI!=NE; ++NI)
1608c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt    evalBind(Dst, StoreE, *NI, location, Val, false);
16098ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor}
16108ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor
16118ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregorvoid ExprEngine::evalLoad(ExplodedNodeSet &Dst,
16128ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor                          const Expr *NodeEx,
16138ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor                          const Expr *BoundEx,
16148ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor                          ExplodedNode *Pred,
16158ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor                          ProgramStateRef state,
1616c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt                          SVal location,
1617c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt                          const ProgramPointTag *tag,
16188ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor                          QualType LoadTy)
1619c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt{
16208ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor  assert(!isa<NonLoc>(location) && "location cannot be a NonLoc.");
16218ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor
16228ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor  // Are we loading from a region?  This actually results in two loads; one
16238ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor  // to fetch the address of the referenced value and one to fetch the
16248ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor  // referenced value.
1625c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt  if (const TypedValueRegion *TR =
16268ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor        dyn_cast_or_null<TypedValueRegion>(location.getAsRegion())) {
16278ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor
1628c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt    QualType ValTy = TR->getValueType();
1629c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt    if (const ReferenceType *RT = ValTy->getAs<ReferenceType>()) {
1630c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt      static SimpleProgramPointTag
1631c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt             loadReferenceTag("ExprEngine : Load Reference");
16328ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor      ExplodedNodeSet Tmp;
16338ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor      evalLoadCommon(Tmp, NodeEx, BoundEx, Pred, state,
16348ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor                     location, &loadReferenceTag,
1635c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt                     getContext().getPointerType(RT->getPointeeType()));
16368ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor
16378ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor      // Perform the load from the referenced value.
16388ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor      for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end() ; I!=E; ++I) {
16398ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor        state = (*I)->getState();
16408ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor        location = state->getSVal(BoundEx, (*I)->getLocationContext());
16418ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor        evalLoadCommon(Dst, NodeEx, BoundEx, *I, state, location, tag, LoadTy);
16428ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor      }
16438ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor      return;
16448ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor    }
1645c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt  }
16468ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor
16478ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor  evalLoadCommon(Dst, NodeEx, BoundEx, Pred, state, location, tag, LoadTy);
16488ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor}
16498ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor
16508ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregorvoid ExprEngine::evalLoadCommon(ExplodedNodeSet &Dst,
16518ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor                                const Expr *NodeEx,
1652c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt                                const Expr *BoundEx,
16538cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne                                ExplodedNode *Pred,
16548ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor                                ProgramStateRef state,
16558cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne                                SVal location,
16568ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor                                const ProgramPointTag *tag,
16578ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor                                QualType LoadTy) {
16588ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor  assert(NodeEx);
16598ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor  assert(BoundEx);
16608ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor  // Evaluate the location (checks for bad dereferences).
16618ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor  ExplodedNodeSet Tmp;
1662c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt  evalLocation(Tmp, NodeEx, BoundEx, Pred, state, location, tag, true);
16638ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor  if (Tmp.empty())
16648ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor    return;
16658ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor
16668ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor  StmtNodeBuilder Bldr(Tmp, Dst, *currentBuilderContext);
16678ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor  if (location.isUndef())
16688ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor    return;
16698ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor
16708ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor  // Proceed with the load.
16718ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor  for (ExplodedNodeSet::iterator NI=Tmp.begin(), NE=Tmp.end(); NI!=NE; ++NI) {
16728cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne    state = (*NI)->getState();
16738cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne    const LocationContext *LCtx = (*NI)->getLocationContext();
16748cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne
16758ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor    if (location.isUnknown()) {
16768ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor      // This is important.  We must nuke the old binding.
16778ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor      Bldr.generateNode(NodeEx, *NI,
16788ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor                        state->BindExpr(BoundEx, LCtx, UnknownVal()),
16798ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor                        false, tag,
16808ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor                        ProgramPoint::PostLoadKind);
1681c302113179a1c2b1254224ea9b6f5316ceeb375cSean Hunt    }
16828ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor    else {
16838ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor      if (LoadTy.isNull())
16848ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor        LoadTy = BoundEx->getType();
16858ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor      SVal V = state->getSVal(cast<Loc>(location), LoadTy);
168663c00d7f35fa060c0a446c9df3a4402d9c7757feJohn McCall      Bldr.generateNode(NodeEx, *NI,
16878ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor                        state->bindExprAndLocation(BoundEx, LCtx, location, V),
16888ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor                        false, tag, ProgramPoint::PostLoadKind);
16898ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor    }
16908ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor  }
16918ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor}
16928ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor
16938ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregorvoid ExprEngine::evalLocation(ExplodedNodeSet &Dst,
16948ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor                              const Stmt *NodeEx,
16958ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor                              const Stmt *BoundEx,
16968ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor                              ExplodedNode *Pred,
169763c00d7f35fa060c0a446c9df3a4402d9c7757feJohn McCall                              ProgramStateRef state,
169863c00d7f35fa060c0a446c9df3a4402d9c7757feJohn McCall                              SVal location,
169963c00d7f35fa060c0a446c9df3a4402d9c7757feJohn McCall                              const ProgramPointTag *tag,
170063c00d7f35fa060c0a446c9df3a4402d9c7757feJohn McCall                              bool isLoad) {
170163c00d7f35fa060c0a446c9df3a4402d9c7757feJohn McCall  StmtNodeBuilder BldrTop(Pred, Dst, *currentBuilderContext);
170263c00d7f35fa060c0a446c9df3a4402d9c7757feJohn McCall  // Early checks for performance reason.
17038ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor  if (location.isUnknown()) {
17048ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor    return;
1705f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne  }
1706f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne
1707f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne  ExplodedNodeSet Src;
1708f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne  BldrTop.takeNodes(Pred);
1709f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne  StmtNodeBuilder Bldr(Pred, Src, *currentBuilderContext);
17100518999d3adcc289997bd974dce90cc97f5c1c44Sebastian Redl  if (Pred->getState() != state) {
1711d457589fc69dc7a9c80cd74d317c0b81a35a27c9Sebastian Redl    // Associate this new state with an ExplodedNode.
1712a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall    // FIXME: If I pass null tag, the graph is incorrect, e.g for
1713d457589fc69dc7a9c80cd74d317c0b81a35a27c9Sebastian Redl    //   int *p;
1714d457589fc69dc7a9c80cd74d317c0b81a35a27c9Sebastian Redl    //   p = 0;
17155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    //   *p = 0xDEADBEEF;
171642602bb40aefcc2751d4078ba88aacf4d965c9bdDouglas Gregor    // "p = 0" is not noted as "Null pointer value stored to 'p'" but
17175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // instead "int *p" is noted as
1718f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne    // "Variable 'p' initialized to a null pointer value"
1719f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne
1720f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne    // FIXME: why is 'tag' not used instead of etag?
1721f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne    static SimpleProgramPointTag etag("ExprEngine: Location");
1722ba49817c5b9f502602672861cf369fd0e53966e8Douglas Gregor    Bldr.generateNode(NodeEx, Pred, state, false, &etag);
17232850784bda09416fc7e9d57f5baa36c9351c757cSebastian Redl  }
1724bebbe0d9b7568ce43a464286bee49429489ef483Douglas Gregor  ExplodedNodeSet Tmp;
1725561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor  getCheckerManager().runCheckersForLocation(Tmp, Src, location, isLoad,
1726bebbe0d9b7568ce43a464286bee49429489ef483Douglas Gregor                                             NodeEx, BoundEx, *this);
1727f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne  BldrTop.addNodes(Tmp);
1728a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall}
1729ba49817c5b9f502602672861cf369fd0e53966e8Douglas Gregor
1730ba49817c5b9f502602672861cf369fd0e53966e8Douglas Gregorstd::pair<const ProgramPointTag *, const ProgramPointTag*>
1731f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter CollingbourneExprEngine::getEagerlyAssumeTags() {
1732f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne  static SimpleProgramPointTag
1733f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne         EagerlyAssumeTrue("ExprEngine : Eagerly Assume True"),
1734f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne         EagerlyAssumeFalse("ExprEngine : Eagerly Assume False");
1735ba49817c5b9f502602672861cf369fd0e53966e8Douglas Gregor  return std::make_pair(&EagerlyAssumeTrue, &EagerlyAssumeFalse);
1736ba49817c5b9f502602672861cf369fd0e53966e8Douglas Gregor}
1737bebbe0d9b7568ce43a464286bee49429489ef483Douglas Gregor
1738561f81243f665cf2001caadc45df505f826b72d6Douglas Gregorvoid ExprEngine::evalEagerlyAssume(ExplodedNodeSet &Dst, ExplodedNodeSet &Src,
1739bebbe0d9b7568ce43a464286bee49429489ef483Douglas Gregor                                   const Expr *Ex) {
1740f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne  StmtNodeBuilder Bldr(Src, Dst, *currentBuilderContext);
1741ba49817c5b9f502602672861cf369fd0e53966e8Douglas Gregor
1742d457589fc69dc7a9c80cd74d317c0b81a35a27c9Sebastian Redl  for (ExplodedNodeSet::iterator I=Src.begin(), E=Src.end(); I!=E; ++I) {
17430518999d3adcc289997bd974dce90cc97f5c1c44Sebastian Redl    ExplodedNode *Pred = *I;
17440b0b77fa29c74c99a77548ed86ca8a04f7cf6b02Douglas Gregor    // Test if the previous node was as the same expression.  This can happen
1745f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne    // when the expression fails to evaluate to anything meaningful and
1746f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne    // (as an optimization) we don't generate a node.
17470b0b77fa29c74c99a77548ed86ca8a04f7cf6b02Douglas Gregor    ProgramPoint P = Pred->getLocation();
1748f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne    if (!isa<PostStmt>(P) || cast<PostStmt>(P).getStmt() != Ex) {
1749f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne      continue;
1750f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne    }
1751f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne
17520b0b77fa29c74c99a77548ed86ca8a04f7cf6b02Douglas Gregor    ProgramStateRef state = Pred->getState();
17530518999d3adcc289997bd974dce90cc97f5c1c44Sebastian Redl    SVal V = state->getSVal(Ex, Pred->getLocationContext());
17540518999d3adcc289997bd974dce90cc97f5c1c44Sebastian Redl    nonloc::SymbolVal *SEV = dyn_cast<nonloc::SymbolVal>(&V);
17555ab75172051a6d2ea71a80a79e81c65519fd3462John McCall    if (SEV && SEV->isExpression()) {
17565ab75172051a6d2ea71a80a79e81c65519fd3462John McCall      const std::pair<const ProgramPointTag *, const ProgramPointTag*> &tags =
1757a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall        getEagerlyAssumeTags();
17580518999d3adcc289997bd974dce90cc97f5c1c44Sebastian Redl
17595ab75172051a6d2ea71a80a79e81c65519fd3462John McCall      // First assume that the condition is true.
17600518999d3adcc289997bd974dce90cc97f5c1c44Sebastian Redl      if (ProgramStateRef StateTrue = state->assume(*SEV, true)) {
1761caae7b099a0324b7c15dc89a9b70969d5d7ce996Chris Lattner        SVal Val = svalBuilder.makeIntVal(1U, Ex->getType());
17620518999d3adcc289997bd974dce90cc97f5c1c44Sebastian Redl        StateTrue = StateTrue->BindExpr(Ex, Pred->getLocationContext(), Val);
1763d457589fc69dc7a9c80cd74d317c0b81a35a27c9Sebastian Redl        Bldr.generateNode(Ex, Pred, StateTrue, false, tags.first);
17640518999d3adcc289997bd974dce90cc97f5c1c44Sebastian Redl      }
1765caae7b099a0324b7c15dc89a9b70969d5d7ce996Chris Lattner
1766f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne      // Next, assume that the condition is false.
1767caae7b099a0324b7c15dc89a9b70969d5d7ce996Chris Lattner      if (ProgramStateRef StateFalse = state->assume(*SEV, false)) {
17680b0b77fa29c74c99a77548ed86ca8a04f7cf6b02Douglas Gregor        SVal Val = svalBuilder.makeIntVal(0U, Ex->getType());
17690b0b77fa29c74c99a77548ed86ca8a04f7cf6b02Douglas Gregor        StateFalse = StateFalse->BindExpr(Ex, Pred->getLocationContext(), Val);
1770a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall        Bldr.generateNode(Ex, Pred, StateFalse, false, tags.second);
1771a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall      }
17721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    }
17730b0b77fa29c74c99a77548ed86ca8a04f7cf6b02Douglas Gregor  }
17740b0b77fa29c74c99a77548ed86ca8a04f7cf6b02Douglas Gregor}
17750518999d3adcc289997bd974dce90cc97f5c1c44Sebastian Redl
17760518999d3adcc289997bd974dce90cc97f5c1c44Sebastian Redlvoid ExprEngine::VisitAsmStmt(const AsmStmt *A, ExplodedNode *Pred,
17770518999d3adcc289997bd974dce90cc97f5c1c44Sebastian Redl                              ExplodedNodeSet &Dst) {
17780518999d3adcc289997bd974dce90cc97f5c1c44Sebastian Redl  StmtNodeBuilder Bldr(Pred, Dst, *currentBuilderContext);
17790518999d3adcc289997bd974dce90cc97f5c1c44Sebastian Redl  // We have processed both the inputs and the outputs.  All of the outputs
17800518999d3adcc289997bd974dce90cc97f5c1c44Sebastian Redl  // should evaluate to Locs.  Nuke all of their values.
178176e773a443be9f006610f46529e07d4c8d857680Chris Lattner
17820b0b77fa29c74c99a77548ed86ca8a04f7cf6b02Douglas Gregor  // FIXME: Some day in the future it would be nice to allow a "plug-in"
17830b0b77fa29c74c99a77548ed86ca8a04f7cf6b02Douglas Gregor  // which interprets the inline asm and stores proper results in the
17840b0b77fa29c74c99a77548ed86ca8a04f7cf6b02Douglas Gregor  // outputs.
17850b0b77fa29c74c99a77548ed86ca8a04f7cf6b02Douglas Gregor
1786866b5c03e3b9c01cf496ad97b85a05afc917345bTed Kremenek  ProgramStateRef state = Pred->getState();
178763c00d7f35fa060c0a446c9df3a4402d9c7757feJohn McCall
1788866b5c03e3b9c01cf496ad97b85a05afc917345bTed Kremenek  for (AsmStmt::const_outputs_iterator OI = A->begin_outputs(),
1789866b5c03e3b9c01cf496ad97b85a05afc917345bTed Kremenek       OE = A->end_outputs(); OI != OE; ++OI) {
17905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    SVal X = state->getSVal(*OI, Pred->getLocationContext());
17911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    assert (!isa<NonLoc>(X));  // Should be an Lval, or unknown, undef.
1792f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne
17935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    if (isa<Loc>(X))
1794f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne      state = state->bindLoc(cast<Loc>(X), UnknownVal());
17951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  }
179677ed8e4edf6ed78c53fb20ec3210aff2a59c9d87Ted Kremenek
179763c00d7f35fa060c0a446c9df3a4402d9c7757feJohn McCall  Bldr.generateNode(A, Pred, state);
17985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
17995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
18005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencervoid ExprEngine::VisitMSAsmStmt(const MSAsmStmt *A, ExplodedNode *Pred,
18015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                                ExplodedNodeSet &Dst) {
18025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  StmtNodeBuilder Bldr(Pred, Dst, *currentBuilderContext);
18035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  Bldr.generateNode(A, Pred, Pred->getState());
18045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
18055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
180677ed8e4edf6ed78c53fb20ec3210aff2a59c9d87Ted Kremenek//===----------------------------------------------------------------------===//
18071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump// Visualization.
18085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
18095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
18102324512285caac0332bbbc6e4cab6245d2a370a1Ted Kremenek#ifndef NDEBUG
1811f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCallstatic ExprEngine* GraphPrintCheckerState;
181273d0d4fac161ed12926e010dcf8b448a8de6a2ecChris Lattnerstatic SourceManager* GraphPrintSourceManager;
1813f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall
18142850784bda09416fc7e9d57f5baa36c9351c757cSebastian Redlnamespace llvm {
1815bebbe0d9b7568ce43a464286bee49429489ef483Douglas Gregortemplate<>
1816561f81243f665cf2001caadc45df505f826b72d6Douglas Gregorstruct DOTGraphTraits<ExplodedNode*> :
1817561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor  public DefaultDOTGraphTraits {
1818bebbe0d9b7568ce43a464286bee49429489ef483Douglas Gregor
1819bebbe0d9b7568ce43a464286bee49429489ef483Douglas Gregor  DOTGraphTraits (bool isSimple=false) : DefaultDOTGraphTraits(isSimple) {}
18202850784bda09416fc7e9d57f5baa36c9351c757cSebastian Redl
182173d0d4fac161ed12926e010dcf8b448a8de6a2ecChris Lattner  // FIXME: Since we do not cache error nodes in ExprEngine now, this does not
182273d0d4fac161ed12926e010dcf8b448a8de6a2ecChris Lattner  // work.
182373d0d4fac161ed12926e010dcf8b448a8de6a2ecChris Lattner  static std::string getNodeAttributes(const ExplodedNode *N, void*) {
18241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1825cb2ca73c1d7e76cc1358ce51457d2d5837d84f9bDouglas Gregor#if 0
1826cb2ca73c1d7e76cc1358ce51457d2d5837d84f9bDouglas Gregor      // FIXME: Replace with a general scheme to tell if the node is
1827cb2ca73c1d7e76cc1358ce51457d2d5837d84f9bDouglas Gregor      // an error node.
1828cb2ca73c1d7e76cc1358ce51457d2d5837d84f9bDouglas Gregor    if (GraphPrintCheckerState->isImplicitNullDeref(N) ||
18292324512285caac0332bbbc6e4cab6245d2a370a1Ted Kremenek        GraphPrintCheckerState->isExplicitNullDeref(N) ||
18302324512285caac0332bbbc6e4cab6245d2a370a1Ted Kremenek        GraphPrintCheckerState->isUndefDeref(N) ||
18312324512285caac0332bbbc6e4cab6245d2a370a1Ted Kremenek        GraphPrintCheckerState->isUndefStore(N) ||
18322324512285caac0332bbbc6e4cab6245d2a370a1Ted Kremenek        GraphPrintCheckerState->isUndefControlFlow(N) ||
18332324512285caac0332bbbc6e4cab6245d2a370a1Ted Kremenek        GraphPrintCheckerState->isUndefResult(N) ||
183433fd5c124aac15bab7cad95e4e0e7761356d2c06Christopher Lamb        GraphPrintCheckerState->isBadCall(N) ||
183533fd5c124aac15bab7cad95e4e0e7761356d2c06Christopher Lamb        GraphPrintCheckerState->isUndefArg(N))
183633fd5c124aac15bab7cad95e4e0e7761356d2c06Christopher Lamb      return "color=\"red\",style=\"filled\"";
183733fd5c124aac15bab7cad95e4e0e7761356d2c06Christopher Lamb
18385549976193e34417d4474a5f4a514268ef6666c7Ted Kremenek    if (GraphPrintCheckerState->isNoReturnCall(N))
18395549976193e34417d4474a5f4a514268ef6666c7Ted Kremenek      return "color=\"blue\",style=\"filled\"";
1840cb2ca73c1d7e76cc1358ce51457d2d5837d84f9bDouglas Gregor#endif
1841cb2ca73c1d7e76cc1358ce51457d2d5837d84f9bDouglas Gregor    return "";
18425549976193e34417d4474a5f4a514268ef6666c7Ted Kremenek  }
18435549976193e34417d4474a5f4a514268ef6666c7Ted Kremenek
1844cb2ca73c1d7e76cc1358ce51457d2d5837d84f9bDouglas Gregor  static void printLocation(llvm::raw_ostream &Out, SourceLocation SLoc) {
18451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    if (SLoc.isFileID()) {
18461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      Out << "\\lline="
18475549976193e34417d4474a5f4a514268ef6666c7Ted Kremenek        << GraphPrintSourceManager->getExpansionLineNumber(SLoc)
184877ed8e4edf6ed78c53fb20ec3210aff2a59c9d87Ted Kremenek        << " col="
18491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        << GraphPrintSourceManager->getExpansionColumnNumber(SLoc)
18501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        << "\\l";
18515549976193e34417d4474a5f4a514268ef6666c7Ted Kremenek    }
18522324512285caac0332bbbc6e4cab6245d2a370a1Ted Kremenek  }
18531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
18541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  static std::string getNodeLabel(const ExplodedNode *N, void*){
18555549976193e34417d4474a5f4a514268ef6666c7Ted Kremenek
18562324512285caac0332bbbc6e4cab6245d2a370a1Ted Kremenek    std::string sbuf;
18571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    llvm::raw_string_ostream Out(sbuf);
185877ed8e4edf6ed78c53fb20ec3210aff2a59c9d87Ted Kremenek
18595549976193e34417d4474a5f4a514268ef6666c7Ted Kremenek    // Program Location.
18601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    ProgramPoint Loc = N->getLocation();
18611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
186263c00d7f35fa060c0a446c9df3a4402d9c7757feJohn McCall    switch (Loc.getKind()) {
186377ed8e4edf6ed78c53fb20ec3210aff2a59c9d87Ted Kremenek      case ProgramPoint::BlockEntranceKind: {
18645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer        Out << "Block Entrance: B"
18651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            << cast<BlockEntrance>(Loc).getBlock()->getBlockID();
1866026dc96ac6ece60da5e1b98e2a71bd0ff0939fd8Chris Lattner        if (const NamedDecl *ND =
1867cb2ca73c1d7e76cc1358ce51457d2d5837d84f9bDouglas Gregor                    dyn_cast<NamedDecl>(Loc.getLocationContext()->getDecl())) {
1868cb2ca73c1d7e76cc1358ce51457d2d5837d84f9bDouglas Gregor          Out << " (";
186963c00d7f35fa060c0a446c9df3a4402d9c7757feJohn McCall          ND->printName(Out);
18705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer          Out << ")";
18711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        }
18721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        break;
18735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      }
18745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
18751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      case ProgramPoint::BlockExitKind:
187677ed8e4edf6ed78c53fb20ec3210aff2a59c9d87Ted Kremenek        assert (false);
187763c00d7f35fa060c0a446c9df3a4402d9c7757feJohn McCall        break;
187863c00d7f35fa060c0a446c9df3a4402d9c7757feJohn McCall
187963c00d7f35fa060c0a446c9df3a4402d9c7757feJohn McCall      case ProgramPoint::CallEnterKind:
18805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer        Out << "CallEnter";
18815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer        break;
18825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1883b4609806e9232593ece09ce08b630836e825865cDouglas Gregor      case ProgramPoint::CallExitBeginKind:
18841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        Out << "CallExitBegin";
1885b4609806e9232593ece09ce08b630836e825865cDouglas Gregor        break;
18861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1887b4609806e9232593ece09ce08b630836e825865cDouglas Gregor      case ProgramPoint::CallExitEndKind:
1888b4609806e9232593ece09ce08b630836e825865cDouglas Gregor        Out << "CallExitEnd";
18895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer        break;
1890cc324ad80ab940efca006b0064f7ca70a6181816Peter Collingbourne
18915549976193e34417d4474a5f4a514268ef6666c7Ted Kremenek      case ProgramPoint::PostStmtPurgeDeadSymbolsKind:
18925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer        Out << "PostStmtPurgeDeadSymbols";
18935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer        break;
18941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1895b4609806e9232593ece09ce08b630836e825865cDouglas Gregor      case ProgramPoint::PreStmtPurgeDeadSymbolsKind:
1896cc324ad80ab940efca006b0064f7ca70a6181816Peter Collingbourne        Out << "PreStmtPurgeDeadSymbols";
1897cc324ad80ab940efca006b0064f7ca70a6181816Peter Collingbourne        break;
1898cc324ad80ab940efca006b0064f7ca70a6181816Peter Collingbourne
1899cc324ad80ab940efca006b0064f7ca70a6181816Peter Collingbourne      case ProgramPoint::EpsilonKind:
1900cc324ad80ab940efca006b0064f7ca70a6181816Peter Collingbourne        Out << "Epsilon Point";
1901cc324ad80ab940efca006b0064f7ca70a6181816Peter Collingbourne        break;
1902cc324ad80ab940efca006b0064f7ca70a6181816Peter Collingbourne
1903cc324ad80ab940efca006b0064f7ca70a6181816Peter Collingbourne      case ProgramPoint::PreImplicitCallKind: {
1904cc324ad80ab940efca006b0064f7ca70a6181816Peter Collingbourne        ImplicitCallPoint *PC = cast<ImplicitCallPoint>(&Loc);
1905cc324ad80ab940efca006b0064f7ca70a6181816Peter Collingbourne        Out << "PreCall: ";
1906cc324ad80ab940efca006b0064f7ca70a6181816Peter Collingbourne
1907cc324ad80ab940efca006b0064f7ca70a6181816Peter Collingbourne        // FIXME: Get proper printing options.
1908cc324ad80ab940efca006b0064f7ca70a6181816Peter Collingbourne        PC->getDecl()->print(Out, LangOptions());
1909cc324ad80ab940efca006b0064f7ca70a6181816Peter Collingbourne        printLocation(Out, PC->getLocation());
1910cc324ad80ab940efca006b0064f7ca70a6181816Peter Collingbourne        break;
1911cc324ad80ab940efca006b0064f7ca70a6181816Peter Collingbourne      }
1912cc324ad80ab940efca006b0064f7ca70a6181816Peter Collingbourne
1913cc324ad80ab940efca006b0064f7ca70a6181816Peter Collingbourne      case ProgramPoint::PostImplicitCallKind: {
1914cc324ad80ab940efca006b0064f7ca70a6181816Peter Collingbourne        ImplicitCallPoint *PC = cast<ImplicitCallPoint>(&Loc);
1915cc324ad80ab940efca006b0064f7ca70a6181816Peter Collingbourne        Out << "PostCall: ";
191642602bb40aefcc2751d4078ba88aacf4d965c9bdDouglas Gregor
19175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer        // FIXME: Get proper printing options.
19181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        PC->getDecl()->print(Out, LangOptions());
1919f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall        printLocation(Out, PC->getLocation());
19201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        break;
19211f0d0133b0e8d1f01f63951ee04927796b34740dDouglas Gregor      }
1922ba0a9006dbc4814e1e35f82812cb5a1dad65e8b8Argyrios Kyrtzidis
19231f0d0133b0e8d1f01f63951ee04927796b34740dDouglas Gregor      default: {
19245549976193e34417d4474a5f4a514268ef6666c7Ted Kremenek        if (StmtPoint *L = dyn_cast<StmtPoint>(&Loc)) {
19255549976193e34417d4474a5f4a514268ef6666c7Ted Kremenek          const Stmt *S = L->getStmt();
192618b2515e1bf8c86a4900792692e42fe1296be28dChris Lattner
1927a00425414e8c209cabc25d1826b200aeb94259afZhongxing Xu          Out << S->getStmtClassName() << ' ' << (void*) S << ' ';
1928d20254f2875d0004c57ee766f258dbcee29f4841Nuno Lopes          LangOptions LO; // FIXME.
1929d20254f2875d0004c57ee766f258dbcee29f4841Nuno Lopes          S->printPretty(Out, 0, PrintingPolicy(LO));
1930d20254f2875d0004c57ee766f258dbcee29f4841Nuno Lopes          printLocation(Out, S->getLocStart());
1931d20254f2875d0004c57ee766f258dbcee29f4841Nuno Lopes
1932d20254f2875d0004c57ee766f258dbcee29f4841Nuno Lopes          if (isa<PreStmt>(Loc))
1933a00425414e8c209cabc25d1826b200aeb94259afZhongxing Xu            Out << "\\lPreStmt\\l;";
1934a00425414e8c209cabc25d1826b200aeb94259afZhongxing Xu          else if (isa<PostLoad>(Loc))
1935bc8d42c6f1565c0b2f93ad524edebfd7a4e6cac6Chris Lattner            Out << "\\lPostLoad\\l;";
1936bc8d42c6f1565c0b2f93ad524edebfd7a4e6cac6Chris Lattner          else if (isa<PostStore>(Loc))
1937bc8d42c6f1565c0b2f93ad524edebfd7a4e6cac6Chris Lattner            Out << "\\lPostStore\\l";
1938a00425414e8c209cabc25d1826b200aeb94259afZhongxing Xu          else if (isa<PostLValue>(Loc))
19395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer            Out << "\\lPostLValue\\l";
19405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
19415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#if 0
19421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            // FIXME: Replace with a general scheme to determine
1943aa165f8458b51c546bebff947343e1a36f3594cbDouglas Gregor            // the name of the check.
1944cc324ad80ab940efca006b0064f7ca70a6181816Peter Collingbourne          if (GraphPrintCheckerState->isImplicitNullDeref(N))
1945cc324ad80ab940efca006b0064f7ca70a6181816Peter Collingbourne            Out << "\\|Implicit-Null Dereference.\\l";
1946cc324ad80ab940efca006b0064f7ca70a6181816Peter Collingbourne          else if (GraphPrintCheckerState->isExplicitNullDeref(N))
1947aa165f8458b51c546bebff947343e1a36f3594cbDouglas Gregor            Out << "\\|Explicit-Null Dereference.\\l";
19485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer          else if (GraphPrintCheckerState->isUndefDeref(N))
19495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer            Out << "\\|Dereference of undefialied value.\\l";
19505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer          else if (GraphPrintCheckerState->isUndefStore(N))
1951cc324ad80ab940efca006b0064f7ca70a6181816Peter Collingbourne            Out << "\\|Store to Undefined Loc.";
19525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer          else if (GraphPrintCheckerState->isUndefResult(N))
19535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer            Out << "\\|Result of operation is undefined.";
19545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer          else if (GraphPrintCheckerState->isNoReturnCall(N))
1955cc324ad80ab940efca006b0064f7ca70a6181816Peter Collingbourne            Out << "\\|Call to function marked \"noreturn\".";
19565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer          else if (GraphPrintCheckerState->isBadCall(N))
19571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            Out << "\\|Call to NULL/Undefined.";
1958934f276cc5b45e19cd12ebb2d04fd7972a23865cSteve Naroff          else if (GraphPrintCheckerState->isUndefArg(N))
1959934f276cc5b45e19cd12ebb2d04fd7972a23865cSteve Naroff            Out << "\\|Argument in call is undefined";
1960934f276cc5b45e19cd12ebb2d04fd7972a23865cSteve Naroff#endif
1961cc324ad80ab940efca006b0064f7ca70a6181816Peter Collingbourne
1962934f276cc5b45e19cd12ebb2d04fd7972a23865cSteve Naroff          break;
19631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        }
1964d18b3299debb7b0dbd9d34d9369189dc98c87f53Chris Lattner
1965d18b3299debb7b0dbd9d34d9369189dc98c87f53Chris Lattner        const BlockEdge &E = cast<BlockEdge>(Loc);
1966d18b3299debb7b0dbd9d34d9369189dc98c87f53Chris Lattner        Out << "Edge: (B" << E.getSrc()->getBlockID() << ", B"
19678189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek            << E.getDst()->getBlockID()  << ')';
19681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
19695549976193e34417d4474a5f4a514268ef6666c7Ted Kremenek        if (const Stmt *T = E.getSrc()->getTerminator()) {
19705549976193e34417d4474a5f4a514268ef6666c7Ted Kremenek
19711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump          SourceLocation SLoc = T->getLocStart();
1972cc324ad80ab940efca006b0064f7ca70a6181816Peter Collingbourne
1973cc324ad80ab940efca006b0064f7ca70a6181816Peter Collingbourne          Out << "\\|Terminator: ";
1974cc324ad80ab940efca006b0064f7ca70a6181816Peter Collingbourne          LangOptions LO; // FIXME.
1975cc324ad80ab940efca006b0064f7ca70a6181816Peter Collingbourne          E.getSrc()->printTerminator(Out, LO);
1976cc324ad80ab940efca006b0064f7ca70a6181816Peter Collingbourne
1977cc324ad80ab940efca006b0064f7ca70a6181816Peter Collingbourne          if (SLoc.isFileID()) {
1978cc324ad80ab940efca006b0064f7ca70a6181816Peter Collingbourne            Out << "\\lline="
1979cc324ad80ab940efca006b0064f7ca70a6181816Peter Collingbourne              << GraphPrintSourceManager->getExpansionLineNumber(SLoc)
1980cc324ad80ab940efca006b0064f7ca70a6181816Peter Collingbourne              << " col="
1981cc324ad80ab940efca006b0064f7ca70a6181816Peter Collingbourne              << GraphPrintSourceManager->getExpansionColumnNumber(SLoc);
19821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump          }
19835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
19845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer          if (isa<SwitchStmt>(T)) {
19855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer            const Stmt *Label = E.getDst()->getLabel();
19865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1987cb888967400a03504c88acedd5248d6778a82f46Chris Lattner            if (Label) {
1988cb888967400a03504c88acedd5248d6778a82f46Chris Lattner              if (const CaseStmt *C = dyn_cast<CaseStmt>(Label)) {
19894ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad                Out << "\\lcase ";
19901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                LangOptions LO; // FIXME.
19911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                C->getLHS()->printPretty(Out, 0, PrintingPolicy(LO));
19921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
19936dde78f744382a5627a04f984a97049e0c4b5e73Anders Carlsson                if (const Stmt *RHS = C->getRHS()) {
19946dde78f744382a5627a04f984a97049e0c4b5e73Anders Carlsson                  Out << " .. ";
19951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                  RHS->printPretty(Out, 0, PrintingPolicy(LO));
1996d18b3299debb7b0dbd9d34d9369189dc98c87f53Chris Lattner                }
19971f0d0133b0e8d1f01f63951ee04927796b34740dDouglas Gregor
1998866b5c03e3b9c01cf496ad97b85a05afc917345bTed Kremenek                Out << ":";
19992882eca5a184c78f793188083f6ce539740a5cf2John McCall              }
20001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump              else {
20011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                assert (isa<DefaultStmt>(Label));
20024bfe1968410ea8ffe3b4f629addd7c4bcf484765Sean Hunt                Out << "\\ldefault:";
20034bfe1968410ea8ffe3b4f629addd7c4bcf484765Sean Hunt              }
20045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer            }
20055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer            else
200688a3514f36de96b19cdf50141c640df1a5f13f6cDouglas Gregor              Out << "\\l(implicit) default:";
200777ed8e4edf6ed78c53fb20ec3210aff2a59c9d87Ted Kremenek          }
200863c00d7f35fa060c0a446c9df3a4402d9c7757feJohn McCall          else if (isa<IndirectGotoStmt>(T)) {
200963c00d7f35fa060c0a446c9df3a4402d9c7757feJohn McCall            // FIXME
201063c00d7f35fa060c0a446c9df3a4402d9c7757feJohn McCall          }
201163c00d7f35fa060c0a446c9df3a4402d9c7757feJohn McCall          else {
20125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer            Out << "\\lCondition: ";
20135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer            if (*E.getSrc()->succ_begin() == E.getDst())
2014ddca44e86281bb7dcf5fdcaf1563434c524e3861Chris Lattner              Out << "true";
20155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer            else
20165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer              Out << "false";
20176bb8017bb9e828d118e15e59d71c66bba323c364John McCall          }
20186857c3e12c86fd0271eb46baab5b18756a94f4cbChandler Carruth
20196857c3e12c86fd0271eb46baab5b18756a94f4cbChandler Carruth          Out << "\\l";
20206857c3e12c86fd0271eb46baab5b18756a94f4cbChandler Carruth        }
20216857c3e12c86fd0271eb46baab5b18756a94f4cbChandler Carruth
20226857c3e12c86fd0271eb46baab5b18756a94f4cbChandler Carruth#if 0
20236857c3e12c86fd0271eb46baab5b18756a94f4cbChandler Carruth          // FIXME: Replace with a general scheme to determine
20246857c3e12c86fd0271eb46baab5b18756a94f4cbChandler Carruth          // the name of the check.
2025161755a09898c95d21bfff33707da9ca41cd53c5John McCall        if (GraphPrintCheckerState->isUndefControlFlow(N)) {
20266bb8017bb9e828d118e15e59d71c66bba323c364John McCall          Out << "\\|Control-flow based on\\lUndefined value.\\l";
20276bb8017bb9e828d118e15e59d71c66bba323c364John McCall        }
2028ddca44e86281bb7dcf5fdcaf1563434c524e3861Chris Lattner#endif
2029ddca44e86281bb7dcf5fdcaf1563434c524e3861Chris Lattner      }
20305549976193e34417d4474a5f4a514268ef6666c7Ted Kremenek    }
20311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2032ddca44e86281bb7dcf5fdcaf1563434c524e3861Chris Lattner    ProgramStateRef state = N->getState();
2033ddca44e86281bb7dcf5fdcaf1563434c524e3861Chris Lattner    Out << "\\|StateID: " << (void*) state.getPtr()
2034f595cc41c4d95fe323f8a2b209523de9956f874dEli Friedman        << " NodeID: " << (void*) N << "\\|";
20351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    state->printDOT(Out);
2036ddca44e86281bb7dcf5fdcaf1563434c524e3861Chris Lattner
20375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Out << "\\l";
20381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
20392577743c5650c646fb705df01403707e94f2df04Abramo Bagnara    if (const ProgramPointTag *tag = Loc.getTag()) {
20402577743c5650c646fb705df01403707e94f2df04Abramo Bagnara      Out << "\\|Tag: " << tag->getTagDescription();
20412577743c5650c646fb705df01403707e94f2df04Abramo Bagnara      Out << "\\l";
20422577743c5650c646fb705df01403707e94f2df04Abramo Bagnara    }
2043ddca44e86281bb7dcf5fdcaf1563434c524e3861Chris Lattner    return Out.str();
204483f6faf37d9bf58986bedc9bc0ea897a56b4dbadDouglas Gregor  }
20451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump};
204683f6faf37d9bf58986bedc9bc0ea897a56b4dbadDouglas Gregor} // end llvm namespace
20476bb8017bb9e828d118e15e59d71c66bba323c364John McCall#endif
20486bb8017bb9e828d118e15e59d71c66bba323c364John McCall
2049c4bf26fbdff42967d660f505a83f75a4df2cc752Douglas Gregor#ifndef NDEBUG
20506bb8017bb9e828d118e15e59d71c66bba323c364John McCalltemplate <typename ITERATOR>
20511eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpExplodedNode *GetGraphNode(ITERATOR I) { return *I; }
2052c4bf26fbdff42967d660f505a83f75a4df2cc752Douglas Gregor
2053c4bf26fbdff42967d660f505a83f75a4df2cc752Douglas Gregortemplate <> ExplodedNode*
2054c4bf26fbdff42967d660f505a83f75a4df2cc752Douglas GregorGetGraphNode<llvm::DenseMap<ExplodedNode*, Expr*>::iterator>
2055c4bf26fbdff42967d660f505a83f75a4df2cc752Douglas Gregor  (llvm::DenseMap<ExplodedNode*, Expr*>::iterator I) {
20566bb8017bb9e828d118e15e59d71c66bba323c364John McCall  return I->first;
2057c4bf26fbdff42967d660f505a83f75a4df2cc752Douglas Gregor}
20581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump#endif
20597cc58b4c927fca539d43eaa58e00dca95946eb7cAbramo Bagnara
20607cc58b4c927fca539d43eaa58e00dca95946eb7cAbramo Bagnaravoid ExprEngine::ViewGraph(bool trim) {
20617cc58b4c927fca539d43eaa58e00dca95946eb7cAbramo Bagnara#ifndef NDEBUG
20627cc58b4c927fca539d43eaa58e00dca95946eb7cAbramo Bagnara  if (trim) {
206383f6faf37d9bf58986bedc9bc0ea897a56b4dbadDouglas Gregor    std::vector<ExplodedNode*> Src;
20646bb8017bb9e828d118e15e59d71c66bba323c364John McCall
20656bb8017bb9e828d118e15e59d71c66bba323c364John McCall    // Flush any outstanding reports to make sure we cover all the nodes.
20666bb8017bb9e828d118e15e59d71c66bba323c364John McCall    // This does not cause them to get displayed.
206783f6faf37d9bf58986bedc9bc0ea897a56b4dbadDouglas Gregor    for (BugReporter::iterator I=BR.begin(), E=BR.end(); I!=E; ++I)
206883f6faf37d9bf58986bedc9bc0ea897a56b4dbadDouglas Gregor      const_cast<BugType*>(*I)->FlushReports(BR);
206983f6faf37d9bf58986bedc9bc0ea897a56b4dbadDouglas Gregor
20706bb8017bb9e828d118e15e59d71c66bba323c364John McCall    // Iterate through the reports and get their nodes.
2071c4bf26fbdff42967d660f505a83f75a4df2cc752Douglas Gregor    for (BugReporter::EQClasses_iterator
2072c4bf26fbdff42967d660f505a83f75a4df2cc752Douglas Gregor           EI = BR.EQClasses_begin(), EE = BR.EQClasses_end(); EI != EE; ++EI) {
20731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      ExplodedNode *N = const_cast<ExplodedNode*>(EI->begin()->getErrorNode());
20745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      if (N) Src.push_back(N);
2075f595cc41c4d95fe323f8a2b209523de9956f874dEli Friedman    }
2076f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall
2077f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall    ViewGraph(&Src[0], &Src[0]+Src.size());
2078f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall  }
2079561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor  else {
2080561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor    GraphPrintCheckerState = this;
2081561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor    GraphPrintSourceManager = &getContext().getSourceManager();
2082bebbe0d9b7568ce43a464286bee49429489ef483Douglas Gregor
20832577743c5650c646fb705df01403707e94f2df04Abramo Bagnara    llvm::ViewGraph(*G.roots_begin(), "ExprEngine");
20842577743c5650c646fb705df01403707e94f2df04Abramo Bagnara
20857cc58b4c927fca539d43eaa58e00dca95946eb7cAbramo Bagnara    GraphPrintCheckerState = NULL;
20867cc58b4c927fca539d43eaa58e00dca95946eb7cAbramo Bagnara    GraphPrintSourceManager = NULL;
20872577743c5650c646fb705df01403707e94f2df04Abramo Bagnara  }
20882577743c5650c646fb705df01403707e94f2df04Abramo Bagnara#endif
20892577743c5650c646fb705df01403707e94f2df04Abramo Bagnara}
20902577743c5650c646fb705df01403707e94f2df04Abramo Bagnara
20912577743c5650c646fb705df01403707e94f2df04Abramo Bagnaravoid ExprEngine::ViewGraph(ExplodedNode** Beg, ExplodedNode** End) {
20922577743c5650c646fb705df01403707e94f2df04Abramo Bagnara#ifndef NDEBUG
20932577743c5650c646fb705df01403707e94f2df04Abramo Bagnara  GraphPrintCheckerState = this;
20942577743c5650c646fb705df01403707e94f2df04Abramo Bagnara  GraphPrintSourceManager = &getContext().getSourceManager();
2095f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall
2096f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall  std::auto_ptr<ExplodedGraph> TrimmedG(G.Trim(Beg, End).first);
2097f89e55ab1bfb3ea997f8b02997c611a02254eb2dJohn McCall
2098bebbe0d9b7568ce43a464286bee49429489ef483Douglas Gregor  if (!TrimmedG.get())
2099561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor    llvm::errs() << "warning: Trimmed ExplodedGraph is empty.\n";
2100bebbe0d9b7568ce43a464286bee49429489ef483Douglas Gregor  else
21012577743c5650c646fb705df01403707e94f2df04Abramo Bagnara    llvm::ViewGraph(*TrimmedG->roots_begin(), "TrimmedExprEngine");
21022577743c5650c646fb705df01403707e94f2df04Abramo Bagnara
21037cc58b4c927fca539d43eaa58e00dca95946eb7cAbramo Bagnara  GraphPrintCheckerState = NULL;
21047cc58b4c927fca539d43eaa58e00dca95946eb7cAbramo Bagnara  GraphPrintSourceManager = NULL;
2105510190777c4bd53e960eea4665b204778fec1b64Eli Friedman#endif
21061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump}
210740d96a69c0e1e8c10f92d450c305a7aae696ca9cDouglas Gregor