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