ExprEngine.cpp revision 603513d2294c437b37bcf47f326b686e31bd9e84
1d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis//=-- ExprEngine.cpp - Path-Sensitive Expression-Level Dataflow ---*- C++ -*-= 264924859b6b09d1cfb62fecf5954ec6c27cb58feTed Kremenek// 34af84313df0d2710fd57af89132e680294225cadTed Kremenek// The LLVM Compiler Infrastructure 4d27f8169f4b68337a489547a41ac45bf7a5d1ddfTed Kremenek// 5d27f8169f4b68337a489547a41ac45bf7a5d1ddfTed Kremenek// This file is distributed under the University of Illinois Open Source 6d27f8169f4b68337a489547a41ac45bf7a5d1ddfTed Kremenek// License. See LICENSE.TXT for details. 7d27f8169f4b68337a489547a41ac45bf7a5d1ddfTed Kremenek// 8d27f8169f4b68337a489547a41ac45bf7a5d1ddfTed Kremenek//===----------------------------------------------------------------------===// 9d27f8169f4b68337a489547a41ac45bf7a5d1ddfTed Kremenek// 1077349cb20bfd7069d081f84c91975bfa8ef60a32Ted Kremenek// This file defines a meta-engine for path-sensitive dataflow analysis that 1177349cb20bfd7069d081f84c91975bfa8ef60a32Ted Kremenek// is built on GREngine, but provides the boilerplate to execute transfer 1277349cb20bfd7069d081f84c91975bfa8ef60a32Ted Kremenek// functions and build the ExplodedGraph at the expression level. 13d27f8169f4b68337a489547a41ac45bf7a5d1ddfTed Kremenek// 14d27f8169f4b68337a489547a41ac45bf7a5d1ddfTed Kremenek//===----------------------------------------------------------------------===// 15a7af5ea88a6c5bdf87497cca6c20831e8c546751Argyrios Kyrtzidis 16c2994283aa7538b7420c8e398cde7afa328d7042Anna Zaks#define DEBUG_TYPE "ExprEngine" 17c2994283aa7538b7420c8e398cde7afa328d7042Anna Zaks 1843dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis#include "clang/StaticAnalyzer/Core/CheckerManager.h" 199b663716449b618ba0390b1dbebc54fa8e971124Ted Kremenek#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" 209b663716449b618ba0390b1dbebc54fa8e971124Ted Kremenek#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h" 21f540c54701e3eeb34cb619a3a4eb18f1ac70ef2dJordan Rose#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" 229b663716449b618ba0390b1dbebc54fa8e971124Ted Kremenek#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h" 23199c3d6cd16aebbb9c7f0d42af9d922c9628bf70Ken Dyck#include "clang/AST/CharUnits.h" 2416f0049415ec596504891259e2a83e19871c0d52Chris Lattner#include "clang/AST/ParentMap.h" 2516f0049415ec596504891259e2a83e19871c0d52Chris Lattner#include "clang/AST/StmtObjC.h" 26337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek#include "clang/AST/StmtCXX.h" 271b63e4f732dbc73d90abf886b4d21f8e3a165f6dChris Lattner#include "clang/Basic/Builtins.h" 2816f0049415ec596504891259e2a83e19871c0d52Chris Lattner#include "clang/Basic/SourceManager.h" 290bed8a12f2878d3cd94fb8bdba55b593d92dd11aTed Kremenek#include "clang/Basic/PrettyStackTrace.h" 30a95d3750441ac8ad03e36af8e6e74039c9a3109dTed Kremenek#include "llvm/Support/raw_ostream.h" 316cb7c1a43b0c8f739d1f54b7fdae5ede86033496Benjamin Kramer#include "llvm/ADT/ImmutableList.h" 32c2994283aa7538b7420c8e398cde7afa328d7042Anna Zaks#include "llvm/ADT/Statistic.h" 334323a57627e796dcfdfdb7d47672dc09ed308edaTed Kremenek 340f5f0595d6a038843a7051c5a65fca7bce2915a0Ted Kremenek#ifndef NDEBUG 350f5f0595d6a038843a7051c5a65fca7bce2915a0Ted Kremenek#include "llvm/Support/GraphWriter.h" 360f5f0595d6a038843a7051c5a65fca7bce2915a0Ted Kremenek#endif 370f5f0595d6a038843a7051c5a65fca7bce2915a0Ted Kremenek 38b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenekusing namespace clang; 399ef6537a894c33003359b1f9b9676e9178e028b7Ted Kremenekusing namespace ento; 40b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenekusing llvm::APSInt; 41ab2b8c54bca82866876f91e756788916d3fa20c3Ted Kremenek 42c2994283aa7538b7420c8e398cde7afa328d7042Anna ZaksSTATISTIC(NumRemoveDeadBindings, 43c2994283aa7538b7420c8e398cde7afa328d7042Anna Zaks "The # of times RemoveDeadBindings is called"); 44749bbe6f5f23676244f12a0d41511c8e73516febAnna ZaksSTATISTIC(NumMaxBlockCountReached, 45749bbe6f5f23676244f12a0d41511c8e73516febAnna Zaks "The # of aborted paths due to reaching the maximum block count in " 46749bbe6f5f23676244f12a0d41511c8e73516febAnna Zaks "a top level function"); 47749bbe6f5f23676244f12a0d41511c8e73516febAnna ZaksSTATISTIC(NumMaxBlockCountReachedInInlined, 48749bbe6f5f23676244f12a0d41511c8e73516febAnna Zaks "The # of aborted paths due to reaching the maximum block count in " 49749bbe6f5f23676244f12a0d41511c8e73516febAnna Zaks "an inlined function"); 505903a373db3d27794c90b25687e0dd6adb0e497dAnna ZaksSTATISTIC(NumTimesRetriedWithoutInlining, 515903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks "The # of times we re-evaluated a call without inlining"); 525903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks 53e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek//===----------------------------------------------------------------------===// 54bdb435ddaafd5069becd543d638112f68825b89dTed Kremenek// Engine construction and deletion. 55bdb435ddaafd5069becd543d638112f68825b89dTed Kremenek//===----------------------------------------------------------------------===// 56bdb435ddaafd5069becd543d638112f68825b89dTed Kremenek 573fd5f370a28552976c52e76c3035d79012d78ddaAnna ZaksExprEngine::ExprEngine(AnalysisManager &mgr, bool gcEnabled, 58fbcb3f11fc90e9f00e6074e9b118b8dc11ca604cAnna Zaks SetOfConstDecls *VisitedCalleesIn, 593bbd8cd831788c506f2980293eb3c7e1b3ca2501Anna Zaks FunctionSummariesTy *FS) 6025e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu : AMgr(mgr), 611d26f48dc2eea1c07431ca1519d7034a21b9bcffTed Kremenek AnalysisDeclContexts(mgr.getAnalysisDeclContextManager()), 62fbcb3f11fc90e9f00e6074e9b118b8dc11ca604cAnna Zaks Engine(*this, FS), 63d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis G(Engine.getGraph()), 64c77a55126fcad66fb086f8e100a494caa2496a2dZhongxing Xu StateMgr(getContext(), mgr.getStoreManagerCreator(), 6532a58084a4c53e6938dd81bfce224db25a5976d1Ted Kremenek mgr.getConstraintManagerCreator(), G.getAllocator(), 66ca5d78d0bc3010164f2f9682967d64d7e305a167Jordan Rose this), 6750a6d0ce344c02782e0207574005c3b2aaa5077cTed Kremenek SymMgr(StateMgr.getSymbolManager()), 68c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek svalBuilder(StateMgr.getSValBuilder()), 698ad8c546372fe602708cb7ceeaf0ebbb866735c6Anna Zaks EntryNode(NULL), 7066c486f275531df6362b3511fc3af6563561801bTed Kremenek currStmt(NULL), currStmtIdx(0), currBldrCtx(0), 714ef19205b6912316296db74a9073ad6fa60e4ccaTed Kremenek ObjCNoRet(mgr.getASTContext()), 72fbcb3f11fc90e9f00e6074e9b118b8dc11ca604cAnna Zaks ObjCGCEnabled(gcEnabled), BR(mgr, *this), 73fbcb3f11fc90e9f00e6074e9b118b8dc11ca604cAnna Zaks VisitedCallees(VisitedCalleesIn) 74255d4d4226b24036ceb11228fbb74286e58620f7Ted Kremenek{ 754d9e497a2b1eab3b1214848216050c64fc3acfd6Jordan Rose unsigned TrimInterval = mgr.options.getGraphTrimInterval(); 764d9e497a2b1eab3b1214848216050c64fc3acfd6Jordan Rose if (TrimInterval != 0) { 774d9e497a2b1eab3b1214848216050c64fc3acfd6Jordan Rose // Enable eager node reclaimation when constructing the ExplodedGraph. 784d9e497a2b1eab3b1214848216050c64fc3acfd6Jordan Rose G.enableNodeReclamation(TrimInterval); 794d9e497a2b1eab3b1214848216050c64fc3acfd6Jordan Rose } 80c80135ba857da48173578b9c528fce6777e18168Ted Kremenek} 8150a6d0ce344c02782e0207574005c3b2aaa5077cTed Kremenek 82d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios KyrtzidisExprEngine::~ExprEngine() { 83cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek BR.FlushReports(); 8450a6d0ce344c02782e0207574005c3b2aaa5077cTed Kremenek} 8550a6d0ce344c02782e0207574005c3b2aaa5077cTed Kremenek 86e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek//===----------------------------------------------------------------------===// 87e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek// Utility methods. 88e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek//===----------------------------------------------------------------------===// 89e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek 908bef8238181a30e52dea380789a7e2d760eac532Ted KremenekProgramStateRef ExprEngine::getInitialState(const LocationContext *InitLoc) { 918bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek ProgramStateRef state = StateMgr.getInitialState(InitLoc); 92a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek const Decl *D = InitLoc->getDecl(); 931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 94cfcd7fd0de701c5ce05e96de1ed2d0bf8c7035d9Ted Kremenek // Preconditions. 9552e5602056e4cade24cbcca57767e94e1d430b03Ted Kremenek // FIXME: It would be nice if we had a more general mechanism to add 9652e5602056e4cade24cbcca57767e94e1d430b03Ted Kremenek // such preconditions. Some day. 975974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek do { 98a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek 995974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 1005974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek // Precondition: the first argument of 'main' is an integer guaranteed 1015974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek // to be > 0. 1025974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek const IdentifierInfo *II = FD->getIdentifier(); 1035974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek if (!II || !(II->getName() == "main" && FD->getNumParams() > 0)) 1045974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek break; 1055974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek 1065974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek const ParmVarDecl *PD = FD->getParamDecl(0); 1075974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek QualType T = PD->getType(); 1085974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek if (!T->isIntegerType()) 1095974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek break; 110b9bbd592c7ea72ada8d982e40a729beb9b53371eTed Kremenek 1115974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek const MemRegion *R = state->getRegion(PD, InitLoc); 1125974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek if (!R) 1135974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek break; 114b9bbd592c7ea72ada8d982e40a729beb9b53371eTed Kremenek 1151397663af9dbcc24dbf0e11de43931b3dc08fdbbTed Kremenek SVal V = state->getSVal(loc::MemRegionVal(R)); 1169c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek SVal Constraint_untested = evalBinOp(state, BO_GT, V, 117c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek svalBuilder.makeZeroVal(T), 1185974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek getContext().IntTy); 1195974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek 1205974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek DefinedOrUnknownSVal *Constraint = 1215974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek dyn_cast<DefinedOrUnknownSVal>(&Constraint_untested); 122b9bbd592c7ea72ada8d982e40a729beb9b53371eTed Kremenek 1235974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek if (!Constraint) 1245974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek break; 125b9bbd592c7ea72ada8d982e40a729beb9b53371eTed Kremenek 1268bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek if (ProgramStateRef newState = state->assume(*Constraint, true)) 1275974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek state = newState; 12852e5602056e4cade24cbcca57767e94e1d430b03Ted Kremenek } 129a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek break; 130a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek } 131a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek while (0); 132a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek 133a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) { 134a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek // Precondition: 'self' is always non-null upon entry to an Objective-C 135a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek // method. 136a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek const ImplicitParamDecl *SelfD = MD->getSelfDecl(); 137a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek const MemRegion *R = state->getRegion(SelfD, InitLoc); 138a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek SVal V = state->getSVal(loc::MemRegionVal(R)); 139a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek 140a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek if (const Loc *LV = dyn_cast<Loc>(&V)) { 141a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek // Assume that the pointer value in 'self' is non-null. 142a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek state = state->assume(*LV, true); 143a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek assert(state && "'self' cannot be null"); 144a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek } 145a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek } 1465974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek 147a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) { 148a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek if (!MD->isStatic()) { 149a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek // Precondition: 'this' is always non-null upon entry to the 150a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek // top-level function. This is our starting assumption for 151a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek // analyzing an "open" program. 152a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek const StackFrameContext *SFC = InitLoc->getCurrentStackFrame(); 153a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek if (SFC->getParent() == 0) { 15410f77ad7fc5e5cf3f37a9b14ff5843468b8b84d2Ted Kremenek loc::MemRegionVal L = svalBuilder.getCXXThis(MD, SFC); 155a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek SVal V = state->getSVal(L); 156a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek if (const Loc *LV = dyn_cast<Loc>(&V)) { 157a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek state = state->assume(*LV, true); 158a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek assert(state && "'this' cannot be null"); 159a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek } 1605974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek } 161cfcd7fd0de701c5ce05e96de1ed2d0bf8c7035d9Ted Kremenek } 162a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek } 163a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek 16452e5602056e4cade24cbcca57767e94e1d430b03Ted Kremenek return state; 165e070a1df66aab6d4168fb28f7559fdf996df3567Ted Kremenek} 166e070a1df66aab6d4168fb28f7559fdf996df3567Ted Kremenek 167f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose/// If the value of the given expression is a NonLoc, copy it into a new 168f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose/// temporary region, and replace the value of the expression with that. 169f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rosestatic ProgramStateRef createTemporaryRegionIfNeeded(ProgramStateRef State, 170f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose const LocationContext *LC, 171f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose const Expr *E) { 172f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose SVal V = State->getSVal(E, LC); 173f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose 174f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose if (isa<NonLoc>(V)) { 175f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose MemRegionManager &MRMgr = State->getStateManager().getRegionManager(); 176f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose const MemRegion *R = MRMgr.getCXXTempObjectRegion(E, LC); 177f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose State = State->bindLoc(loc::MemRegionVal(R), V); 178f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose State = State->BindExpr(E, LC, loc::MemRegionVal(R)); 179f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose } 180f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose 181f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose return State; 182f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose} 183f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose 184e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek//===----------------------------------------------------------------------===// 185e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek// Top-level transfer function logic (Dispatcher). 186e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek//===----------------------------------------------------------------------===// 187e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek 1889c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek/// evalAssume - Called by ConstraintManager. Used to call checker-specific 18932a58084a4c53e6938dd81bfce224db25a5976d1Ted Kremenek/// logic for handling assumptions on symbolic values. 1908bef8238181a30e52dea380789a7e2d760eac532Ted KremenekProgramStateRef ExprEngine::processAssume(ProgramStateRef state, 191fe27971d54d26997149d6b84057f04ff398d1d5dJordy Rose SVal cond, bool assumption) { 192fe27971d54d26997149d6b84057f04ff398d1d5dJordy Rose return getCheckerManager().runCheckersForEvalAssume(state, cond, assumption); 19332a58084a4c53e6938dd81bfce224db25a5976d1Ted Kremenek} 19432a58084a4c53e6938dd81bfce224db25a5976d1Ted Kremenek 1958bef8238181a30e52dea380789a7e2d760eac532Ted Kremenekbool ExprEngine::wantsRegionChangeUpdate(ProgramStateRef state) { 196183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis return getCheckerManager().wantsRegionChangeUpdate(state); 197c2b7dfaad674587cfd220ff447b3710d252130c3Jordy Rose} 198c2b7dfaad674587cfd220ff447b3710d252130c3Jordy Rose 1998bef8238181a30e52dea380789a7e2d760eac532Ted KremenekProgramStateRef 2008bef8238181a30e52dea380789a7e2d760eac532Ted KremenekExprEngine::processRegionChanges(ProgramStateRef state, 20135bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek const StoreManager::InvalidatedSymbols *invalidated, 202537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose ArrayRef<const MemRegion *> Explicits, 20366c40400e7d6272b0cd675ada18dd62c1f0362c7Anna Zaks ArrayRef<const MemRegion *> Regions, 204740d490593e0de8732a697c9f77b90ddd463863bJordan Rose const CallEvent *Call) { 20535bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek return getCheckerManager().runCheckersForRegionChanges(state, invalidated, 20666c40400e7d6272b0cd675ada18dd62c1f0362c7Anna Zaks Explicits, Regions, Call); 207c2b7dfaad674587cfd220ff447b3710d252130c3Jordy Rose} 208c2b7dfaad674587cfd220ff447b3710d252130c3Jordy Rose 2098bef8238181a30e52dea380789a7e2d760eac532Ted Kremenekvoid ExprEngine::printState(raw_ostream &Out, ProgramStateRef State, 210dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose const char *NL, const char *Sep) { 211dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose getCheckerManager().runCheckersForPrintState(Out, State, NL, Sep); 212dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose} 213dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose 214e36de1fe51c39d9161915dd3dbef880954af6476Ted Kremenekvoid ExprEngine::processEndWorklist(bool hasWorkRemaining) { 21530726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis getCheckerManager().runCheckersForEndAnalysis(G, BR, *this); 216ccc263b44c62ce3a02f797a3ddb3d6017cf0e5e4Ted Kremenek} 217ccc263b44c62ce3a02f797a3ddb3d6017cf0e5e4Ted Kremenek 218ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaksvoid ExprEngine::processCFGElement(const CFGElement E, ExplodedNode *Pred, 219ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks unsigned StmtIdx, NodeBuilderContext *Ctx) { 22066c486f275531df6362b3511fc3af6563561801bTed Kremenek currStmtIdx = StmtIdx; 22166c486f275531df6362b3511fc3af6563561801bTed Kremenek currBldrCtx = Ctx; 222ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks 2239c6cd67ea416bace666d614c84d5531124287653Zhongxing Xu switch (E.getKind()) { 2243c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek case CFGElement::Invalid: 2253c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek llvm_unreachable("Unexpected CFGElement kind."); 2263c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek case CFGElement::Statement: 227ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks ProcessStmt(const_cast<Stmt*>(E.getAs<CFGStmt>()->getStmt()), Pred); 2283c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek return; 2293c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek case CFGElement::Initializer: 230ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks ProcessInitializer(E.getAs<CFGInitializer>()->getInitializer(), Pred); 2313c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek return; 2323c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek case CFGElement::AutomaticObjectDtor: 2333c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek case CFGElement::BaseDtor: 2343c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek case CFGElement::MemberDtor: 2353c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek case CFGElement::TemporaryDtor: 236ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks ProcessImplicitDtor(*E.getAs<CFGImplicitDtor>(), Pred); 2373c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek return; 2389c6cd67ea416bace666d614c84d5531124287653Zhongxing Xu } 23966c486f275531df6362b3511fc3af6563561801bTed Kremenek currBldrCtx = 0; 2409c6cd67ea416bace666d614c84d5531124287653Zhongxing Xu} 2419c6cd67ea416bace666d614c84d5531124287653Zhongxing Xu 242ce117a7d289f57f792e5cc3294280cfe070433deTed Kremenekstatic bool shouldRemoveDeadBindings(AnalysisManager &AMgr, 243ce117a7d289f57f792e5cc3294280cfe070433deTed Kremenek const CFGStmt S, 244ce117a7d289f57f792e5cc3294280cfe070433deTed Kremenek const ExplodedNode *Pred, 245ce117a7d289f57f792e5cc3294280cfe070433deTed Kremenek const LocationContext *LC) { 246ce117a7d289f57f792e5cc3294280cfe070433deTed Kremenek 247ce117a7d289f57f792e5cc3294280cfe070433deTed Kremenek // Are we never purging state values? 248255d4d4226b24036ceb11228fbb74286e58620f7Ted Kremenek if (AMgr.options.AnalysisPurgeOpt == PurgeNone) 249ce117a7d289f57f792e5cc3294280cfe070433deTed Kremenek return false; 250ce117a7d289f57f792e5cc3294280cfe070433deTed Kremenek 251ce117a7d289f57f792e5cc3294280cfe070433deTed Kremenek // Is this the beginning of a basic block? 2529e9a3e612d57b583800d5f0e48bb28d4afbd8b84Ted Kremenek if (isa<BlockEntrance>(Pred->getLocation())) 253ce117a7d289f57f792e5cc3294280cfe070433deTed Kremenek return true; 254ce117a7d289f57f792e5cc3294280cfe070433deTed Kremenek 255ce117a7d289f57f792e5cc3294280cfe070433deTed Kremenek // Is this on a non-expression? 256ce117a7d289f57f792e5cc3294280cfe070433deTed Kremenek if (!isa<Expr>(S.getStmt())) 257ce117a7d289f57f792e5cc3294280cfe070433deTed Kremenek return true; 258ff80afcfb2b00ccffcb6cb10528bec565fc59eddAnna Zaks 259ff80afcfb2b00ccffcb6cb10528bec565fc59eddAnna Zaks // Run before processing a call. 2606062334cc388bce69fb3978c4ecb26c6485a5c2bJordan Rose if (CallEvent::isCallStmt(S.getStmt())) 261ff80afcfb2b00ccffcb6cb10528bec565fc59eddAnna Zaks return true; 262ff80afcfb2b00ccffcb6cb10528bec565fc59eddAnna Zaks 263ce117a7d289f57f792e5cc3294280cfe070433deTed Kremenek // Is this an expression that is consumed by another expression? If so, 264ce117a7d289f57f792e5cc3294280cfe070433deTed Kremenek // postpone cleaning out the state. 265ce117a7d289f57f792e5cc3294280cfe070433deTed Kremenek ParentMap &PM = LC->getAnalysisDeclContext()->getParentMap(); 266ce117a7d289f57f792e5cc3294280cfe070433deTed Kremenek return !PM.isConsumedExpr(cast<Expr>(S.getStmt())); 267ce117a7d289f57f792e5cc3294280cfe070433deTed Kremenek} 268ce117a7d289f57f792e5cc3294280cfe070433deTed Kremenek 2690b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaksvoid ExprEngine::removeDead(ExplodedNode *Pred, ExplodedNodeSet &Out, 2700b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks const Stmt *ReferenceStmt, 2710b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks const LocationContext *LC, 2720b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks const Stmt *DiagnosticStmt, 2730b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks ProgramPoint::Kind K) { 2740b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks assert((K == ProgramPoint::PreStmtPurgeDeadSymbolsKind || 2750b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks ReferenceStmt == 0) && "PreStmt is not generally supported by " 2760b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks "the SymbolReaper yet"); 2770b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks NumRemoveDeadBindings++; 2780b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks CleanedState = Pred->getState(); 2790b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks SymbolReaper SymReaper(LC, ReferenceStmt, SymMgr, getStoreManager()); 2800b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks 2810b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks getCheckerManager().runCheckersForLiveSymbols(CleanedState, SymReaper); 2820b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks 2830b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks // Create a state in which dead bindings are removed from the environment 2840b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks // and the store. TODO: The function should just return new env and store, 2850b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks // not a new state. 2860b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks const StackFrameContext *SFC = LC->getCurrentStackFrame(); 2870b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks CleanedState = StateMgr.removeDeadBindings(CleanedState, SFC, SymReaper); 288241677a13cc46647a8f5098b3e3239bd9480dca2Ted Kremenek 28977d7ef8d8a80ccb2ab3d25c80810571e3ab14ee4Ted Kremenek // Process any special transfer function for dead symbols. 290f185cc1ac77a84139c603eee3473b88dcb839c68Anna Zaks // A tag to track convenience transitions, which can be removed at cleanup. 291f185cc1ac77a84139c603eee3473b88dcb839c68Anna Zaks static SimpleProgramPointTag cleanupTag("ExprEngine : Clean Node"); 2926bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks if (!SymReaper.hasDeadSymbols()) { 2936bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks // Generate a CleanedNode that has the environment and store cleaned 2946bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks // up. Since no symbols are dead, we can optimize and not clean out 2956bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks // the constraint manager. 29666c486f275531df6362b3511fc3af6563561801bTed Kremenek StmtNodeBuilder Bldr(Pred, Out, *currBldrCtx); 297fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose Bldr.generateNode(DiagnosticStmt, Pred, CleanedState, &cleanupTag, K); 2981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2996bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks } else { 3006bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks // Call checkers with the non-cleaned state so that they could query the 3016bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks // values of the soon to be dead symbols. 302fe27971d54d26997149d6b84057f04ff398d1d5dJordy Rose ExplodedNodeSet CheckedSet; 3030b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks getCheckerManager().runCheckersForDeadSymbols(CheckedSet, Pred, SymReaper, 3040b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks DiagnosticStmt, *this, K); 305183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis 306fe27971d54d26997149d6b84057f04ff398d1d5dJordy Rose // For each node in CheckedSet, generate CleanedNodes that have the 307fe27971d54d26997149d6b84057f04ff398d1d5dJordy Rose // environment, the store, and the constraints cleaned up but have the 308fe27971d54d26997149d6b84057f04ff398d1d5dJordy Rose // user-supplied states as the predecessors. 30966c486f275531df6362b3511fc3af6563561801bTed Kremenek StmtNodeBuilder Bldr(CheckedSet, Out, *currBldrCtx); 310fe27971d54d26997149d6b84057f04ff398d1d5dJordy Rose for (ExplodedNodeSet::const_iterator 311fe27971d54d26997149d6b84057f04ff398d1d5dJordy Rose I = CheckedSet.begin(), E = CheckedSet.end(); I != E; ++I) { 3128bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek ProgramStateRef CheckerState = (*I)->getState(); 3136bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks 3146bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks // The constraint manager has not been cleaned up yet, so clean up now. 3156bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks CheckerState = getConstraintManager().removeDeadBindings(CheckerState, 3166bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks SymReaper); 3176bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks 3180b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks assert(StateMgr.haveEqualEnvironments(CheckerState, Pred->getState()) && 3196bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks "Checkers are not allowed to modify the Environment as a part of " 3206bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks "checkDeadSymbols processing."); 3210b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks assert(StateMgr.haveEqualStores(CheckerState, Pred->getState()) && 3226bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks "Checkers are not allowed to modify the Store as a part of " 3236bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks "checkDeadSymbols processing."); 3246bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks 3256bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks // Create a state based on CleanedState with CheckerState GDM and 3266bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks // generate a transition to that state. 3278bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek ProgramStateRef CleanedCheckerSt = 3286bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks StateMgr.getPersistentStateWithGDM(CleanedState, CheckerState); 329fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose Bldr.generateNode(DiagnosticStmt, *I, CleanedCheckerSt, &cleanupTag, K); 3306bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks } 33177d7ef8d8a80ccb2ab3d25c80810571e3ab14ee4Ted Kremenek } 3320b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks} 3330b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks 3340b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaksvoid ExprEngine::ProcessStmt(const CFGStmt S, 3350b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks ExplodedNode *Pred) { 3360b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks // Reclaim any unnecessary nodes in the ExplodedGraph. 3370b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks G.reclaimRecentlyAllocatedNodes(); 3380b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks 33966c486f275531df6362b3511fc3af6563561801bTed Kremenek currStmt = S.getStmt(); 3400b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(), 34166c486f275531df6362b3511fc3af6563561801bTed Kremenek currStmt->getLocStart(), 3420b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks "Error evaluating statement"); 3431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3440b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks // Remove dead bindings and symbols. 3450b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks EntryNode = Pred; 3460b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks ExplodedNodeSet CleanedStates; 3470b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks if (shouldRemoveDeadBindings(AMgr, S, Pred, EntryNode->getLocationContext())){ 34866c486f275531df6362b3511fc3af6563561801bTed Kremenek removeDead(EntryNode, CleanedStates, currStmt, 34966c486f275531df6362b3511fc3af6563561801bTed Kremenek Pred->getLocationContext(), currStmt); 3500b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks } else 3510b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks CleanedStates.Add(EntryNode); 3520b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks 3530b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks // Visit the statement. 354dd7ddf2b2296f95e7591ca3f9791f0eb9a15ee42Anna Zaks ExplodedNodeSet Dst; 3550b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks for (ExplodedNodeSet::iterator I = CleanedStates.begin(), 3560b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks E = CleanedStates.end(); I != E; ++I) { 357dd7ddf2b2296f95e7591ca3f9791f0eb9a15ee42Anna Zaks ExplodedNodeSet DstI; 3581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // Visit the statement. 35966c486f275531df6362b3511fc3af6563561801bTed Kremenek Visit(currStmt, *I, DstI); 360dd7ddf2b2296f95e7591ca3f9791f0eb9a15ee42Anna Zaks Dst.insert(DstI); 361ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks } 362ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks 363dd7ddf2b2296f95e7591ca3f9791f0eb9a15ee42Anna Zaks // Enqueue the new nodes onto the work list. 36466c486f275531df6362b3511fc3af6563561801bTed Kremenek Engine.enqueue(Dst, currBldrCtx->getBlock(), currStmtIdx); 3651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 366e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek // NULL out these variables to cleanup. 367846d4e923bf11bcdc2816758aafa331795f29230Ted Kremenek CleanedState = NULL; 368846d4e923bf11bcdc2816758aafa331795f29230Ted Kremenek EntryNode = NULL; 36966c486f275531df6362b3511fc3af6563561801bTed Kremenek currStmt = 0; 370e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek} 371e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek 372d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisvoid ExprEngine::ProcessInitializer(const CFGInitializer Init, 373056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks ExplodedNode *Pred) { 374cbb67480094b3bcb5b715acd827cbad55e2a204cSean Hunt const CXXCtorInitializer *BMI = Init.getInitializer(); 375563ea2335d7d0df44bbfe8941f64523e8af1fc14Jordan Rose 376563ea2335d7d0df44bbfe8941f64523e8af1fc14Jordan Rose PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(), 377563ea2335d7d0df44bbfe8941f64523e8af1fc14Jordan Rose BMI->getSourceLocation(), 378563ea2335d7d0df44bbfe8941f64523e8af1fc14Jordan Rose "Error evaluating initializer"); 379563ea2335d7d0df44bbfe8941f64523e8af1fc14Jordan Rose 38066c486f275531df6362b3511fc3af6563561801bTed Kremenek // We don't set EntryNode and currStmt. And we don't clean up state. 381056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks const StackFrameContext *stackFrame = 382056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks cast<StackFrameContext>(Pred->getLocationContext()); 383056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks const CXXConstructorDecl *decl = 384056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks cast<CXXConstructorDecl>(stackFrame->getDecl()); 3853682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose 3863682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose ProgramStateRef State = Pred->getState(); 3873a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose SVal thisVal = State->getSVal(svalBuilder.getCXXThis(decl, stackFrame)); 3889dc84c9455df2a77195147d0210c915dc1775a88Zhongxing Xu 3893682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose PostInitializer PP(BMI, stackFrame); 3903682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose ExplodedNodeSet Tmp(Pred); 3913682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose 3923a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose // Evaluate the initializer, if necessary 39300eb3f9c5b33e3d99aee1f8b75dd9c9678fdd66bFrancois Pichet if (BMI->isAnyMemberInitializer()) { 3943a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose // Constructors build the object directly in the field, 3953a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose // but non-objects must be copied in from the initializer. 3963682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose const Expr *Init = BMI->getInit(); 3973682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose if (!isa<CXXConstructExpr>(Init)) { 3983a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose SVal FieldLoc; 3993a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose if (BMI->isIndirectMemberInitializer()) 4003a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose FieldLoc = State->getLValue(BMI->getIndirectMember(), thisVal); 4013a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose else 4023a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose FieldLoc = State->getLValue(BMI->getMember(), thisVal); 4033a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose 4043a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose SVal InitVal = State->getSVal(BMI->getInit(), stackFrame); 4053682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose 4063682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose Tmp.clear(); 4073682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose evalBind(Tmp, Init, Pred, FieldLoc, InitVal, /*isInit=*/true, &PP); 4083a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose } 409056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks } else { 410563ea2335d7d0df44bbfe8941f64523e8af1fc14Jordan Rose assert(BMI->isBaseInitializer() || BMI->isDelegatingInitializer()); 411888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose // We already did all the work when visiting the CXXConstructExpr. 412056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks } 413dd7ddf2b2296f95e7591ca3f9791f0eb9a15ee42Anna Zaks 4143682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose // Construct PostInitializer nodes whether the state changed or not, 4153a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose // so that the diagnostics don't get confused. 4163682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose ExplodedNodeSet Dst; 4173682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose NodeBuilder Bldr(Tmp, Dst, *currBldrCtx); 4183682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose for (ExplodedNodeSet::iterator I = Tmp.begin(), E = Tmp.end(); I != E; ++I) { 4193682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose ExplodedNode *N = *I; 4203682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose Bldr.generateNode(PP, N->getState(), N); 4213682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose } 4223a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose 423dd7ddf2b2296f95e7591ca3f9791f0eb9a15ee42Anna Zaks // Enqueue the new nodes onto the work list. 42466c486f275531df6362b3511fc3af6563561801bTed Kremenek Engine.enqueue(Dst, currBldrCtx->getBlock(), currStmtIdx); 4259c6cd67ea416bace666d614c84d5531124287653Zhongxing Xu} 4269c6cd67ea416bace666d614c84d5531124287653Zhongxing Xu 427d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisvoid ExprEngine::ProcessImplicitDtor(const CFGImplicitDtor D, 428ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks ExplodedNode *Pred) { 429ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks ExplodedNodeSet Dst; 4303c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek switch (D.getKind()) { 4314ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu case CFGElement::AutomaticObjectDtor: 432056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks ProcessAutomaticObjDtor(cast<CFGAutomaticObjDtor>(D), Pred, Dst); 4334ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu break; 4344ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu case CFGElement::BaseDtor: 435056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks ProcessBaseDtor(cast<CFGBaseDtor>(D), Pred, Dst); 4364ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu break; 4374ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu case CFGElement::MemberDtor: 438056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks ProcessMemberDtor(cast<CFGMemberDtor>(D), Pred, Dst); 4394ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu break; 4404ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu case CFGElement::TemporaryDtor: 441056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks ProcessTemporaryDtor(cast<CFGTemporaryDtor>(D), Pred, Dst); 4424ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu break; 4434ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu default: 4444ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu llvm_unreachable("Unexpected dtor kind."); 4454ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu } 446ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks 447dd7ddf2b2296f95e7591ca3f9791f0eb9a15ee42Anna Zaks // Enqueue the new nodes onto the work list. 44866c486f275531df6362b3511fc3af6563561801bTed Kremenek Engine.enqueue(Dst, currBldrCtx->getBlock(), currStmtIdx); 4494ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu} 4504ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu 451056c4b46335a3bd2612414735d5749ee159c0165Anna Zaksvoid ExprEngine::ProcessAutomaticObjDtor(const CFGAutomaticObjDtor Dtor, 452056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks ExplodedNode *Pred, 453056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks ExplodedNodeSet &Dst) { 4548bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek ProgramStateRef state = Pred->getState(); 455056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks const VarDecl *varDecl = Dtor.getVarDecl(); 4562210490e6d099b7a5b4f68f44a136e4dcf3cdea2Zhongxing Xu 4572210490e6d099b7a5b4f68f44a136e4dcf3cdea2Zhongxing Xu QualType varType = varDecl->getType(); 4582210490e6d099b7a5b4f68f44a136e4dcf3cdea2Zhongxing Xu 4592210490e6d099b7a5b4f68f44a136e4dcf3cdea2Zhongxing Xu if (const ReferenceType *refType = varType->getAs<ReferenceType>()) 4602210490e6d099b7a5b4f68f44a136e4dcf3cdea2Zhongxing Xu varType = refType->getPointeeType(); 4612210490e6d099b7a5b4f68f44a136e4dcf3cdea2Zhongxing Xu 462056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks Loc dest = state->getLValue(varDecl, Pred->getLocationContext()); 463b13453bd8a91f331d0910ca95ad52aa41b52f648Zhongxing Xu 464888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose VisitCXXDestructor(varType, cast<loc::MemRegionVal>(dest).getRegion(), 465200fa2e70d52ae6d620e81cd45536071fdde70c0Jordan Rose Dtor.getTriggerStmt(), /*IsBase=*/false, Pred, Dst); 4664ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu} 4674ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu 468d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisvoid ExprEngine::ProcessBaseDtor(const CFGBaseDtor D, 469888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose ExplodedNode *Pred, ExplodedNodeSet &Dst) { 470888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose const LocationContext *LCtx = Pred->getLocationContext(); 471888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose ProgramStateRef State = Pred->getState(); 472888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose 473888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose const CXXDestructorDecl *CurDtor = cast<CXXDestructorDecl>(LCtx->getDecl()); 474888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose Loc ThisPtr = getSValBuilder().getCXXThis(CurDtor, 475888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose LCtx->getCurrentStackFrame()); 476888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose SVal ThisVal = Pred->getState()->getSVal(ThisPtr); 477888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose 478888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose // Create the base object region. 479888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose QualType BaseTy = D.getBaseSpecifier()->getType(); 480888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose SVal BaseVal = getStoreManager().evalDerivedToBase(ThisVal, BaseTy); 481888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose 482888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose VisitCXXDestructor(BaseTy, cast<loc::MemRegionVal>(BaseVal).getRegion(), 483200fa2e70d52ae6d620e81cd45536071fdde70c0Jordan Rose CurDtor->getBody(), /*IsBase=*/true, Pred, Dst); 484888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose} 4854ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu 486d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisvoid ExprEngine::ProcessMemberDtor(const CFGMemberDtor D, 4873a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose ExplodedNode *Pred, ExplodedNodeSet &Dst) { 4883a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose const FieldDecl *Member = D.getFieldDecl(); 4893a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose ProgramStateRef State = Pred->getState(); 4903a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose const LocationContext *LCtx = Pred->getLocationContext(); 4913a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose 4923a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose const CXXDestructorDecl *CurDtor = cast<CXXDestructorDecl>(LCtx->getDecl()); 4933a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose Loc ThisVal = getSValBuilder().getCXXThis(CurDtor, 4943a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose LCtx->getCurrentStackFrame()); 4953a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose SVal FieldVal = State->getLValue(Member, cast<Loc>(State->getSVal(ThisVal))); 4963a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose 4973a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose VisitCXXDestructor(Member->getType(), 4983a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose cast<loc::MemRegionVal>(FieldVal).getRegion(), 499200fa2e70d52ae6d620e81cd45536071fdde70c0Jordan Rose CurDtor->getBody(), /*IsBase=*/false, Pred, Dst); 5003a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose} 5014ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu 502d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisvoid ExprEngine::ProcessTemporaryDtor(const CFGTemporaryDtor D, 503056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks ExplodedNode *Pred, 504056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks ExplodedNodeSet &Dst) {} 5059c6cd67ea416bace666d614c84d5531124287653Zhongxing Xu 50648b6247804eacc262cc5508e0fbb74ed819fbb6eJordan Rosevoid ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred, 5076889679d72859960e0fc8d1080487f63c4df1e0aAnna Zaks ExplodedNodeSet &DstTop) { 5080bed8a12f2878d3cd94fb8bdba55b593d92dd11aTed Kremenek PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(), 5090bed8a12f2878d3cd94fb8bdba55b593d92dd11aTed Kremenek S->getLocStart(), 5100bed8a12f2878d3cd94fb8bdba55b593d92dd11aTed Kremenek "Error evaluating statement"); 5116889679d72859960e0fc8d1080487f63c4df1e0aAnna Zaks ExplodedNodeSet Dst; 51266c486f275531df6362b3511fc3af6563561801bTed Kremenek StmtNodeBuilder Bldr(Pred, DstTop, *currBldrCtx); 5130bed8a12f2878d3cd94fb8bdba55b593d92dd11aTed Kremenek 514f6a1648197562e0b133440d612d9af297d0a86ccJohn McCall // Expressions to ignore. 515f6a1648197562e0b133440d612d9af297d0a86ccJohn McCall if (const Expr *Ex = dyn_cast<Expr>(S)) 516892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek S = Ex->IgnoreParens(); 517f6a1648197562e0b133440d612d9af297d0a86ccJohn McCall 518e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek // FIXME: add metadata to the CFG so that we can disable 519e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek // this check when we KNOW that there is no block-level subexpression. 520e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek // The motivation is that this check requires a hashtable lookup. 5211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 52266c486f275531df6362b3511fc3af6563561801bTed Kremenek if (S != currStmt && Pred->getLocationContext()->getCFG()->isBlkExpr(S)) 523e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek return; 5241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 525e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek switch (S->getStmtClass()) { 526f85e193739c953358c865005855253af4f68a497John McCall // C++ and ARC stuff we don't support yet. 527f85e193739c953358c865005855253af4f68a497John McCall case Expr::ObjCIndirectCopyRestoreExprClass: 5281b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::CXXDependentScopeMemberExprClass: 5291b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::CXXPseudoDestructorExprClass: 5301b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::CXXTryStmtClass: 5311b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::CXXTypeidExprClass: 5329be88403e965cc49af76c9d33d818781d44b333eFrancois Pichet case Stmt::CXXUuidofExprClass: 533c768a0c46e6c064c3281d663777ee95aea8652eeTed Kremenek case Stmt::CXXUnresolvedConstructExprClass: 5341b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::DependentScopeDeclRefExprClass: 5351b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::UnaryTypeTraitExprClass: 5366ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet case Stmt::BinaryTypeTraitExprClass: 5374ca8ac2e61c37ddadf37024af86f3e1019af8532Douglas Gregor case Stmt::TypeTraitExprClass: 53821ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley case Stmt::ArrayTypeTraitExprClass: 539552622067dc45013d240f73952fece703f5e63bdJohn Wiegley case Stmt::ExpressionTraitExprClass: 5401b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::UnresolvedLookupExprClass: 541c768a0c46e6c064c3281d663777ee95aea8652eeTed Kremenek case Stmt::UnresolvedMemberExprClass: 5426b219d082434394c1ac401390ec1d1967727815aSebastian Redl case Stmt::CXXNoexceptExprClass: 543be230c36e32142cbdcdbe9c97511d097beeecbabDouglas Gregor case Stmt::PackExpansionExprClass: 544c7793c73ba8a343de3f2552d984851985a46f159Douglas Gregor case Stmt::SubstNonTypeTemplateParmPackExprClass: 5459a4db032ecd991626d236a502e770126db32bd31Richard Smith case Stmt::FunctionParmPackExprClass: 54628bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley case Stmt::SEHTryStmtClass: 54728bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley case Stmt::SEHExceptStmtClass: 54801d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor case Stmt::LambdaExprClass: 549ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks case Stmt::SEHFinallyStmtClass: { 550fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose const ExplodedNode *node = Bldr.generateSink(S, Pred, Pred->getState()); 55166c486f275531df6362b3511fc3af6563561801bTed Kremenek Engine.addAbortedBlock(node, currBldrCtx->getBlock()); 552c768a0c46e6c064c3281d663777ee95aea8652eeTed Kremenek break; 553c768a0c46e6c064c3281d663777ee95aea8652eeTed Kremenek } 5545fe98728dca1f3a7a378ce1a21984a0f8a0c0b8bTed Kremenek 555f6a1648197562e0b133440d612d9af297d0a86ccJohn McCall case Stmt::ParenExprClass: 556f6a1648197562e0b133440d612d9af297d0a86ccJohn McCall llvm_unreachable("ParenExprs already handled."); 557f111d935722ed488144600cea5ed03a6b5069e8fPeter Collingbourne case Stmt::GenericSelectionExprClass: 558f111d935722ed488144600cea5ed03a6b5069e8fPeter Collingbourne llvm_unreachable("GenericSelectionExprs already handled."); 5591b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek // Cases that should never be evaluated simply because they shouldn't 5601b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek // appear in the CFG. 5611b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::BreakStmtClass: 5621b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::CaseStmtClass: 5631b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::CompoundStmtClass: 5641b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::ContinueStmtClass: 56546eaf7789a1059a7b42b7dbd183150c72df5738fTed Kremenek case Stmt::CXXForRangeStmtClass: 5661b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::DefaultStmtClass: 5671b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::DoStmtClass: 568d40066b0fb883839a9100e5455e33190b9b8abacTed Kremenek case Stmt::ForStmtClass: 5691b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::GotoStmtClass: 570d40066b0fb883839a9100e5455e33190b9b8abacTed Kremenek case Stmt::IfStmtClass: 5711b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::IndirectGotoStmtClass: 5721b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::LabelStmtClass: 573534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith case Stmt::AttributedStmtClass: 5741b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::NoStmtClass: 5751b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::NullStmtClass: 576d40066b0fb883839a9100e5455e33190b9b8abacTed Kremenek case Stmt::SwitchStmtClass: 577d40066b0fb883839a9100e5455e33190b9b8abacTed Kremenek case Stmt::WhileStmtClass: 578ba0513de93d2fab6db5ab30b6927209fcc883078Douglas Gregor case Expr::MSDependentExistsStmtClass: 5791b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek llvm_unreachable("Stmt should not be in analyzer evaluation loop"); 5801b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek 5814ccc4cc5d4e7c5c436d5f45065d3639cfc7c6e48Jordan Rose case Stmt::ObjCSubscriptRefExprClass: 5824ccc4cc5d4e7c5c436d5f45065d3639cfc7c6e48Jordan Rose case Stmt::ObjCPropertyRefExprClass: 5834ccc4cc5d4e7c5c436d5f45065d3639cfc7c6e48Jordan Rose llvm_unreachable("These are handled by PseudoObjectExpr"); 5844ccc4cc5d4e7c5c436d5f45065d3639cfc7c6e48Jordan Rose 5858ad9cbc518a603176462f1fa1efe389023590082Ted Kremenek case Stmt::GNUNullExprClass: { 5868f08426e6f54ed20b959018f24dbea106a00b4adJordy Rose // GNU __null is a pointer-width integer, not an actual pointer. 5878bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek ProgramStateRef state = Pred->getState(); 5885eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek state = state->BindExpr(S, Pred->getLocationContext(), 5895eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek svalBuilder.makeIntValWithPtrWidth(0, false)); 590ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.generateNode(S, Pred, state); 5918ad9cbc518a603176462f1fa1efe389023590082Ted Kremenek break; 5928ad9cbc518a603176462f1fa1efe389023590082Ted Kremenek } 5938ad9cbc518a603176462f1fa1efe389023590082Ted Kremenek 5944beaa9f51b2da57c64740cef2bd1c2fdb0c325d5Ted Kremenek case Stmt::ObjCAtSynchronizedStmtClass: 595ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 5964beaa9f51b2da57c64740cef2bd1c2fdb0c325d5Ted Kremenek VisitObjCAtSynchronizedStmt(cast<ObjCAtSynchronizedStmt>(S), Pred, Dst); 597ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 5984beaa9f51b2da57c64740cef2bd1c2fdb0c325d5Ted Kremenek break; 5994beaa9f51b2da57c64740cef2bd1c2fdb0c325d5Ted Kremenek 600ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks case Stmt::ExprWithCleanupsClass: 601e711d7e7875920fee4180a26bfc67d67f0f71a2cErik Verbruggen // Handled due to fully linearised CFG. 602f85e193739c953358c865005855253af4f68a497John McCall break; 603f85e193739c953358c865005855253af4f68a497John McCall 6041b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek // Cases not handled yet; but will handle some day. 6051b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::DesignatedInitExprClass: 6061b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::ExtVectorElementExprClass: 6071b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::ImaginaryLiteralClass: 6081b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::ObjCAtCatchStmtClass: 6091b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::ObjCAtFinallyStmtClass: 6101b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::ObjCAtTryStmtClass: 611f85e193739c953358c865005855253af4f68a497John McCall case Stmt::ObjCAutoreleasePoolStmtClass: 6121b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::ObjCEncodeExprClass: 6131b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::ObjCIsaExprClass: 6141b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::ObjCProtocolExprClass: 6151b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::ObjCSelectorExprClass: 6161b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::ParenListExprClass: 6171b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::PredefinedExprClass: 6181b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::ShuffleVectorExprClass: 6191b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::VAArgExprClass: 620e08ce650a2b02410eddd1f60a4aa6b3d4be71e73Peter Collingbourne case Stmt::CUDAKernelCallExprClass: 62156ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall case Stmt::OpaqueValueExprClass: 62261eee0ca33b29e102f11bab77c8b74cc00e2392bTanya Lattner case Stmt::AsTypeExprClass: 623276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman case Stmt::AtomicExprClass: 624337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek // Fall through. 6251b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek 6261b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek // Cases we intentionally don't evaluate, since they don't need 6271b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek // to be explicitly evaluated. 628bc9ad74a13e83303a3a5251f8bacbbca17341c17Zhongxing Xu case Stmt::AddrLabelExprClass: 629bc9ad74a13e83303a3a5251f8bacbbca17341c17Zhongxing Xu case Stmt::IntegerLiteralClass: 630bc9ad74a13e83303a3a5251f8bacbbca17341c17Zhongxing Xu case Stmt::CharacterLiteralClass: 631c319c585c0d5899cba0dca2272e6e4909c8b9f16Ted Kremenek case Stmt::ImplicitValueInitExprClass: 632c319c585c0d5899cba0dca2272e6e4909c8b9f16Ted Kremenek case Stmt::CXXScalarValueInitExprClass: 633477323d58a0de352c6a61e08b5a83127c4adc904Zhongxing Xu case Stmt::CXXBoolLiteralExprClass: 6341a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek case Stmt::ObjCBoolLiteralExprClass: 635bc9ad74a13e83303a3a5251f8bacbbca17341c17Zhongxing Xu case Stmt::FloatingLiteralClass: 636f901a7de97f46ba2b1ff153f9fb83d00dc37cfcfDouglas Gregor case Stmt::SizeOfPackExprClass: 637e739a29c62c67eaec0af5c4d5c75f9e8f11228bdTed Kremenek case Stmt::StringLiteralClass: 638e739a29c62c67eaec0af5c4d5c75f9e8f11228bdTed Kremenek case Stmt::ObjCStringLiteralClass: 639cc2c4b293d8590346f26b7ecc16d299226b8794fTed Kremenek case Stmt::CXXBindTemporaryExprClass: 640b66529d04727dc686b97ea3d937fc9785792f505Jordan Rose case Stmt::CXXDefaultArgExprClass: 64169a0e5021c5c49a34aa25cd89b1e613a52097e65Jordan Rose case Stmt::SubstNonTypeTemplateParmExprClass: 642bdd4c848349d4091d66b052efa453e6d69a77e36Ted Kremenek case Stmt::CXXNullPtrLiteralExprClass: { 643bdd4c848349d4091d66b052efa453e6d69a77e36Ted Kremenek Bldr.takeNodes(Pred); 644bdd4c848349d4091d66b052efa453e6d69a77e36Ted Kremenek ExplodedNodeSet preVisit; 645bdd4c848349d4091d66b052efa453e6d69a77e36Ted Kremenek getCheckerManager().runCheckersForPreStmt(preVisit, Pred, S, *this); 646bdd4c848349d4091d66b052efa453e6d69a77e36Ted Kremenek getCheckerManager().runCheckersForPostStmt(Dst, preVisit, S, *this); 647bdd4c848349d4091d66b052efa453e6d69a77e36Ted Kremenek Bldr.addNodes(Dst); 648e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek break; 649bdd4c848349d4091d66b052efa453e6d69a77e36Ted Kremenek } 6501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 6511a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek case Expr::ObjCArrayLiteralClass: 65270fdbc366da85880aae5baebd3351e993ca05603Jordy Rose case Expr::ObjCDictionaryLiteralClass: 65370fdbc366da85880aae5baebd3351e993ca05603Jordy Rose // FIXME: explicitly model with a region and the actual contents 65470fdbc366da85880aae5baebd3351e993ca05603Jordy Rose // of the container. For now, conjure a symbol. 65570fdbc366da85880aae5baebd3351e993ca05603Jordy Rose case Expr::ObjCBoxedExprClass: { 6561a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek Bldr.takeNodes(Pred); 6571a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek 6581a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek ExplodedNodeSet preVisit; 6591a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek getCheckerManager().runCheckersForPreStmt(preVisit, Pred, S, *this); 6601a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek 6611a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek ExplodedNodeSet Tmp; 66266c486f275531df6362b3511fc3af6563561801bTed Kremenek StmtNodeBuilder Bldr2(preVisit, Tmp, *currBldrCtx); 6631a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek 66470fdbc366da85880aae5baebd3351e993ca05603Jordy Rose const Expr *Ex = cast<Expr>(S); 66570fdbc366da85880aae5baebd3351e993ca05603Jordy Rose QualType resultType = Ex->getType(); 66670fdbc366da85880aae5baebd3351e993ca05603Jordy Rose 6671a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek for (ExplodedNodeSet::iterator it = preVisit.begin(), et = preVisit.end(); 6681a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek it != et; ++it) { 6691a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek ExplodedNode *N = *it; 6701a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek const LocationContext *LCtx = N->getLocationContext(); 6713b1df8bb941a18c4a7256d7cfcbccb9de7e39995Ted Kremenek SVal result = svalBuilder.conjureSymbolVal(0, Ex, LCtx, resultType, 67266c486f275531df6362b3511fc3af6563561801bTed Kremenek currBldrCtx->blockCount()); 6731a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek ProgramStateRef state = N->getState()->BindExpr(Ex, LCtx, result); 6741a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek Bldr2.generateNode(S, N, state); 6751a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek } 6761a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek 6771a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek getCheckerManager().runCheckersForPostStmt(Dst, Tmp, S, *this); 6781a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek Bldr.addNodes(Dst); 6791a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek break; 6801a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek } 6811a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek 682540cbe2b60294fe7b926c26b4f1840f544fe3011Ted Kremenek case Stmt::ArraySubscriptExprClass: 683ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 684892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek VisitLvalArraySubscriptExpr(cast<ArraySubscriptExpr>(S), Pred, Dst); 685ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 686540cbe2b60294fe7b926c26b4f1840f544fe3011Ted Kremenek break; 6871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 688df5faf5e7ae6823d0af0b801c4ac26d47f2cee97Chad Rosier case Stmt::GCCAsmStmtClass: 689ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 690df5faf5e7ae6823d0af0b801c4ac26d47f2cee97Chad Rosier VisitGCCAsmStmt(cast<GCCAsmStmt>(S), Pred, Dst); 691ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 692e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek break; 693b9bbd592c7ea72ada8d982e40a729beb9b53371eTed Kremenek 6948cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier case Stmt::MSAsmStmtClass: 6958cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier Bldr.takeNodes(Pred); 6968cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier VisitMSAsmStmt(cast<MSAsmStmt>(S), Pred, Dst); 6978cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier Bldr.addNodes(Dst); 6988cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier break; 6998cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier 700c95ad9ff6e574aecdd759542d5578bc65d586d93Ted Kremenek case Stmt::BlockExprClass: 701ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 702c95ad9ff6e574aecdd759542d5578bc65d586d93Ted Kremenek VisitBlockExpr(cast<BlockExpr>(S), Pred, Dst); 703ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 704c95ad9ff6e574aecdd759542d5578bc65d586d93Ted Kremenek break; 705c95ad9ff6e574aecdd759542d5578bc65d586d93Ted Kremenek 706e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek case Stmt::BinaryOperatorClass: { 70703509aea098772644bf4662dc1c88634818ceeccZhongxing Xu const BinaryOperator* B = cast<BinaryOperator>(S); 708e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek if (B->isLogicalOp()) { 709ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 710e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek VisitLogicalExpr(B, Pred, Dst); 711ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 712e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek break; 713e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek } 7142de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall else if (B->getOpcode() == BO_Comma) { 7158bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek ProgramStateRef state = Pred->getState(); 716ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.generateNode(B, Pred, 7175eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek state->BindExpr(B, Pred->getLocationContext(), 7185eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek state->getSVal(B->getRHS(), 7195eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek Pred->getLocationContext()))); 720e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek break; 721e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek } 72206fb99fb403bff1651429923f666a2ebe2b1522fTed Kremenek 723ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 724ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks 7250caa2d47b84337e942b3f6652adfafe4ae506cfeTed Kremenek if (AMgr.options.eagerlyAssumeBinOpBifurcation && 726bb141217871e93767aa3f2de1b9946fa6d37066aZhongxing Xu (B->isRelationalOp() || B->isEqualityOp())) { 727031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu ExplodedNodeSet Tmp; 728892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Tmp); 7290caa2d47b84337e942b3f6652adfafe4ae506cfeTed Kremenek evalEagerlyAssumeBinOpBifurcation(Dst, Tmp, cast<Expr>(S)); 73048af2a9c1ed3259512f2d1431720add1fbe8fb5fTed Kremenek } 73148af2a9c1ed3259512f2d1431720add1fbe8fb5fTed Kremenek else 732892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Dst); 73348af2a9c1ed3259512f2d1431720add1fbe8fb5fTed Kremenek 734ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 735e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek break; 736e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek } 73706fb99fb403bff1651429923f666a2ebe2b1522fTed Kremenek 738f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose case Stmt::CXXOperatorCallExprClass: { 739f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose const CXXOperatorCallExpr *OCE = cast<CXXOperatorCallExpr>(S); 740f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose 741f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose // For instance method operators, make sure the 'this' argument has a 742f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose // valid region. 743f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose const Decl *Callee = OCE->getCalleeDecl(); 744f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose if (const CXXMethodDecl *MD = dyn_cast_or_null<CXXMethodDecl>(Callee)) { 745f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose if (MD->isInstance()) { 746f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose ProgramStateRef State = Pred->getState(); 747f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose const LocationContext *LCtx = Pred->getLocationContext(); 748f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose ProgramStateRef NewState = 749f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose createTemporaryRegionIfNeeded(State, LCtx, OCE->getArg(0)); 750f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose if (NewState != State) 751f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose Pred = Bldr.generateNode(OCE, Pred, NewState, /*Tag=*/0, 752f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose ProgramPoint::PreStmtKind); 753f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose } 754f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose } 755f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose // FALLTHROUGH 756f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose } 757b277159055933e610bbc80262b600d3ad7e0595cTed Kremenek case Stmt::CallExprClass: 7589fcce65e7e1307b5b8da9be13e4092d6bb94dc1dRichard Smith case Stmt::CXXMemberCallExprClass: 7599fcce65e7e1307b5b8da9be13e4092d6bb94dc1dRichard Smith case Stmt::UserDefinedLiteralClass: { 760ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 761b277159055933e610bbc80262b600d3ad7e0595cTed Kremenek VisitCallExpr(cast<CallExpr>(S), Pred, Dst); 762ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 76306fb99fb403bff1651429923f666a2ebe2b1522fTed Kremenek break; 764e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek } 765337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek 766337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek case Stmt::CXXCatchStmtClass: { 767337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek Bldr.takeNodes(Pred); 768337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek VisitCXXCatchStmt(cast<CXXCatchStmt>(S), Pred, Dst); 769337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek Bldr.addNodes(Dst); 770337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek break; 771337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek } 77206fb99fb403bff1651429923f666a2ebe2b1522fTed Kremenek 773744f1cd66bb6747ea71fbf1172698e7bf35ec88dTed Kremenek case Stmt::CXXTemporaryObjectExprClass: 774888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose case Stmt::CXXConstructExprClass: { 775ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 776888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose VisitCXXConstructExpr(cast<CXXConstructExpr>(S), Pred, Dst); 777ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 7787ce351db56fbce162a3b650518ce05b5c61ebf36Zhongxing Xu break; 7797ce351db56fbce162a3b650518ce05b5c61ebf36Zhongxing Xu } 7807ce351db56fbce162a3b650518ce05b5c61ebf36Zhongxing Xu 781856c6bcaea56e05255e9f3997ddd56b5c18a14f0Zhongxing Xu case Stmt::CXXNewExprClass: { 782ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 78303509aea098772644bf4662dc1c88634818ceeccZhongxing Xu const CXXNewExpr *NE = cast<CXXNewExpr>(S); 784856c6bcaea56e05255e9f3997ddd56b5c18a14f0Zhongxing Xu VisitCXXNewExpr(NE, Pred, Dst); 785ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 786856c6bcaea56e05255e9f3997ddd56b5c18a14f0Zhongxing Xu break; 787856c6bcaea56e05255e9f3997ddd56b5c18a14f0Zhongxing Xu } 788856c6bcaea56e05255e9f3997ddd56b5c18a14f0Zhongxing Xu 7896b8513829895e56a7b97e787ea74520bc626512eZhongxing Xu case Stmt::CXXDeleteExprClass: { 790ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 79103509aea098772644bf4662dc1c88634818ceeccZhongxing Xu const CXXDeleteExpr *CDE = cast<CXXDeleteExpr>(S); 7926b8513829895e56a7b97e787ea74520bc626512eZhongxing Xu VisitCXXDeleteExpr(CDE, Pred, Dst); 793ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 7946b8513829895e56a7b97e787ea74520bc626512eZhongxing Xu break; 7956b8513829895e56a7b97e787ea74520bc626512eZhongxing Xu } 796e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek // FIXME: ChooseExpr is really a constant. We need to fix 797e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek // the CFG do not model them as explicit control-flow. 7981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 799e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek case Stmt::ChooseExprClass: { // __builtin_choose_expr 800ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 8019c378f705405d37f49795d5e915989de774fe11fTed Kremenek const ChooseExpr *C = cast<ChooseExpr>(S); 802e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek VisitGuardedExpr(C, C->getLHS(), C->getRHS(), Pred, Dst); 803ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 804e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek break; 805e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek } 8061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 807e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek case Stmt::CompoundAssignOperatorClass: 808ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 809892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Dst); 810ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 811e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek break; 812f22679e3e5d5f5754931952e58112b4c863a4137Zhongxing Xu 813f22679e3e5d5f5754931952e58112b4c863a4137Zhongxing Xu case Stmt::CompoundLiteralExprClass: 814ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 815892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek VisitCompoundLiteralExpr(cast<CompoundLiteralExpr>(S), Pred, Dst); 816ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 817f22679e3e5d5f5754931952e58112b4c863a4137Zhongxing Xu break; 8181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 81956ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall case Stmt::BinaryConditionalOperatorClass: 820e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek case Stmt::ConditionalOperatorClass: { // '?' operator 821ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 82256ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall const AbstractConditionalOperator *C 82356ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall = cast<AbstractConditionalOperator>(S); 82456ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall VisitGuardedExpr(C, C->getTrueExpr(), C->getFalseExpr(), Pred, Dst); 825ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 826e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek break; 827e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek } 8281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 829bb141217871e93767aa3f2de1b9946fa6d37066aZhongxing Xu case Stmt::CXXThisExprClass: 830ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 831bb141217871e93767aa3f2de1b9946fa6d37066aZhongxing Xu VisitCXXThisExpr(cast<CXXThisExpr>(S), Pred, Dst); 832ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 833bb141217871e93767aa3f2de1b9946fa6d37066aZhongxing Xu break; 834bb141217871e93767aa3f2de1b9946fa6d37066aZhongxing Xu 835892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek case Stmt::DeclRefExprClass: { 836ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 837892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek const DeclRefExpr *DE = cast<DeclRefExpr>(S); 838892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek VisitCommonDeclRefExpr(DE, DE->getDecl(), Pred, Dst); 839ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 840e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek break; 841892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek } 8421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 843e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek case Stmt::DeclStmtClass: 844ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 845e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek VisitDeclStmt(cast<DeclStmt>(S), Pred, Dst); 846ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 847e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek break; 8481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 8490835a3cdeefe714b4959d31127ea155e56393125Argyrios Kyrtzidis case Stmt::ImplicitCastExprClass: 8500d9d736c49b51691ced96759ec99399824e2a602Zhongxing Xu case Stmt::CStyleCastExprClass: 8510d9d736c49b51691ced96759ec99399824e2a602Zhongxing Xu case Stmt::CXXStaticCastExprClass: 8520d9d736c49b51691ced96759ec99399824e2a602Zhongxing Xu case Stmt::CXXDynamicCastExprClass: 8530d9d736c49b51691ced96759ec99399824e2a602Zhongxing Xu case Stmt::CXXReinterpretCastExprClass: 8540d9d736c49b51691ced96759ec99399824e2a602Zhongxing Xu case Stmt::CXXConstCastExprClass: 855f85e193739c953358c865005855253af4f68a497John McCall case Stmt::CXXFunctionalCastExprClass: 856f85e193739c953358c865005855253af4f68a497John McCall case Stmt::ObjCBridgedCastExprClass: { 857ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 8589c378f705405d37f49795d5e915989de774fe11fTed Kremenek const CastExpr *C = cast<CastExpr>(S); 859f85e193739c953358c865005855253af4f68a497John McCall // Handle the previsit checks. 860f85e193739c953358c865005855253af4f68a497John McCall ExplodedNodeSet dstPrevisit; 861f85e193739c953358c865005855253af4f68a497John McCall getCheckerManager().runCheckersForPreStmt(dstPrevisit, Pred, C, *this); 862f85e193739c953358c865005855253af4f68a497John McCall 863f85e193739c953358c865005855253af4f68a497John McCall // Handle the expression itself. 864f85e193739c953358c865005855253af4f68a497John McCall ExplodedNodeSet dstExpr; 865f85e193739c953358c865005855253af4f68a497John McCall for (ExplodedNodeSet::iterator i = dstPrevisit.begin(), 866f85e193739c953358c865005855253af4f68a497John McCall e = dstPrevisit.end(); i != e ; ++i) { 867f85e193739c953358c865005855253af4f68a497John McCall VisitCast(C, C->getSubExpr(), *i, dstExpr); 868f85e193739c953358c865005855253af4f68a497John McCall } 869f85e193739c953358c865005855253af4f68a497John McCall 870f85e193739c953358c865005855253af4f68a497John McCall // Handle the postvisit checks. 871f85e193739c953358c865005855253af4f68a497John McCall getCheckerManager().runCheckersForPostStmt(Dst, dstExpr, C, *this); 872ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 873e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek break; 874e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek } 875b9bbd592c7ea72ada8d982e40a729beb9b53371eTed Kremenek 87603e80030515c800d1ab44125b9052dfffd1bd04cDouglas Gregor case Expr::MaterializeTemporaryExprClass: { 877ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 878c210cb7a358d14cdd93b58562f33ff5ed2d895c1Jordan Rose const MaterializeTemporaryExpr *MTE = cast<MaterializeTemporaryExpr>(S); 879c210cb7a358d14cdd93b58562f33ff5ed2d895c1Jordan Rose CreateCXXTemporaryObject(MTE, Pred, Dst); 880ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 88103e80030515c800d1ab44125b9052dfffd1bd04cDouglas Gregor break; 88203e80030515c800d1ab44125b9052dfffd1bd04cDouglas Gregor } 88303e80030515c800d1ab44125b9052dfffd1bd04cDouglas Gregor 884c4f8706b6539e06a5de153bd72850bb2e0a71456Zhongxing Xu case Stmt::InitListExprClass: 885ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 886c4f8706b6539e06a5de153bd72850bb2e0a71456Zhongxing Xu VisitInitListExpr(cast<InitListExpr>(S), Pred, Dst); 887ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 888c4f8706b6539e06a5de153bd72850bb2e0a71456Zhongxing Xu break; 8891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 89097ed4f68f5dba3e21e7a490ef0f9ffd3bfead7f8Ted Kremenek case Stmt::MemberExprClass: 891ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 892892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek VisitMemberExpr(cast<MemberExpr>(S), Pred, Dst); 893ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 894469ecbded3616416ef938ed94a67f86149faf226Ted Kremenek break; 895ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks 89697ed4f68f5dba3e21e7a490ef0f9ffd3bfead7f8Ted Kremenek case Stmt::ObjCIvarRefExprClass: 897ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 898892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek VisitLvalObjCIvarRefExpr(cast<ObjCIvarRefExpr>(S), Pred, Dst); 899ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 90097ed4f68f5dba3e21e7a490ef0f9ffd3bfead7f8Ted Kremenek break; 901af3374187c47acea45706eab6744be6b1c66a856Ted Kremenek 902af3374187c47acea45706eab6744be6b1c66a856Ted Kremenek case Stmt::ObjCForCollectionStmtClass: 903ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 904af3374187c47acea45706eab6744be6b1c66a856Ted Kremenek VisitObjCForCollectionStmt(cast<ObjCForCollectionStmt>(S), Pred, Dst); 905ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 906af3374187c47acea45706eab6744be6b1c66a856Ted Kremenek break; 9071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 908d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose case Stmt::ObjCMessageExprClass: 909ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 910d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose VisitObjCMessage(cast<ObjCMessageExpr>(S), Pred, Dst); 911ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 912e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek break; 9131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 914c32a453e40b2c8878fed10512fb2f570b7aba576Jordan Rose case Stmt::ObjCAtThrowStmtClass: 915c32a453e40b2c8878fed10512fb2f570b7aba576Jordan Rose case Stmt::CXXThrowExprClass: 916bbfd07a0c94f659beaf74316029ef73769cefb81Ted Kremenek // FIXME: This is not complete. We basically treat @throw as 917bbfd07a0c94f659beaf74316029ef73769cefb81Ted Kremenek // an abort. 918fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose Bldr.generateSink(S, Pred, Pred->getState()); 919bbfd07a0c94f659beaf74316029ef73769cefb81Ted Kremenek break; 9201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 9211b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek case Stmt::ReturnStmtClass: 922ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 9231b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek VisitReturnStmt(cast<ReturnStmt>(S), Pred, Dst); 924ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 9251b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek break; 9261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 9278ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor case Stmt::OffsetOfExprClass: 928ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 9298ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor VisitOffsetOfExpr(cast<OffsetOfExpr>(S), Pred, Dst); 930ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 9318ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor break; 9328ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor 933f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne case Stmt::UnaryExprOrTypeTraitExprClass: 934ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 935f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne VisitUnaryExprOrTypeTraitExpr(cast<UnaryExprOrTypeTraitExpr>(S), 936f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne Pred, Dst); 937ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 938e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek break; 9391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 940e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek case Stmt::StmtExprClass: { 9419c378f705405d37f49795d5e915989de774fe11fTed Kremenek const StmtExpr *SE = cast<StmtExpr>(S); 942a3d1eb85853eae7b719f679b40923826b5e4b7dfTed Kremenek 943a3d1eb85853eae7b719f679b40923826b5e4b7dfTed Kremenek if (SE->getSubStmt()->body_empty()) { 944a3d1eb85853eae7b719f679b40923826b5e4b7dfTed Kremenek // Empty statement expression. 945a3d1eb85853eae7b719f679b40923826b5e4b7dfTed Kremenek assert(SE->getType() == getContext().VoidTy 946a3d1eb85853eae7b719f679b40923826b5e4b7dfTed Kremenek && "Empty statement expression must have void type."); 947a3d1eb85853eae7b719f679b40923826b5e4b7dfTed Kremenek break; 948a3d1eb85853eae7b719f679b40923826b5e4b7dfTed Kremenek } 9491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 9509c378f705405d37f49795d5e915989de774fe11fTed Kremenek if (Expr *LastExpr = dyn_cast<Expr>(*SE->getSubStmt()->body_rbegin())) { 9518bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek ProgramStateRef state = Pred->getState(); 952ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.generateNode(SE, Pred, 9535eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek state->BindExpr(SE, Pred->getLocationContext(), 9545eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek state->getSVal(LastExpr, 9555eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek Pred->getLocationContext()))); 956a3d1eb85853eae7b719f679b40923826b5e4b7dfTed Kremenek } 957e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek break; 958e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek } 9596987c7b74146b9658b1925c5981f8b0cd0672b55Zhongxing Xu 96072374594c5d9ade02451bc85cf9dfa5b0ea106e7Ted Kremenek case Stmt::UnaryOperatorClass: { 961ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 96203509aea098772644bf4662dc1c88634818ceeccZhongxing Xu const UnaryOperator *U = cast<UnaryOperator>(S); 9630caa2d47b84337e942b3f6652adfafe4ae506cfeTed Kremenek if (AMgr.options.eagerlyAssumeBinOpBifurcation && (U->getOpcode() == UO_LNot)) { 964031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu ExplodedNodeSet Tmp; 965892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek VisitUnaryOperator(U, Pred, Tmp); 9660caa2d47b84337e942b3f6652adfafe4ae506cfeTed Kremenek evalEagerlyAssumeBinOpBifurcation(Dst, Tmp, U); 96772374594c5d9ade02451bc85cf9dfa5b0ea106e7Ted Kremenek } 96872374594c5d9ade02451bc85cf9dfa5b0ea106e7Ted Kremenek else 969892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek VisitUnaryOperator(U, Pred, Dst); 970ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 9711b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek break; 97272374594c5d9ade02451bc85cf9dfa5b0ea106e7Ted Kremenek } 9734b9c2d235fb9449e249d74f48ecfec601650de93John McCall 9744b9c2d235fb9449e249d74f48ecfec601650de93John McCall case Stmt::PseudoObjectExprClass: { 9754b9c2d235fb9449e249d74f48ecfec601650de93John McCall Bldr.takeNodes(Pred); 9768bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek ProgramStateRef state = Pred->getState(); 9774b9c2d235fb9449e249d74f48ecfec601650de93John McCall const PseudoObjectExpr *PE = cast<PseudoObjectExpr>(S); 9784b9c2d235fb9449e249d74f48ecfec601650de93John McCall if (const Expr *Result = PE->getResultExpr()) { 9795eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek SVal V = state->getSVal(Result, Pred->getLocationContext()); 9805eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek Bldr.generateNode(S, Pred, 9815eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek state->BindExpr(S, Pred->getLocationContext(), V)); 9824b9c2d235fb9449e249d74f48ecfec601650de93John McCall } 9834b9c2d235fb9449e249d74f48ecfec601650de93John McCall else 9845eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek Bldr.generateNode(S, Pred, 9855eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek state->BindExpr(S, Pred->getLocationContext(), 9865eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek UnknownVal())); 9874b9c2d235fb9449e249d74f48ecfec601650de93John McCall 9884b9c2d235fb9449e249d74f48ecfec601650de93John McCall Bldr.addNodes(Dst); 9894b9c2d235fb9449e249d74f48ecfec601650de93John McCall break; 9904b9c2d235fb9449e249d74f48ecfec601650de93John McCall } 9911b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek } 9921b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek} 9931b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek 9945903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaksbool ExprEngine::replayWithoutInlining(ExplodedNode *N, 9955903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks const LocationContext *CalleeLC) { 9965903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks const StackFrameContext *CalleeSF = CalleeLC->getCurrentStackFrame(); 9975903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks const StackFrameContext *CallerSF = CalleeSF->getParent()->getCurrentStackFrame(); 9985903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks assert(CalleeSF && CallerSF); 9995903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks ExplodedNode *BeforeProcessingCall = 0; 100028038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose const Stmt *CE = CalleeSF->getCallSite(); 10015903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks 10025903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks // Find the first node before we started processing the call expression. 10035903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks while (N) { 10045903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks ProgramPoint L = N->getLocation(); 10055903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks BeforeProcessingCall = N; 10065903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks N = N->pred_empty() ? NULL : *(N->pred_begin()); 10075903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks 10085903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks // Skip the nodes corresponding to the inlined code. 10095903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks if (L.getLocationContext()->getCurrentStackFrame() != CallerSF) 10105903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks continue; 10115903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks // We reached the caller. Find the node right before we started 101228038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose // processing the call. 10130b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks if (L.isPurgeKind()) 10145903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks continue; 101528038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose if (isa<PreImplicitCall>(&L)) 101628038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose continue; 1017852aa0d2c5d2d1faf2d77b5aa3c0848068a342c5Jordan Rose if (isa<CallEnter>(&L)) 1018852aa0d2c5d2d1faf2d77b5aa3c0848068a342c5Jordan Rose continue; 10195903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks if (const StmtPoint *SP = dyn_cast<StmtPoint>(&L)) 102028038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose if (SP->getStmt() == CE) 10215903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks continue; 10225903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks break; 10235903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks } 10245903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks 1025253955ca25c7e7049963b5db613c0cd15d66e4f8Anna Zaks if (!BeforeProcessingCall) 10265903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks return false; 10275903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks 10285903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks // TODO: Clean up the unneeded nodes. 10295903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks 10305903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks // Build an Epsilon node from which we will restart the analyzes. 103128038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose // Note that CE is permitted to be NULL! 10325903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks ProgramPoint NewNodeLoc = 10335903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks EpsilonPoint(BeforeProcessingCall->getLocationContext(), CE); 10345903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks // Add the special flag to GDM to signal retrying with no inlining. 10355903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks // Note, changing the state ensures that we are not going to cache out. 10365903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks ProgramStateRef NewNodeState = BeforeProcessingCall->getState(); 10375903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks NewNodeState = NewNodeState->set<ReplayWithoutInlining>((void*)CE); 10385903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks 10395903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks // Make the new node a successor of BeforeProcessingCall. 10405903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks bool IsNew = false; 10415903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks ExplodedNode *NewNode = G.getNode(NewNodeLoc, NewNodeState, false, &IsNew); 1042253955ca25c7e7049963b5db613c0cd15d66e4f8Anna Zaks // We cached out at this point. Caching out is common due to us backtracking 1043253955ca25c7e7049963b5db613c0cd15d66e4f8Anna Zaks // from the inlined function, which might spawn several paths. 1044253955ca25c7e7049963b5db613c0cd15d66e4f8Anna Zaks if (!IsNew) 1045253955ca25c7e7049963b5db613c0cd15d66e4f8Anna Zaks return true; 1046253955ca25c7e7049963b5db613c0cd15d66e4f8Anna Zaks 10475903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks NewNode->addPredecessor(BeforeProcessingCall, G); 10485903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks 10495903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks // Add the new node to the work list. 10505903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks Engine.enqueueStmtNode(NewNode, CalleeSF->getCallSiteBlock(), 10515903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks CalleeSF->getIndex()); 10525903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks NumTimesRetriedWithoutInlining++; 10535903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks return true; 10545903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks} 10555903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks 1056c03a39e16762627b421247b12a2658be630a3300Anna Zaks/// Block entrance. (Update counters). 1057253955ca25c7e7049963b5db613c0cd15d66e4f8Anna Zaksvoid ExprEngine::processCFGBlockEntrance(const BlockEdge &L, 1058253955ca25c7e7049963b5db613c0cd15d66e4f8Anna Zaks NodeBuilderWithSinks &nodeBuilder) { 105927c54e57c4a012dcdf2b40cf985b70d0b9caa69eTed Kremenek 106027c54e57c4a012dcdf2b40cf985b70d0b9caa69eTed Kremenek // FIXME: Refactor this into a checker. 1061c03a39e16762627b421247b12a2658be630a3300Anna Zaks ExplodedNode *pred = nodeBuilder.getContext().getPred(); 106227c54e57c4a012dcdf2b40cf985b70d0b9caa69eTed Kremenek 10632fa9d72d4d23ccdcd4137946e5ebafac7a04f04cTed Kremenek if (nodeBuilder.getContext().blockCount() >= AMgr.options.maxBlockVisitOnPath) { 1064ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek static SimpleProgramPointTag tag("ExprEngine : Block count exceeded"); 1065253955ca25c7e7049963b5db613c0cd15d66e4f8Anna Zaks const ExplodedNode *Sink = 1066fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose nodeBuilder.generateSink(pred->getState(), pred, &tag); 1067749bbe6f5f23676244f12a0d41511c8e73516febAnna Zaks 1068749bbe6f5f23676244f12a0d41511c8e73516febAnna Zaks // Check if we stopped at the top level function or not. 1069749bbe6f5f23676244f12a0d41511c8e73516febAnna Zaks // Root node should have the location context of the top most function. 10705903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks const LocationContext *CalleeLC = pred->getLocation().getLocationContext(); 10713bbd8cd831788c506f2980293eb3c7e1b3ca2501Anna Zaks const LocationContext *CalleeSF = CalleeLC->getCurrentStackFrame(); 10725903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks const LocationContext *RootLC = 10735903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks (*G.roots_begin())->getLocation().getLocationContext(); 10743bbd8cd831788c506f2980293eb3c7e1b3ca2501Anna Zaks if (RootLC->getCurrentStackFrame() != CalleeSF) { 1075e62f048960645b79363408fdead53fec2a063c52Anna Zaks Engine.FunctionSummaries->markReachedMaxBlockCount(CalleeSF->getDecl()); 10763bbd8cd831788c506f2980293eb3c7e1b3ca2501Anna Zaks 10775903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks // Re-run the call evaluation without inlining it, by storing the 10785903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks // no-inlining policy in the state and enqueuing the new work item on 10795903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks // the list. Replay should almost never fail. Use the stats to catch it 10805903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks // if it does. 1081255d4d4226b24036ceb11228fbb74286e58620f7Ted Kremenek if ((!AMgr.options.NoRetryExhausted && 1082255d4d4226b24036ceb11228fbb74286e58620f7Ted Kremenek replayWithoutInlining(pred, CalleeLC))) 1083253955ca25c7e7049963b5db613c0cd15d66e4f8Anna Zaks return; 1084253955ca25c7e7049963b5db613c0cd15d66e4f8Anna Zaks NumMaxBlockCountReachedInInlined++; 10855903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks } else 1086749bbe6f5f23676244f12a0d41511c8e73516febAnna Zaks NumMaxBlockCountReached++; 1087253955ca25c7e7049963b5db613c0cd15d66e4f8Anna Zaks 1088253955ca25c7e7049963b5db613c0cd15d66e4f8Anna Zaks // Make sink nodes as exhausted(for stats) only if retry failed. 1089253955ca25c7e7049963b5db613c0cd15d66e4f8Anna Zaks Engine.blocksExhausted.push_back(std::make_pair(L, Sink)); 109027c54e57c4a012dcdf2b40cf985b70d0b9caa69eTed Kremenek } 1091e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek} 1092e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek 1093e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek//===----------------------------------------------------------------------===// 1094e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek// Branch processing. 1095e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek//===----------------------------------------------------------------------===// 1096e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek 10976ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek/// RecoverCastedSymbol - A helper function for ProcessBranch that is used 10986ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek/// to try to recover some path-sensitivity for casts of symbolic 10996ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek/// integers that promote their values (which are currently not tracked well). 11006ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek/// This function returns the SVal bound to Condition->IgnoreCasts if all the 11016ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek// cast(s) did was sign-extend the original value. 1102294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenekstatic SVal RecoverCastedSymbol(ProgramStateManager& StateMgr, 11038bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek ProgramStateRef state, 1104294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const Stmt *Condition, 11055eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek const LocationContext *LCtx, 1106294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ASTContext &Ctx) { 11076ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek 110803509aea098772644bf4662dc1c88634818ceeccZhongxing Xu const Expr *Ex = dyn_cast<Expr>(Condition); 11096ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek if (!Ex) 11106ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek return UnknownVal(); 11116ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek 11126ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek uint64_t bits = 0; 11136ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek bool bitsInit = false; 11141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 111503509aea098772644bf4662dc1c88634818ceeccZhongxing Xu while (const CastExpr *CE = dyn_cast<CastExpr>(Ex)) { 11166ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek QualType T = CE->getType(); 11176ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek 11186ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek if (!T->isIntegerType()) 11196ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek return UnknownVal(); 11201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 11216ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek uint64_t newBits = Ctx.getTypeSize(T); 11226ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek if (!bitsInit || newBits < bits) { 11236ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek bitsInit = true; 11246ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek bits = newBits; 11256ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek } 11261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 11276ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek Ex = CE->getSubExpr(); 11286ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek } 11296ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek 11306ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek // We reached a non-cast. Is it a symbolic value? 11316ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek QualType T = Ex->getType(); 11326ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek 11336ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek if (!bitsInit || !T->isIntegerType() || Ctx.getTypeSize(T) > bits) 11346ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek return UnknownVal(); 11351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 11365eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek return state->getSVal(Ex, LCtx); 11376ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek} 11386ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek 11393f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenekstatic const Stmt *ResolveCondition(const Stmt *Condition, 11403f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek const CFGBlock *B) { 11413f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek if (const Expr *Ex = dyn_cast<Expr>(Condition)) 11423f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek Condition = Ex->IgnoreParens(); 11433f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 11443f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek const BinaryOperator *BO = dyn_cast<BinaryOperator>(Condition); 11453f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek if (!BO || !BO->isLogicalOp()) 11463f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek return Condition; 11473f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 11483f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // For logical operations, we still have the case where some branches 11493f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // use the traditional "merge" approach and others sink the branch 11503f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // directly into the basic blocks representing the logical operation. 11513f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // We need to distinguish between those two cases here. 11523f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 11533f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // The invariants are still shifting, but it is possible that the 11543f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // last element in a CFGBlock is not a CFGStmt. Look for the last 11553f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // CFGStmt as the value of the condition. 11563f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek CFGBlock::const_reverse_iterator I = B->rbegin(), E = B->rend(); 11573f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek for (; I != E; ++I) { 11583f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek CFGElement Elem = *I; 11593f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek CFGStmt *CS = dyn_cast<CFGStmt>(&Elem); 11603f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek if (!CS) 11613f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek continue; 11623f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek if (CS->getStmt() != Condition) 11633f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek break; 11643f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek return Condition; 11653f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek } 11663f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 11673f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek assert(I != E); 11683f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 11693f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek while (Condition) { 11703f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek BO = dyn_cast<BinaryOperator>(Condition); 11713f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek if (!BO || !BO->isLogicalOp()) 11723f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek return Condition; 11733f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek Condition = BO->getRHS()->IgnoreParens(); 11743f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek } 11753f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek llvm_unreachable("could not resolve condition"); 11763f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek} 11773f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 11789c378f705405d37f49795d5e915989de774fe11fTed Kremenekvoid ExprEngine::processBranch(const Stmt *Condition, const Stmt *Term, 1179a19f4af7a94835ce4693bfe12d6270754e79eb56Anna Zaks NodeBuilderContext& BldCtx, 1180ad62deeb70e97da6bd514dd390ea1ce6af6ad81dAnna Zaks ExplodedNode *Pred, 11811aae01a8308d2f8e31adab3f4d7ac35543aac680Anna Zaks ExplodedNodeSet &Dst, 1182a19f4af7a94835ce4693bfe12d6270754e79eb56Anna Zaks const CFGBlock *DstT, 1183a19f4af7a94835ce4693bfe12d6270754e79eb56Anna Zaks const CFGBlock *DstF) { 118466c486f275531df6362b3511fc3af6563561801bTed Kremenek currBldrCtx = &BldCtx; 1185f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks 1186b2331834a0515c80862ee51325c758a053829f15Ted Kremenek // Check for NULL conditions; e.g. "for(;;)" 11871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (!Condition) { 11881aae01a8308d2f8e31adab3f4d7ac35543aac680Anna Zaks BranchNodeBuilder NullCondBldr(Pred, Dst, BldCtx, DstT, DstF); 1189a19f4af7a94835ce4693bfe12d6270754e79eb56Anna Zaks NullCondBldr.markInfeasible(false); 11904e82d3cf6fd4c907265e3fa3aac0a835c35dc759Anna Zaks NullCondBldr.generateNode(Pred->getState(), true, Pred); 1191b2331834a0515c80862ee51325c758a053829f15Ted Kremenek return; 1192b2331834a0515c80862ee51325c758a053829f15Ted Kremenek } 11931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 11943f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 11953f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // Resolve the condition in the precense of nested '||' and '&&'. 11963f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek if (const Expr *Ex = dyn_cast<Expr>(Condition)) 11973f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek Condition = Ex->IgnoreParens(); 11983f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 11993f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek Condition = ResolveCondition(Condition, BldCtx.getBlock()); 120021028dd8850c64a414f7a82dfddcc291351203d6Ted Kremenek PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(), 120121028dd8850c64a414f7a82dfddcc291351203d6Ted Kremenek Condition->getLocStart(), 120221028dd8850c64a414f7a82dfddcc291351203d6Ted Kremenek "Error evaluating branch"); 12030fb0bc4067d6c9d7c0e655300ef309b05d3adfc9Ted Kremenek 1204f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks ExplodedNodeSet CheckersOutSet; 1205f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks getCheckerManager().runCheckersForBranchCondition(Condition, CheckersOutSet, 12064e82d3cf6fd4c907265e3fa3aac0a835c35dc759Anna Zaks Pred, *this); 12078ff5c41f2bde7ebbe568b4c15e59f14b8befae66Anna Zaks // We generated only sinks. 1208f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks if (CheckersOutSet.empty()) 12098ff5c41f2bde7ebbe568b4c15e59f14b8befae66Anna Zaks return; 12101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1211f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks BranchNodeBuilder builder(CheckersOutSet, Dst, BldCtx, DstT, DstF); 1212f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks for (NodeBuilder::iterator I = CheckersOutSet.begin(), 1213f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks E = CheckersOutSet.end(); E != I; ++I) { 1214cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks ExplodedNode *PredI = *I; 1215cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks 1216cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks if (PredI->isSink()) 1217cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks continue; 1218cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks 12198bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek ProgramStateRef PrevState = Pred->getState(); 12205eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek SVal X = PrevState->getSVal(Condition, Pred->getLocationContext()); 1221cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks 1222cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks if (X.isUnknownOrUndef()) { 1223cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks // Give it a chance to recover from unknown. 1224cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks if (const Expr *Ex = dyn_cast<Expr>(Condition)) { 1225cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks if (Ex->getType()->isIntegerType()) { 1226cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks // Try to recover some path-sensitivity. Right now casts of symbolic 1227cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks // integers that promote their values are currently not tracked well. 1228cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks // If 'Condition' is such an expression, try and recover the 1229cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks // underlying value and use that instead. 1230cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks SVal recovered = RecoverCastedSymbol(getStateManager(), 1231cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks PrevState, Condition, 12325eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek Pred->getLocationContext(), 1233cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks getContext()); 1234cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks 1235cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks if (!recovered.isUnknown()) { 1236cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks X = recovered; 1237cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks } 12380835e4cccfef3ea5346962722b79484f6b3ca602Zhongxing Xu } 1239b38911f16b4943548db6a3695fc6ae23070b25d2Ted Kremenek } 12400835e4cccfef3ea5346962722b79484f6b3ca602Zhongxing Xu } 12415eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek 12420835e4cccfef3ea5346962722b79484f6b3ca602Zhongxing Xu // If the condition is still unknown, give up. 124373c498a08f4968b6987d1453c7b77929dcc6d5f7Argyrios Kyrtzidis if (X.isUnknownOrUndef()) { 1244829846b5002d7f8d6a54b9c58c3ecf7cac56d2ccTed Kremenek builder.generateNode(PrevState, true, PredI); 1245829846b5002d7f8d6a54b9c58c3ecf7cac56d2ccTed Kremenek builder.generateNode(PrevState, false, PredI); 1246cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks continue; 12471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 12481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1249cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks DefinedSVal V = cast<DefinedSVal>(X); 12500835e4cccfef3ea5346962722b79484f6b3ca602Zhongxing Xu 1251cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks // Process the true branch. 1252cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks if (builder.isFeasible(true)) { 12538bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek if (ProgramStateRef state = PrevState->assume(V, true)) 1254829846b5002d7f8d6a54b9c58c3ecf7cac56d2ccTed Kremenek builder.generateNode(state, true, PredI); 1255cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks else 1256cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks builder.markInfeasible(true); 1257cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks } 12581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1259cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks // Process the false branch. 1260cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks if (builder.isFeasible(false)) { 12618bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek if (ProgramStateRef state = PrevState->assume(V, false)) 1262829846b5002d7f8d6a54b9c58c3ecf7cac56d2ccTed Kremenek builder.generateNode(state, false, PredI); 1263cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks else 1264cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks builder.markInfeasible(false); 1265cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks } 1266cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks } 126766c486f275531df6362b3511fc3af6563561801bTed Kremenek currBldrCtx = 0; 1268f233d48cfc513b045e2c2cfca5c175220fbd0a82Ted Kremenek} 1269f233d48cfc513b045e2c2cfca5c175220fbd0a82Ted Kremenek 1270e36de1fe51c39d9161915dd3dbef880954af6476Ted Kremenek/// processIndirectGoto - Called by CoreEngine. Used to generate successor 1271754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek/// nodes by processing the 'effects' of a computed goto jump. 1272ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattnervoid ExprEngine::processIndirectGoto(IndirectGotoNodeBuilder &builder) { 1273754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek 12748bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek ProgramStateRef state = builder.getState(); 12755eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek SVal V = state->getSVal(builder.getTarget(), builder.getLocationContext()); 12761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1277754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek // Three possibilities: 1278754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek // 1279754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek // (1) We know the computed label. 12804a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek // (2) The label is NULL (or some other constant), or Undefined. 1281754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek // (3) We have no clue about the label. Dispatch to all targets. 1282754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek // 12831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1284d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis typedef IndirectGotoNodeBuilder::iterator iterator; 1285754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek 12861c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu if (isa<loc::GotoLabel>(V)) { 1287ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattner const LabelDecl *L = cast<loc::GotoLabel>(V).getLabel(); 12881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1289ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattner for (iterator I = builder.begin(), E = builder.end(); I != E; ++I) { 129024f1a967741ff9f8025ee23be12ba6feacc31f77Ted Kremenek if (I.getLabel() == L) { 1291a8538d902fce9cfec20f39b34492268b51643819Ted Kremenek builder.generateNode(I, state); 1292754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek return; 1293754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek } 1294754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek } 12951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1296b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie llvm_unreachable("No block with label."); 1297754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek } 1298754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek 12991c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu if (isa<loc::ConcreteInt>(V) || isa<UndefinedVal>(V)) { 1300754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek // Dispatch to the first target and mark it as a sink. 13012055effed54d614b51e3501a174c9b1fe92e4de4Zhongxing Xu //ExplodedNode* N = builder.generateNode(builder.begin(), state, true); 13022055effed54d614b51e3501a174c9b1fe92e4de4Zhongxing Xu // FIXME: add checker visit. 13032055effed54d614b51e3501a174c9b1fe92e4de4Zhongxing Xu // UndefBranches.insert(N); 1304754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek return; 1305754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek } 13061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1307754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek // This is really a catch-all. We don't support symbolics yet. 1308b3cfd58c9b13325d994e5f9b5065e6a22d91911dTed Kremenek // FIXME: Implement dispatch for symbolic pointers. 13091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1310754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek for (iterator I=builder.begin(), E=builder.end(); I != E; ++I) 1311a8538d902fce9cfec20f39b34492268b51643819Ted Kremenek builder.generateNode(I, state); 1312754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek} 1313f233d48cfc513b045e2c2cfca5c175220fbd0a82Ted Kremenek 1314d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis/// ProcessEndPath - Called by CoreEngine. Used to generate end-of-path 131573099bfea9f5d4ec05265170bbefec3d76fb6b5eTed Kremenek/// nodes when the control reaches the end of a function. 1316af498a28797c075c48d7e943df5f5a8e78ed8eb0Anna Zaksvoid ExprEngine::processEndOfFunction(NodeBuilderContext& BC) { 1317af498a28797c075c48d7e943df5f5a8e78ed8eb0Anna Zaks StateMgr.EndPath(BC.Pred->getState()); 1318af498a28797c075c48d7e943df5f5a8e78ed8eb0Anna Zaks ExplodedNodeSet Dst; 1319af498a28797c075c48d7e943df5f5a8e78ed8eb0Anna Zaks getCheckerManager().runCheckersForEndPath(BC, Dst, *this); 13204d2ae4a70336dc2aa11389b34946be152bb454c9Anna Zaks Engine.enqueueEndOfFunction(Dst); 132173099bfea9f5d4ec05265170bbefec3d76fb6b5eTed Kremenek} 132273099bfea9f5d4ec05265170bbefec3d76fb6b5eTed Kremenek 1323d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis/// ProcessSwitch - Called by CoreEngine. Used to generate successor 1324daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek/// nodes by processing the 'effects' of a switch statement. 1325e36de1fe51c39d9161915dd3dbef880954af6476Ted Kremenekvoid ExprEngine::processSwitch(SwitchNodeBuilder& builder) { 1326d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis typedef SwitchNodeBuilder::iterator iterator; 13278bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek ProgramStateRef state = builder.getState(); 13289c378f705405d37f49795d5e915989de774fe11fTed Kremenek const Expr *CondE = builder.getCondition(); 13295eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek SVal CondV_untested = state->getSVal(CondE, builder.getLocationContext()); 1330daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek 13315b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek if (CondV_untested.isUndef()) { 13322055effed54d614b51e3501a174c9b1fe92e4de4Zhongxing Xu //ExplodedNode* N = builder.generateDefaultCaseNode(state, true); 1333b9bbd592c7ea72ada8d982e40a729beb9b53371eTed Kremenek // FIXME: add checker 13342055effed54d614b51e3501a174c9b1fe92e4de4Zhongxing Xu //UndefBranches.insert(N); 13352055effed54d614b51e3501a174c9b1fe92e4de4Zhongxing Xu 1336daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek return; 1337daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek } 13385b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek DefinedOrUnknownSVal CondV = cast<DefinedOrUnknownSVal>(CondV_untested); 1339692416c214a3b234236dedcf875735a9cc29e90bTed Kremenek 13408bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek ProgramStateRef DefaultSt = state; 134134feff654c6304e0a59ceb1376989d28dbc956ffTed Kremenek 134234feff654c6304e0a59ceb1376989d28dbc956ffTed Kremenek iterator I = builder.begin(), EI = builder.end(); 134334feff654c6304e0a59ceb1376989d28dbc956ffTed Kremenek bool defaultIsFeasible = I == EI; 13441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 134534feff654c6304e0a59ceb1376989d28dbc956ffTed Kremenek for ( ; I != EI; ++I) { 1346e71f3d587844110d836c82250830b27b1651afdbTed Kremenek // Successor may be pruned out during CFG construction. 1347e71f3d587844110d836c82250830b27b1651afdbTed Kremenek if (!I.getBlock()) 1348e71f3d587844110d836c82250830b27b1651afdbTed Kremenek continue; 1349e71f3d587844110d836c82250830b27b1651afdbTed Kremenek 13509c378f705405d37f49795d5e915989de774fe11fTed Kremenek const CaseStmt *Case = I.getCase(); 135172afb3739da0da02158242ae41a50cfe0bea78b4Ted Kremenek 135272afb3739da0da02158242ae41a50cfe0bea78b4Ted Kremenek // Evaluate the LHS of the case value. 135385df96c1f04867e26ba069aa0cc6a4cd6a01292eRichard Smith llvm::APSInt V1 = Case->getLHS()->EvaluateKnownConstInt(getContext()); 135485df96c1f04867e26ba069aa0cc6a4cd6a01292eRichard Smith assert(V1.getBitWidth() == getContext().getTypeSize(CondE->getType())); 13551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1356daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek // Get the RHS of the case, if it exists. 135785df96c1f04867e26ba069aa0cc6a4cd6a01292eRichard Smith llvm::APSInt V2; 135885df96c1f04867e26ba069aa0cc6a4cd6a01292eRichard Smith if (const Expr *E = Case->getRHS()) 135985df96c1f04867e26ba069aa0cc6a4cd6a01292eRichard Smith V2 = E->EvaluateKnownConstInt(getContext()); 136014a1140c9f4e20b12a54db8745b74699b9872cd2Ted Kremenek else 136114a1140c9f4e20b12a54db8745b74699b9872cd2Ted Kremenek V2 = V1; 13621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1363daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek // FIXME: Eventually we should replace the logic below with a range 1364daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek // comparison, rather than concretize the values within the range. 1365aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek // This should be easy once we have "ranges" for NonLVals. 13661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 136714a1140c9f4e20b12a54db8745b74699b9872cd2Ted Kremenek do { 136885df96c1f04867e26ba069aa0cc6a4cd6a01292eRichard Smith nonloc::ConcreteInt CaseVal(getBasicVals().getValue(V1)); 13699c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek DefinedOrUnknownSVal Res = svalBuilder.evalEQ(DefaultSt ? DefaultSt : state, 137048569f9562740ac1f4b175cb17ce3d49035402c4Ted Kremenek CondV, CaseVal); 1371b9bbd592c7ea72ada8d982e40a729beb9b53371eTed Kremenek 13721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // Now "assume" that the case matches. 13738bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek if (ProgramStateRef stateNew = state->assume(Res, true)) { 1374a591bc04d21fa62ebffcb2c7814d738ca8f5e2f9Ted Kremenek builder.generateCaseStmtNode(I, stateNew); 13751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1376daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek // If CondV evaluates to a constant, then we know that this 1377daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek // is the *only* case that we can take, so stop evaluating the 1378daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek // others. 13791c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu if (isa<nonloc::ConcreteInt>(CondV)) 1380daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek return; 1381daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek } 13821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1383daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek // Now "assume" that the case doesn't match. Add this state 1384daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek // to the default state (if it is feasible). 138548569f9562740ac1f4b175cb17ce3d49035402c4Ted Kremenek if (DefaultSt) { 13868bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek if (ProgramStateRef stateNew = DefaultSt->assume(Res, false)) { 138748569f9562740ac1f4b175cb17ce3d49035402c4Ted Kremenek defaultIsFeasible = true; 138848569f9562740ac1f4b175cb17ce3d49035402c4Ted Kremenek DefaultSt = stateNew; 138948569f9562740ac1f4b175cb17ce3d49035402c4Ted Kremenek } 139048569f9562740ac1f4b175cb17ce3d49035402c4Ted Kremenek else { 139148569f9562740ac1f4b175cb17ce3d49035402c4Ted Kremenek defaultIsFeasible = false; 139248569f9562740ac1f4b175cb17ce3d49035402c4Ted Kremenek DefaultSt = NULL; 139348569f9562740ac1f4b175cb17ce3d49035402c4Ted Kremenek } 13945014ab113eb211b8320ae30b173d7020352663c6Ted Kremenek } 1395b9bbd592c7ea72ada8d982e40a729beb9b53371eTed Kremenek 139614a1140c9f4e20b12a54db8745b74699b9872cd2Ted Kremenek // Concretize the next value in the range. 139785df96c1f04867e26ba069aa0cc6a4cd6a01292eRichard Smith if (V1 == V2) 139814a1140c9f4e20b12a54db8745b74699b9872cd2Ted Kremenek break; 13991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 140085df96c1f04867e26ba069aa0cc6a4cd6a01292eRichard Smith ++V1; 140185df96c1f04867e26ba069aa0cc6a4cd6a01292eRichard Smith assert (V1 <= V2); 14021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 140314a1140c9f4e20b12a54db8745b74699b9872cd2Ted Kremenek } while (true); 1404daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek } 14051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 14064d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek if (!defaultIsFeasible) 14074d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek return; 14084d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek 14094d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek // If we have switch(enum value), the default branch is not 14104d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek // feasible if all of the enum constants not covered by 'case:' statements 14114d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek // are not feasible values for the switch condition. 14124d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek // 14134d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek // Note that this isn't as accurate as it could be. Even if there isn't 14144d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek // a case for a particular enum value as long as that enum value isn't 14154d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek // feasible then it shouldn't be considered for making 'default:' reachable. 14164d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek const SwitchStmt *SS = builder.getSwitch(); 14174d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek const Expr *CondExpr = SS->getCond()->IgnoreParenImpCasts(); 14184d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek if (CondExpr->getType()->getAs<EnumType>()) { 14194d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek if (SS->isAllEnumCasesCovered()) 14204d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek return; 14214d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek } 14224d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek 14234d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek builder.generateDefaultCaseNode(DefaultSt); 1424daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek} 1425daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek 1426e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek//===----------------------------------------------------------------------===// 1427ec96a2d52d16e150baaf629cd35e3fabff5d8915Ted Kremenek// Transfer functions: Loads and stores. 1428e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek//===----------------------------------------------------------------------===// 1429d27f8169f4b68337a489547a41ac45bf7a5d1ddfTed Kremenek 1430d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisvoid ExprEngine::VisitCommonDeclRefExpr(const Expr *Ex, const NamedDecl *D, 1431d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis ExplodedNode *Pred, 1432d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis ExplodedNodeSet &Dst) { 143366c486f275531df6362b3511fc3af6563561801bTed Kremenek StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx); 1434ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks 14358bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek ProgramStateRef state = Pred->getState(); 14365eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek const LocationContext *LCtx = Pred->getLocationContext(); 14376d69b5d82281992e981caa9bc038e3f6cac6594aZhongxing Xu 14389c378f705405d37f49795d5e915989de774fe11fTed Kremenek if (const VarDecl *VD = dyn_cast<VarDecl>(D)) { 1439591b5f53c0e11d87401b4804bb1be1a53f95c619Anna Zaks assert(Ex->isGLValue()); 1440d17da2b99f323fa91b01e1dd119cc32e0ee8197dTed Kremenek SVal V = state->getLValue(VD, Pred->getLocationContext()); 1441a7581731b1453b51b26154d2409d42a5b6395079Zhongxing Xu 1442892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek // For references, the 'lvalue' is the pointer address stored in the 1443892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek // reference region. 1444892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek if (VD->getType()->isReferenceType()) { 1445892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek if (const MemRegion *R = V.getAsRegion()) 1446892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek V = state->getSVal(R); 1447892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek else 1448892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek V = UnknownVal(); 1449852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek } 14506d69b5d82281992e981caa9bc038e3f6cac6594aZhongxing Xu 1451fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose Bldr.generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V), 0, 1452ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks ProgramPoint::PostLValueKind); 1453852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek return; 1454892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek } 14559c378f705405d37f49795d5e915989de774fe11fTed Kremenek if (const EnumConstantDecl *ED = dyn_cast<EnumConstantDecl>(D)) { 1456591b5f53c0e11d87401b4804bb1be1a53f95c619Anna Zaks assert(!Ex->isGLValue()); 1457c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek SVal V = svalBuilder.makeIntVal(ED->getInitVal()); 14585eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek Bldr.generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V)); 14596d69b5d82281992e981caa9bc038e3f6cac6594aZhongxing Xu return; 1460892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek } 14619c378f705405d37f49795d5e915989de774fe11fTed Kremenek if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 1462c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek SVal V = svalBuilder.getFunctionPointer(FD); 1463fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose Bldr.generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V), 0, 1464ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks ProgramPoint::PostLValueKind); 14656d69b5d82281992e981caa9bc038e3f6cac6594aZhongxing Xu return; 14661b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek } 14675aac0b6ae95f137b1783f3e6227241fb457b8f8bTed Kremenek if (isa<FieldDecl>(D)) { 1468fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose // FIXME: Compute lvalue of field pointers-to-member. 14690156439a3d718ea0ef5922c38d189a60829c8a86Jordan Rose // Right now we just use a non-null void pointer, so that it gives proper 14700156439a3d718ea0ef5922c38d189a60829c8a86Jordan Rose // results in boolean contexts. 14710156439a3d718ea0ef5922c38d189a60829c8a86Jordan Rose SVal V = svalBuilder.conjureSymbolVal(Ex, LCtx, getContext().VoidPtrTy, 14720156439a3d718ea0ef5922c38d189a60829c8a86Jordan Rose currBldrCtx->blockCount()); 14730156439a3d718ea0ef5922c38d189a60829c8a86Jordan Rose state = state->assume(cast<DefinedOrUnknownSVal>(V), true); 14740156439a3d718ea0ef5922c38d189a60829c8a86Jordan Rose Bldr.generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V), 0, 1475fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose ProgramPoint::PostLValueKind); 14765aac0b6ae95f137b1783f3e6227241fb457b8f8bTed Kremenek return; 14775aac0b6ae95f137b1783f3e6227241fb457b8f8bTed Kremenek } 14785aac0b6ae95f137b1783f3e6227241fb457b8f8bTed Kremenek 1479fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose llvm_unreachable("Support for this Decl not implemented."); 14803271f8d315712885ac87747369bb1d9f4b1ea81fTed Kremenek} 14813271f8d315712885ac87747369bb1d9f4b1ea81fTed Kremenek 1482540cbe2b60294fe7b926c26b4f1840f544fe3011Ted Kremenek/// VisitArraySubscriptExpr - Transfer function for array accesses 14839c378f705405d37f49795d5e915989de774fe11fTed Kremenekvoid ExprEngine::VisitLvalArraySubscriptExpr(const ArraySubscriptExpr *A, 14849c378f705405d37f49795d5e915989de774fe11fTed Kremenek ExplodedNode *Pred, 14859c378f705405d37f49795d5e915989de774fe11fTed Kremenek ExplodedNodeSet &Dst){ 14861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 14879c378f705405d37f49795d5e915989de774fe11fTed Kremenek const Expr *Base = A->getBase()->IgnoreParens(); 14889c378f705405d37f49795d5e915989de774fe11fTed Kremenek const Expr *Idx = A->getIdx()->IgnoreParens(); 1489892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek 14901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 14918f3407ef22bc7efe6ca4169381e09d0d657ec192Ted Kremenek ExplodedNodeSet checkerPreStmt; 14928f3407ef22bc7efe6ca4169381e09d0d657ec192Ted Kremenek getCheckerManager().runCheckersForPreStmt(checkerPreStmt, Pred, A, *this); 14938f3407ef22bc7efe6ca4169381e09d0d657ec192Ted Kremenek 149466c486f275531df6362b3511fc3af6563561801bTed Kremenek StmtNodeBuilder Bldr(checkerPreStmt, Dst, *currBldrCtx); 1495ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks 14968f3407ef22bc7efe6ca4169381e09d0d657ec192Ted Kremenek for (ExplodedNodeSet::iterator it = checkerPreStmt.begin(), 14978f3407ef22bc7efe6ca4169381e09d0d657ec192Ted Kremenek ei = checkerPreStmt.end(); it != ei; ++it) { 14985eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek const LocationContext *LCtx = (*it)->getLocationContext(); 14998bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek ProgramStateRef state = (*it)->getState(); 15005eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek SVal V = state->getLValue(A->getType(), 15015eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek state->getSVal(Idx, LCtx), 15025eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek state->getSVal(Base, LCtx)); 1503591b5f53c0e11d87401b4804bb1be1a53f95c619Anna Zaks assert(A->isGLValue()); 1504fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose Bldr.generateNode(A, *it, state->BindExpr(A, LCtx, V), 0, 1505fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose ProgramPoint::PostLValueKind); 15061b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek } 1507540cbe2b60294fe7b926c26b4f1840f544fe3011Ted Kremenek} 1508540cbe2b60294fe7b926c26b4f1840f544fe3011Ted Kremenek 1509469ecbded3616416ef938ed94a67f86149faf226Ted Kremenek/// VisitMemberExpr - Transfer function for member expressions. 15109c378f705405d37f49795d5e915989de774fe11fTed Kremenekvoid ExprEngine::VisitMemberExpr(const MemberExpr *M, ExplodedNode *Pred, 15116889679d72859960e0fc8d1080487f63c4df1e0aAnna Zaks ExplodedNodeSet &TopDst) { 15121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 151366c486f275531df6362b3511fc3af6563561801bTed Kremenek StmtNodeBuilder Bldr(Pred, TopDst, *currBldrCtx); 15146889679d72859960e0fc8d1080487f63c4df1e0aAnna Zaks ExplodedNodeSet Dst; 1515603513d2294c437b37bcf47f326b686e31bd9e84Jordan Rose ValueDecl *Member = M->getMemberDecl(); 151610f77ad7fc5e5cf3f37a9b14ff5843468b8b84d2Ted Kremenek 1517603513d2294c437b37bcf47f326b686e31bd9e84Jordan Rose // Handle static member variables and enum constants accessed via 1518603513d2294c437b37bcf47f326b686e31bd9e84Jordan Rose // member syntax. 1519603513d2294c437b37bcf47f326b686e31bd9e84Jordan Rose if (isa<VarDecl>(Member) || isa<EnumConstantDecl>(Member)) { 1520ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 1521603513d2294c437b37bcf47f326b686e31bd9e84Jordan Rose VisitCommonDeclRefExpr(M, Member, Pred, Dst); 1522ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 15235bd04952d4ae7ca894f583583208f0cec4735a90Ted Kremenek return; 15245bd04952d4ae7ca894f583583208f0cec4735a90Ted Kremenek } 152510f77ad7fc5e5cf3f37a9b14ff5843468b8b84d2Ted Kremenek 1526f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose ProgramStateRef state = Pred->getState(); 1527f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose const LocationContext *LCtx = Pred->getLocationContext(); 1528f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose Expr *BaseExpr = M->getBase(); 1529f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose 153010f77ad7fc5e5cf3f37a9b14ff5843468b8b84d2Ted Kremenek // Handle C++ method calls. 1531603513d2294c437b37bcf47f326b686e31bd9e84Jordan Rose if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(Member)) { 1532f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose if (MD->isInstance()) 1533f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose state = createTemporaryRegionIfNeeded(state, LCtx, BaseExpr); 153410f77ad7fc5e5cf3f37a9b14ff5843468b8b84d2Ted Kremenek 1535f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose SVal MDVal = svalBuilder.getFunctionPointer(MD); 1536f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose state = state->BindExpr(M, LCtx, MDVal); 153720aa40342bd74895128860c081aa84cd85bfa68dJordan Rose 1538f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose Bldr.generateNode(M, Pred, state); 1539ce6644bc1e921833f9b3c10cf7d4a0b78e8d5dc9Jordan Rose return; 154020aa40342bd74895128860c081aa84cd85bfa68dJordan Rose } 154120aa40342bd74895128860c081aa84cd85bfa68dJordan Rose 1542f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose // Handle regular struct fields / member variables. 1543f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose state = createTemporaryRegionIfNeeded(state, LCtx, BaseExpr); 1544f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose SVal baseExprVal = state->getSVal(BaseExpr, LCtx); 1545d27a368f4800b447b970b7c438d0fb4da00838dcJordan Rose 1546603513d2294c437b37bcf47f326b686e31bd9e84Jordan Rose FieldDecl *field = cast<FieldDecl>(Member); 1547e3939d7446959afb6b650fe08e952d0f64ab6794Ted Kremenek SVal L = state->getLValue(field, baseExprVal); 15486b4be2ef4ce49717ff972434975ce3c34c9a1c4cJordan Rose if (M->isGLValue()) { 15496b4be2ef4ce49717ff972434975ce3c34c9a1c4cJordan Rose if (field->getType()->isReferenceType()) { 1550d27a368f4800b447b970b7c438d0fb4da00838dcJordan Rose if (const MemRegion *R = L.getAsRegion()) 1551d27a368f4800b447b970b7c438d0fb4da00838dcJordan Rose L = state->getSVal(R); 1552d27a368f4800b447b970b7c438d0fb4da00838dcJordan Rose else 15536b4be2ef4ce49717ff972434975ce3c34c9a1c4cJordan Rose L = UnknownVal(); 15546b4be2ef4ce49717ff972434975ce3c34c9a1c4cJordan Rose } 15556b4be2ef4ce49717ff972434975ce3c34c9a1c4cJordan Rose 1556d27a368f4800b447b970b7c438d0fb4da00838dcJordan Rose Bldr.generateNode(M, Pred, state->BindExpr(M, LCtx, L), 0, 1557d27a368f4800b447b970b7c438d0fb4da00838dcJordan Rose ProgramPoint::PostLValueKind); 15586b4be2ef4ce49717ff972434975ce3c34c9a1c4cJordan Rose } else { 1559ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 1560bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek evalLoad(Dst, M, M, Pred, state, L); 1561ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 1562ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks } 1563469ecbded3616416ef938ed94a67f86149faf226Ted Kremenek} 1564469ecbded3616416ef938ed94a67f86149faf226Ted Kremenek 15659c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek/// evalBind - Handle the semantics of binding a value to a specific location. 15669c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek/// This method is used by evalStore and (soon) VisitDeclStmt, and others. 15679c378f705405d37f49795d5e915989de774fe11fTed Kremenekvoid ExprEngine::evalBind(ExplodedNodeSet &Dst, const Stmt *StoreE, 156893bd5ca766c4d7906878f4ffe76ce1b2080e540bJordy Rose ExplodedNode *Pred, 156932a549a64922af0903bdb777613ae7ae4490b70fTed Kremenek SVal location, SVal Val, 15703682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose bool atDeclInit, const ProgramPoint *PP) { 15713682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose 15723682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose const LocationContext *LC = Pred->getLocationContext(); 15733682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose PostStmt PS(StoreE, LC); 15743682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose if (!PP) 15753682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose PP = &PS; 1576b9bbd592c7ea72ada8d982e40a729beb9b53371eTed Kremenek 1577b107c4b7efb907d75620cd3c17f82fe27dc5b745Ted Kremenek // Do a previsit of the bind. 1578fe27971d54d26997149d6b84057f04ff398d1d5dJordy Rose ExplodedNodeSet CheckedSet; 1579fe27971d54d26997149d6b84057f04ff398d1d5dJordy Rose getCheckerManager().runCheckersForBind(CheckedSet, Pred, location, Val, 15803682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose StoreE, *this, *PP); 1581b9bbd592c7ea72ada8d982e40a729beb9b53371eTed Kremenek 158232a549a64922af0903bdb777613ae7ae4490b70fTed Kremenek // If the location is not a 'Loc', it will already be handled by 158332a549a64922af0903bdb777613ae7ae4490b70fTed Kremenek // the checkers. There is nothing left to do. 158432a549a64922af0903bdb777613ae7ae4490b70fTed Kremenek if (!isa<Loc>(location)) { 158532a549a64922af0903bdb777613ae7ae4490b70fTed Kremenek Dst = CheckedSet; 158632a549a64922af0903bdb777613ae7ae4490b70fTed Kremenek return; 158732a549a64922af0903bdb777613ae7ae4490b70fTed Kremenek } 158832a549a64922af0903bdb777613ae7ae4490b70fTed Kremenek 15896b6152ba96c164a292cc0b8d8b1d4cecbec27a60Anna Zaks ExplodedNodeSet TmpDst; 159066c486f275531df6362b3511fc3af6563561801bTed Kremenek StmtNodeBuilder Bldr(CheckedSet, TmpDst, *currBldrCtx); 15916b6152ba96c164a292cc0b8d8b1d4cecbec27a60Anna Zaks 1592b107c4b7efb907d75620cd3c17f82fe27dc5b745Ted Kremenek for (ExplodedNodeSet::iterator I = CheckedSet.begin(), E = CheckedSet.end(); 1593b107c4b7efb907d75620cd3c17f82fe27dc5b745Ted Kremenek I!=E; ++I) { 15943d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks ExplodedNode *PredI = *I; 15953d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks ProgramStateRef state = PredI->getState(); 159632a549a64922af0903bdb777613ae7ae4490b70fTed Kremenek 159732a549a64922af0903bdb777613ae7ae4490b70fTed Kremenek // When binding the value, pass on the hint that this is a initialization. 159832a549a64922af0903bdb777613ae7ae4490b70fTed Kremenek // For initializations, we do not need to inform clients of region 159932a549a64922af0903bdb777613ae7ae4490b70fTed Kremenek // changes. 160032a549a64922af0903bdb777613ae7ae4490b70fTed Kremenek state = state->bindLoc(cast<Loc>(location), 160132a549a64922af0903bdb777613ae7ae4490b70fTed Kremenek Val, /* notifyChanges = */ !atDeclInit); 160232a549a64922af0903bdb777613ae7ae4490b70fTed Kremenek 16033d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks const MemRegion *LocReg = 0; 160432a549a64922af0903bdb777613ae7ae4490b70fTed Kremenek if (loc::MemRegionVal *LocRegVal = dyn_cast<loc::MemRegionVal>(&location)) { 16053d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks LocReg = LocRegVal->getRegion(); 160632a549a64922af0903bdb777613ae7ae4490b70fTed Kremenek } 16073682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose 16083d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks const ProgramPoint L = PostStore(StoreE, LC, LocReg, 0); 1609fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose Bldr.generateNode(L, state, PredI); 1610b107c4b7efb907d75620cd3c17f82fe27dc5b745Ted Kremenek } 16116b6152ba96c164a292cc0b8d8b1d4cecbec27a60Anna Zaks Dst.insert(TmpDst); 1612a8538d902fce9cfec20f39b34492268b51643819Ted Kremenek} 1613a8538d902fce9cfec20f39b34492268b51643819Ted Kremenek 16149c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek/// evalStore - Handle the semantics of a store via an assignment. 1615a8538d902fce9cfec20f39b34492268b51643819Ted Kremenek/// @param Dst The node set to store generated state nodes 16162e6f5b823912ae76211427cb8684c9eaa6e53a1fJames Dennett/// @param AssignE The assignment expression if the store happens in an 1617e8a4d7d0064b357a30fe7ee4f2ddc02f9ffc0357Zhongxing Xu/// assignment. 16182e6f5b823912ae76211427cb8684c9eaa6e53a1fJames Dennett/// @param LocationE The location expression that is stored to. 1619a8538d902fce9cfec20f39b34492268b51643819Ted Kremenek/// @param state The current simulation state 1620a8538d902fce9cfec20f39b34492268b51643819Ted Kremenek/// @param location The location to store the value 1621a8538d902fce9cfec20f39b34492268b51643819Ted Kremenek/// @param Val The value to be stored 16229c378f705405d37f49795d5e915989de774fe11fTed Kremenekvoid ExprEngine::evalStore(ExplodedNodeSet &Dst, const Expr *AssignE, 16239c378f705405d37f49795d5e915989de774fe11fTed Kremenek const Expr *LocationE, 16249c378f705405d37f49795d5e915989de774fe11fTed Kremenek ExplodedNode *Pred, 16258bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek ProgramStateRef state, SVal location, SVal Val, 1626ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek const ProgramPointTag *tag) { 162714429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis // Proceed with the store. We use AssignE as the anchor for the PostStore 162814429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis // ProgramPoint if it is non-NULL, and LocationE otherwise. 162914429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis const Expr *StoreE = AssignE ? AssignE : LocationE; 163014429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis 16311b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek // Evaluate the location (checks for bad dereferences). 1632b4b817d704287836b52b34369009e682f208aa2bTed Kremenek ExplodedNodeSet Tmp; 1633bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek evalLocation(Tmp, AssignE, LocationE, Pred, state, location, tag, false); 16341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1635b4b817d704287836b52b34369009e682f208aa2bTed Kremenek if (Tmp.empty()) 16361b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek return; 1637b0533965f1b4db020692e3b23ca7b3bc15bf5897Ted Kremenek 163873c498a08f4968b6987d1453c7b77929dcc6d5f7Argyrios Kyrtzidis if (location.isUndef()) 163973c498a08f4968b6987d1453c7b77929dcc6d5f7Argyrios Kyrtzidis return; 1640a8538d902fce9cfec20f39b34492268b51643819Ted Kremenek 1641b4b817d704287836b52b34369009e682f208aa2bTed Kremenek for (ExplodedNodeSet::iterator NI=Tmp.begin(), NE=Tmp.end(); NI!=NE; ++NI) 16423d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks evalBind(Dst, StoreE, *NI, location, Val, false); 16431b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek} 16441b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek 1645bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenekvoid ExprEngine::evalLoad(ExplodedNodeSet &Dst, 1646bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek const Expr *NodeEx, 1647bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek const Expr *BoundEx, 1648bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek ExplodedNode *Pred, 1649bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek ProgramStateRef state, 1650bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek SVal location, 1651bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek const ProgramPointTag *tag, 1652bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek QualType LoadTy) 1653bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek{ 1654cca8ab155e8c20b98ba2d90eb2b1c228895e06fdZhanyong Wan assert(!isa<NonLoc>(location) && "location cannot be a NonLoc."); 165514429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis 16565b8c69494881b7d35bc6244b4a19be0cc2eab368Jordan Rose // Are we loading from a region? This actually results in two loads; one 1657852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek // to fetch the address of the referenced value and one to fetch the 1658852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek // referenced value. 16599697934650354bed2e509d8e7e44f21a1fb00f76Ted Kremenek if (const TypedValueRegion *TR = 16609697934650354bed2e509d8e7e44f21a1fb00f76Ted Kremenek dyn_cast_or_null<TypedValueRegion>(location.getAsRegion())) { 1661b9bbd592c7ea72ada8d982e40a729beb9b53371eTed Kremenek 1662018220c343c103b7dfaa117a7a474c7a7fd6d068Zhongxing Xu QualType ValTy = TR->getValueType(); 1663852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek if (const ReferenceType *RT = ValTy->getAs<ReferenceType>()) { 1664ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek static SimpleProgramPointTag 1665ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek loadReferenceTag("ExprEngine : Load Reference"); 1666852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek ExplodedNodeSet Tmp; 1667bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek evalLoadCommon(Tmp, NodeEx, BoundEx, Pred, state, 1668bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek location, &loadReferenceTag, 1669852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek getContext().getPointerType(RT->getPointeeType())); 1670852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek 1671852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek // Perform the load from the referenced value. 1672852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end() ; I!=E; ++I) { 1673db5e8cd095d1ffdd18f5620ad2348b5f386bebe3Anna Zaks state = (*I)->getState(); 1674bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek location = state->getSVal(BoundEx, (*I)->getLocationContext()); 1675bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek evalLoadCommon(Dst, NodeEx, BoundEx, *I, state, location, tag, LoadTy); 1676b9bbd592c7ea72ada8d982e40a729beb9b53371eTed Kremenek } 1677852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek return; 1678852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek } 1679852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek } 1680b9bbd592c7ea72ada8d982e40a729beb9b53371eTed Kremenek 1681bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek evalLoadCommon(Dst, NodeEx, BoundEx, Pred, state, location, tag, LoadTy); 1682852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek} 1683852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek 1684bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenekvoid ExprEngine::evalLoadCommon(ExplodedNodeSet &Dst, 1685bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek const Expr *NodeEx, 1686bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek const Expr *BoundEx, 1687bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek ExplodedNode *Pred, 1688bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek ProgramStateRef state, 1689bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek SVal location, 1690bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek const ProgramPointTag *tag, 1691bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek QualType LoadTy) { 1692bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek assert(NodeEx); 1693bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek assert(BoundEx); 16941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // Evaluate the location (checks for bad dereferences). 1695b4b817d704287836b52b34369009e682f208aa2bTed Kremenek ExplodedNodeSet Tmp; 1696bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek evalLocation(Tmp, NodeEx, BoundEx, Pred, state, location, tag, true); 1697b4b817d704287836b52b34369009e682f208aa2bTed Kremenek if (Tmp.empty()) 16981b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek return; 1699b9bbd592c7ea72ada8d982e40a729beb9b53371eTed Kremenek 170066c486f275531df6362b3511fc3af6563561801bTed Kremenek StmtNodeBuilder Bldr(Tmp, Dst, *currBldrCtx); 170173c498a08f4968b6987d1453c7b77929dcc6d5f7Argyrios Kyrtzidis if (location.isUndef()) 170273c498a08f4968b6987d1453c7b77929dcc6d5f7Argyrios Kyrtzidis return; 1703b9bbd592c7ea72ada8d982e40a729beb9b53371eTed Kremenek 17041b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek // Proceed with the load. 1705b4b817d704287836b52b34369009e682f208aa2bTed Kremenek for (ExplodedNodeSet::iterator NI=Tmp.begin(), NE=Tmp.end(); NI!=NE; ++NI) { 1706db5e8cd095d1ffdd18f5620ad2348b5f386bebe3Anna Zaks state = (*NI)->getState(); 17075eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek const LocationContext *LCtx = (*NI)->getLocationContext(); 170896ebad66c451d79c9f57b1edb31efaeeb23b9a01Ted Kremenek 1709b4b817d704287836b52b34369009e682f208aa2bTed Kremenek if (location.isUnknown()) { 1710b4b817d704287836b52b34369009e682f208aa2bTed Kremenek // This is important. We must nuke the old binding. 1711bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek Bldr.generateNode(NodeEx, *NI, 1712bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek state->BindExpr(BoundEx, LCtx, UnknownVal()), 1713fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose tag, ProgramPoint::PostLoadKind); 1714b4b817d704287836b52b34369009e682f208aa2bTed Kremenek } 1715b4b817d704287836b52b34369009e682f208aa2bTed Kremenek else { 171696ebad66c451d79c9f57b1edb31efaeeb23b9a01Ted Kremenek if (LoadTy.isNull()) 1717bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek LoadTy = BoundEx->getType(); 171896ebad66c451d79c9f57b1edb31efaeeb23b9a01Ted Kremenek SVal V = state->getSVal(cast<Loc>(location), LoadTy); 1719bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek Bldr.generateNode(NodeEx, *NI, 1720bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek state->bindExprAndLocation(BoundEx, LCtx, location, V), 1721fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose tag, ProgramPoint::PostLoadKind); 1722b4b817d704287836b52b34369009e682f208aa2bTed Kremenek } 1723d5b499d43c3526fae7f9ebb6e2d50e79d3496cedZhongxing Xu } 17241b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek} 17251b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek 1726bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenekvoid ExprEngine::evalLocation(ExplodedNodeSet &Dst, 1727bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek const Stmt *NodeEx, 1728bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek const Stmt *BoundEx, 1729bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek ExplodedNode *Pred, 1730bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek ProgramStateRef state, 1731bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek SVal location, 1732bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek const ProgramPointTag *tag, 1733bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek bool isLoad) { 173466c486f275531df6362b3511fc3af6563561801bTed Kremenek StmtNodeBuilder BldrTop(Pred, Dst, *currBldrCtx); 173500b1ad2d56f3e39f95c3f61bf511a531ab6a4fa5Zhongxing Xu // Early checks for performance reason. 1736769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis if (location.isUnknown()) { 1737b4b817d704287836b52b34369009e682f208aa2bTed Kremenek return; 1738b4b817d704287836b52b34369009e682f208aa2bTed Kremenek } 1739b9bbd592c7ea72ada8d982e40a729beb9b53371eTed Kremenek 17409c0d6891b3ec4b0d20b8a295946c0dc5426d147cArgyrios Kyrtzidis ExplodedNodeSet Src; 1741ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks BldrTop.takeNodes(Pred); 174266c486f275531df6362b3511fc3af6563561801bTed Kremenek StmtNodeBuilder Bldr(Pred, Src, *currBldrCtx); 1743ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks if (Pred->getState() != state) { 1744eb48bd1dd4168ab206a330bf523659170291a6a0Argyrios Kyrtzidis // Associate this new state with an ExplodedNode. 1745eb48bd1dd4168ab206a330bf523659170291a6a0Argyrios Kyrtzidis // FIXME: If I pass null tag, the graph is incorrect, e.g for 1746eb48bd1dd4168ab206a330bf523659170291a6a0Argyrios Kyrtzidis // int *p; 1747eb48bd1dd4168ab206a330bf523659170291a6a0Argyrios Kyrtzidis // p = 0; 1748eb48bd1dd4168ab206a330bf523659170291a6a0Argyrios Kyrtzidis // *p = 0xDEADBEEF; 1749eb48bd1dd4168ab206a330bf523659170291a6a0Argyrios Kyrtzidis // "p = 0" is not noted as "Null pointer value stored to 'p'" but 1750eb48bd1dd4168ab206a330bf523659170291a6a0Argyrios Kyrtzidis // instead "int *p" is noted as 1751eb48bd1dd4168ab206a330bf523659170291a6a0Argyrios Kyrtzidis // "Variable 'p' initialized to a null pointer value" 1752ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek 1753fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose static SimpleProgramPointTag tag("ExprEngine: Location"); 1754fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose Bldr.generateNode(NodeEx, Pred, state, &tag); 17550296c22557b3735e2ffeff690eb46fb0e9152bccTed Kremenek } 1756ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks ExplodedNodeSet Tmp; 1757bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek getCheckerManager().runCheckersForLocation(Tmp, Src, location, isLoad, 1758bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek NodeEx, BoundEx, *this); 1759ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks BldrTop.addNodes(Tmp); 1760ec96a2d52d16e150baaf629cd35e3fabff5d8915Ted Kremenek} 1761ec96a2d52d16e150baaf629cd35e3fabff5d8915Ted Kremenek 17626c7511db998817e64f2e124013e7d7c9a430c580Ted Kremenekstd::pair<const ProgramPointTag *, const ProgramPointTag*> 17630caa2d47b84337e942b3f6652adfafe4ae506cfeTed KremenekExprEngine::geteagerlyAssumeBinOpBifurcationTags() { 17646c7511db998817e64f2e124013e7d7c9a430c580Ted Kremenek static SimpleProgramPointTag 17650caa2d47b84337e942b3f6652adfafe4ae506cfeTed Kremenek eagerlyAssumeBinOpBifurcationTrue("ExprEngine : Eagerly Assume True"), 17660caa2d47b84337e942b3f6652adfafe4ae506cfeTed Kremenek eagerlyAssumeBinOpBifurcationFalse("ExprEngine : Eagerly Assume False"); 17670caa2d47b84337e942b3f6652adfafe4ae506cfeTed Kremenek return std::make_pair(&eagerlyAssumeBinOpBifurcationTrue, 17680caa2d47b84337e942b3f6652adfafe4ae506cfeTed Kremenek &eagerlyAssumeBinOpBifurcationFalse); 17696c7511db998817e64f2e124013e7d7c9a430c580Ted Kremenek} 17706c7511db998817e64f2e124013e7d7c9a430c580Ted Kremenek 17710caa2d47b84337e942b3f6652adfafe4ae506cfeTed Kremenekvoid ExprEngine::evalEagerlyAssumeBinOpBifurcation(ExplodedNodeSet &Dst, 17720caa2d47b84337e942b3f6652adfafe4ae506cfeTed Kremenek ExplodedNodeSet &Src, 17730caa2d47b84337e942b3f6652adfafe4ae506cfeTed Kremenek const Expr *Ex) { 177466c486f275531df6362b3511fc3af6563561801bTed Kremenek StmtNodeBuilder Bldr(Src, Dst, *currBldrCtx); 177586b39f20d5091ca3fdcbeb4a22766aaffdf6ac35Ted Kremenek 1776031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu for (ExplodedNodeSet::iterator I=Src.begin(), E=Src.end(); I!=E; ++I) { 1777031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu ExplodedNode *Pred = *I; 1778b293902c5cfa18365ffb0e00763849c9808a2ad1Ted Kremenek // Test if the previous node was as the same expression. This can happen 1779b293902c5cfa18365ffb0e00763849c9808a2ad1Ted Kremenek // when the expression fails to evaluate to anything meaningful and 1780b293902c5cfa18365ffb0e00763849c9808a2ad1Ted Kremenek // (as an optimization) we don't generate a node. 17811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump ProgramPoint P = Pred->getLocation(); 1782b293902c5cfa18365ffb0e00763849c9808a2ad1Ted Kremenek if (!isa<PostStmt>(P) || cast<PostStmt>(P).getStmt() != Ex) { 1783b293902c5cfa18365ffb0e00763849c9808a2ad1Ted Kremenek continue; 17841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 1785b293902c5cfa18365ffb0e00763849c9808a2ad1Ted Kremenek 17868bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek ProgramStateRef state = Pred->getState(); 17875eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek SVal V = state->getSVal(Ex, Pred->getLocationContext()); 17885344baa704f42b22d9df25c24ffbbf6b4716603bAnna Zaks nonloc::SymbolVal *SEV = dyn_cast<nonloc::SymbolVal>(&V); 17895344baa704f42b22d9df25c24ffbbf6b4716603bAnna Zaks if (SEV && SEV->isExpression()) { 17906c7511db998817e64f2e124013e7d7c9a430c580Ted Kremenek const std::pair<const ProgramPointTag *, const ProgramPointTag*> &tags = 17910caa2d47b84337e942b3f6652adfafe4ae506cfeTed Kremenek geteagerlyAssumeBinOpBifurcationTags(); 17926c7511db998817e64f2e124013e7d7c9a430c580Ted Kremenek 179348af2a9c1ed3259512f2d1431720add1fbe8fb5fTed Kremenek // First assume that the condition is true. 17948bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek if (ProgramStateRef StateTrue = state->assume(*SEV, true)) { 179586b39f20d5091ca3fdcbeb4a22766aaffdf6ac35Ted Kremenek SVal Val = svalBuilder.makeIntVal(1U, Ex->getType()); 17965eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek StateTrue = StateTrue->BindExpr(Ex, Pred->getLocationContext(), Val); 1797fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose Bldr.generateNode(Ex, Pred, StateTrue, tags.first); 179848af2a9c1ed3259512f2d1431720add1fbe8fb5fTed Kremenek } 17991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 180048af2a9c1ed3259512f2d1431720add1fbe8fb5fTed Kremenek // Next, assume that the condition is false. 18018bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek if (ProgramStateRef StateFalse = state->assume(*SEV, false)) { 180286b39f20d5091ca3fdcbeb4a22766aaffdf6ac35Ted Kremenek SVal Val = svalBuilder.makeIntVal(0U, Ex->getType()); 18035eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek StateFalse = StateFalse->BindExpr(Ex, Pred->getLocationContext(), Val); 1804fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose Bldr.generateNode(Ex, Pred, StateFalse, tags.second); 180548af2a9c1ed3259512f2d1431720add1fbe8fb5fTed Kremenek } 180648af2a9c1ed3259512f2d1431720add1fbe8fb5fTed Kremenek } 180748af2a9c1ed3259512f2d1431720add1fbe8fb5fTed Kremenek } 180848af2a9c1ed3259512f2d1431720add1fbe8fb5fTed Kremenek} 180948af2a9c1ed3259512f2d1431720add1fbe8fb5fTed Kremenek 1810df5faf5e7ae6823d0af0b801c4ac26d47f2cee97Chad Rosiervoid ExprEngine::VisitGCCAsmStmt(const GCCAsmStmt *A, ExplodedNode *Pred, 1811df5faf5e7ae6823d0af0b801c4ac26d47f2cee97Chad Rosier ExplodedNodeSet &Dst) { 181266c486f275531df6362b3511fc3af6563561801bTed Kremenek StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx); 1813a81d3d434e6581ff354eaf5b2a3c25c75771a792Erik Verbruggen // We have processed both the inputs and the outputs. All of the outputs 1814a81d3d434e6581ff354eaf5b2a3c25c75771a792Erik Verbruggen // should evaluate to Locs. Nuke all of their values. 18151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1816a81d3d434e6581ff354eaf5b2a3c25c75771a792Erik Verbruggen // FIXME: Some day in the future it would be nice to allow a "plug-in" 1817a81d3d434e6581ff354eaf5b2a3c25c75771a792Erik Verbruggen // which interprets the inline asm and stores proper results in the 1818a81d3d434e6581ff354eaf5b2a3c25c75771a792Erik Verbruggen // outputs. 18191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1820a81d3d434e6581ff354eaf5b2a3c25c75771a792Erik Verbruggen ProgramStateRef state = Pred->getState(); 18211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1822df5faf5e7ae6823d0af0b801c4ac26d47f2cee97Chad Rosier for (GCCAsmStmt::const_outputs_iterator OI = A->begin_outputs(), 1823a81d3d434e6581ff354eaf5b2a3c25c75771a792Erik Verbruggen OE = A->end_outputs(); OI != OE; ++OI) { 1824a81d3d434e6581ff354eaf5b2a3c25c75771a792Erik Verbruggen SVal X = state->getSVal(*OI, Pred->getLocationContext()); 1825a81d3d434e6581ff354eaf5b2a3c25c75771a792Erik Verbruggen assert (!isa<NonLoc>(X)); // Should be an Lval, or unknown, undef. 18261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1827a81d3d434e6581ff354eaf5b2a3c25c75771a792Erik Verbruggen if (isa<Loc>(X)) 1828a81d3d434e6581ff354eaf5b2a3c25c75771a792Erik Verbruggen state = state->bindLoc(cast<Loc>(X), UnknownVal()); 1829ef44bfb9d0f15ba0391f8346c9f01355fb450a09Ted Kremenek } 18301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1831a81d3d434e6581ff354eaf5b2a3c25c75771a792Erik Verbruggen Bldr.generateNode(A, Pred, state); 1832ef44bfb9d0f15ba0391f8346c9f01355fb450a09Ted Kremenek} 1833ef44bfb9d0f15ba0391f8346c9f01355fb450a09Ted Kremenek 18348cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosiervoid ExprEngine::VisitMSAsmStmt(const MSAsmStmt *A, ExplodedNode *Pred, 18358cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier ExplodedNodeSet &Dst) { 183666c486f275531df6362b3511fc3af6563561801bTed Kremenek StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx); 18378cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier Bldr.generateNode(A, Pred, Pred->getState()); 18388cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier} 18398cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier 1840094bef56a7900f13bb777f9a352704104b1458e7Ted Kremenek//===----------------------------------------------------------------------===// 1841e01c98767dfd7153c3c84637c36659e3bbe16ff7Ted Kremenek// Visualization. 1842ee98546b0d5f3439c4a590b0d7d1545af794a0ecTed Kremenek//===----------------------------------------------------------------------===// 1843ee98546b0d5f3439c4a590b0d7d1545af794a0ecTed Kremenek 1844aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek#ifndef NDEBUG 1845d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisstatic ExprEngine* GraphPrintCheckerState; 1846e97ca065c91ff9ca2a2a42eb443eaa553c40441cTed Kremenekstatic SourceManager* GraphPrintSourceManager; 18473b4f6702860208692f6ef28401e68de4e3ff9af9Ted Kremenek 1848aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremeneknamespace llvm { 1849aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenektemplate<> 185047491f8b7adf9d42a404d44c073e8a5308fa6cfcDouglas Gregorstruct DOTGraphTraits<ExplodedNode*> : 1851aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek public DefaultDOTGraphTraits { 1852006b0eb3e11162d8c06372db813ac9f71a7a16e8Tobias Grosser 1853006b0eb3e11162d8c06372db813ac9f71a7a16e8Tobias Grosser DOTGraphTraits (bool isSimple=false) : DefaultDOTGraphTraits(isSimple) {} 1854006b0eb3e11162d8c06372db813ac9f71a7a16e8Tobias Grosser 1855d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis // FIXME: Since we do not cache error nodes in ExprEngine now, this does not 1856ec9227fea66c3439991fc84b0d33b0a8b4b8875eZhongxing Xu // work. 18579c378f705405d37f49795d5e915989de774fe11fTed Kremenek static std::string getNodeAttributes(const ExplodedNode *N, void*) { 18581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 185910f51e8785e43d5a22acc2d2a638307c582949c2Ted Kremenek#if 0 186010f51e8785e43d5a22acc2d2a638307c582949c2Ted Kremenek // FIXME: Replace with a general scheme to tell if the node is 186110f51e8785e43d5a22acc2d2a638307c582949c2Ted Kremenek // an error node. 1862a3fadfcce5911742801a302cac82d4fe54d5c682Ted Kremenek if (GraphPrintCheckerState->isImplicitNullDeref(N) || 18639dca062461a6244cf0f733346657fa3eee853f9bTed Kremenek GraphPrintCheckerState->isExplicitNullDeref(N) || 18644a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek GraphPrintCheckerState->isUndefDeref(N) || 18654a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek GraphPrintCheckerState->isUndefStore(N) || 18664a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek GraphPrintCheckerState->isUndefControlFlow(N) || 18675e03fcb5420c33207433dd6f800588e256dd9bdbTed Kremenek GraphPrintCheckerState->isUndefResult(N) || 18682ded35a576e3899553ea0ccfcbf5cbdb3d8cf664Ted Kremenek GraphPrintCheckerState->isBadCall(N) || 18692ded35a576e3899553ea0ccfcbf5cbdb3d8cf664Ted Kremenek GraphPrintCheckerState->isUndefArg(N)) 1870a3fadfcce5911742801a302cac82d4fe54d5c682Ted Kremenek return "color=\"red\",style=\"filled\""; 18711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 18728cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek if (GraphPrintCheckerState->isNoReturnCall(N)) 18738cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek return "color=\"blue\",style=\"filled\""; 18742055effed54d614b51e3501a174c9b1fe92e4de4Zhongxing Xu#endif 1875a3fadfcce5911742801a302cac82d4fe54d5c682Ted Kremenek return ""; 1876a3fadfcce5911742801a302cac82d4fe54d5c682Ted Kremenek } 18771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 187828038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose static void printLocation(llvm::raw_ostream &Out, SourceLocation SLoc) { 187928038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose if (SLoc.isFileID()) { 188028038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose Out << "\\lline=" 188128038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose << GraphPrintSourceManager->getExpansionLineNumber(SLoc) 188228038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose << " col=" 188328038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose << GraphPrintSourceManager->getExpansionColumnNumber(SLoc) 188428038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose << "\\l"; 188528038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose } 188628038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose } 188728038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose 18889c378f705405d37f49795d5e915989de774fe11fTed Kremenek static std::string getNodeLabel(const ExplodedNode *N, void*){ 18891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 189053ba0b636194dbeaa65a6f85316c9397a0c5298bTed Kremenek std::string sbuf; 189153ba0b636194dbeaa65a6f85316c9397a0c5298bTed Kremenek llvm::raw_string_ostream Out(sbuf); 1892803c9edd06e8f936821525d36b1d8cc131e37d44Ted Kremenek 1893803c9edd06e8f936821525d36b1d8cc131e37d44Ted Kremenek // Program Location. 1894aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek ProgramPoint Loc = N->getLocation(); 18951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1896aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek switch (Loc.getKind()) { 18970b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks case ProgramPoint::BlockEntranceKind: { 18981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Out << "Block Entrance: B" 1899aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek << cast<BlockEntrance>(Loc).getBlock()->getBlockID(); 19000b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks if (const NamedDecl *ND = 19010b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks dyn_cast<NamedDecl>(Loc.getLocationContext()->getDecl())) { 19020b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks Out << " ("; 19030b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks ND->printName(Out); 19040b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks Out << ")"; 19050b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks } 1906aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek break; 19070b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks } 19081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1909aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek case ProgramPoint::BlockExitKind: 1910aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek assert (false); 1911aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek break; 19121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1913102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor case ProgramPoint::CallEnterKind: 1914102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor Out << "CallEnter"; 1915102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor break; 1916102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor 19170b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks case ProgramPoint::CallExitBeginKind: 19180b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks Out << "CallExitBegin"; 19190b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks break; 19200b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks 19210b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks case ProgramPoint::CallExitEndKind: 19220b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks Out << "CallExitEnd"; 19230b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks break; 19240b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks 19250b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks case ProgramPoint::PostStmtPurgeDeadSymbolsKind: 19260b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks Out << "PostStmtPurgeDeadSymbols"; 19270b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks break; 19280b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks 19290b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks case ProgramPoint::PreStmtPurgeDeadSymbolsKind: 19300b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks Out << "PreStmtPurgeDeadSymbols"; 1931102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor break; 1932102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor 19335903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks case ProgramPoint::EpsilonKind: 19345903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks Out << "Epsilon Point"; 19355903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks break; 19365903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks 193728038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose case ProgramPoint::PreImplicitCallKind: { 193828038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose ImplicitCallPoint *PC = cast<ImplicitCallPoint>(&Loc); 193928038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose Out << "PreCall: "; 194028038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose 194128038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose // FIXME: Get proper printing options. 194228038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose PC->getDecl()->print(Out, LangOptions()); 194328038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose printLocation(Out, PC->getLocation()); 194428038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose break; 194528038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose } 194628038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose 194728038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose case ProgramPoint::PostImplicitCallKind: { 194828038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose ImplicitCallPoint *PC = cast<ImplicitCallPoint>(&Loc); 194928038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose Out << "PostCall: "; 195028038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose 195128038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose // FIXME: Get proper printing options. 195228038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose PC->getDecl()->print(Out, LangOptions()); 195328038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose printLocation(Out, PC->getLocation()); 195428038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose break; 195528038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose } 195628038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose 1957aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek default: { 19585f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek if (StmtPoint *L = dyn_cast<StmtPoint>(&Loc)) { 19599c378f705405d37f49795d5e915989de774fe11fTed Kremenek const Stmt *S = L->getStmt(); 19608c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek 196131ba6135375433b617a8587ea6cc836a014ebd86Roman Divacky Out << S->getStmtClassName() << ' ' << (const void*) S << ' '; 1962e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner LangOptions LO; // FIXME. 1963e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner S->printPretty(Out, 0, PrintingPolicy(LO)); 196428038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose printLocation(Out, S->getLocStart()); 19651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 19665f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek if (isa<PreStmt>(Loc)) 19671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Out << "\\lPreStmt\\l;"; 19685f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek else if (isa<PostLoad>(Loc)) 19697090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek Out << "\\lPostLoad\\l;"; 19707090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek else if (isa<PostStore>(Loc)) 19717090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek Out << "\\lPostStore\\l"; 19727090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek else if (isa<PostLValue>(Loc)) 19737090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek Out << "\\lPostLValue\\l"; 19741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 197510f51e8785e43d5a22acc2d2a638307c582949c2Ted Kremenek#if 0 197610f51e8785e43d5a22acc2d2a638307c582949c2Ted Kremenek // FIXME: Replace with a general scheme to determine 197710f51e8785e43d5a22acc2d2a638307c582949c2Ted Kremenek // the name of the check. 19788c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek if (GraphPrintCheckerState->isImplicitNullDeref(N)) 19798c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek Out << "\\|Implicit-Null Dereference.\\l"; 19808c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek else if (GraphPrintCheckerState->isExplicitNullDeref(N)) 19818c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek Out << "\\|Explicit-Null Dereference.\\l"; 19828c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek else if (GraphPrintCheckerState->isUndefDeref(N)) 19838c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek Out << "\\|Dereference of undefialied value.\\l"; 19848c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek else if (GraphPrintCheckerState->isUndefStore(N)) 19858c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek Out << "\\|Store to Undefined Loc."; 19868c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek else if (GraphPrintCheckerState->isUndefResult(N)) 19878c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek Out << "\\|Result of operation is undefined."; 19888c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek else if (GraphPrintCheckerState->isNoReturnCall(N)) 19898c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek Out << "\\|Call to function marked \"noreturn\"."; 19908c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek else if (GraphPrintCheckerState->isBadCall(N)) 19918c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek Out << "\\|Call to NULL/Undefined."; 19928c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek else if (GraphPrintCheckerState->isUndefArg(N)) 19938c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek Out << "\\|Argument in call is undefined"; 199410f51e8785e43d5a22acc2d2a638307c582949c2Ted Kremenek#endif 19951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 19968c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek break; 19978c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek } 19988c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek 19999c378f705405d37f49795d5e915989de774fe11fTed Kremenek const BlockEdge &E = cast<BlockEdge>(Loc); 2000aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek Out << "Edge: (B" << E.getSrc()->getBlockID() << ", B" 2001aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek << E.getDst()->getBlockID() << ')'; 20021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 20039c378f705405d37f49795d5e915989de774fe11fTed Kremenek if (const Stmt *T = E.getSrc()->getTerminator()) { 20041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2005e97ca065c91ff9ca2a2a42eb443eaa553c40441cTed Kremenek SourceLocation SLoc = T->getLocStart(); 20061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2007b38911f16b4943548db6a3695fc6ae23070b25d2Ted Kremenek Out << "\\|Terminator: "; 2008e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner LangOptions LO; // FIXME. 2009e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner E.getSrc()->printTerminator(Out, LO); 20101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 20119b5551d7f0209cec8b9c555cf70e893940674e5cTed Kremenek if (SLoc.isFileID()) { 20129b5551d7f0209cec8b9c555cf70e893940674e5cTed Kremenek Out << "\\lline=" 2013642116259e8df6286063a17361c20e95b5017a0aChandler Carruth << GraphPrintSourceManager->getExpansionLineNumber(SLoc) 20147da5aea7669e6db3e593162b8a123aef06a04d07Chris Lattner << " col=" 2015a77c031cb66f75d22672070052cc6e0205289ff8Chandler Carruth << GraphPrintSourceManager->getExpansionColumnNumber(SLoc); 20169b5551d7f0209cec8b9c555cf70e893940674e5cTed Kremenek } 20171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2018daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek if (isa<SwitchStmt>(T)) { 20199c378f705405d37f49795d5e915989de774fe11fTed Kremenek const Stmt *Label = E.getDst()->getLabel(); 20201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 20211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (Label) { 20229c378f705405d37f49795d5e915989de774fe11fTed Kremenek if (const CaseStmt *C = dyn_cast<CaseStmt>(Label)) { 2023daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek Out << "\\lcase "; 2024e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner LangOptions LO; // FIXME. 2025e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner C->getLHS()->printPretty(Out, 0, PrintingPolicy(LO)); 20261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 20279c378f705405d37f49795d5e915989de774fe11fTed Kremenek if (const Stmt *RHS = C->getRHS()) { 2028daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek Out << " .. "; 2029e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner RHS->printPretty(Out, 0, PrintingPolicy(LO)); 2030daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek } 20311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2032daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek Out << ":"; 2033daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek } 2034daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek else { 2035daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek assert (isa<DefaultStmt>(Label)); 2036daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek Out << "\\ldefault:"; 2037daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek } 2038daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek } 20391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump else 2040daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek Out << "\\l(implicit) default:"; 2041daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek } 2042daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek else if (isa<IndirectGotoStmt>(T)) { 2043b38911f16b4943548db6a3695fc6ae23070b25d2Ted Kremenek // FIXME 2044b38911f16b4943548db6a3695fc6ae23070b25d2Ted Kremenek } 2045b38911f16b4943548db6a3695fc6ae23070b25d2Ted Kremenek else { 2046b38911f16b4943548db6a3695fc6ae23070b25d2Ted Kremenek Out << "\\lCondition: "; 2047b38911f16b4943548db6a3695fc6ae23070b25d2Ted Kremenek if (*E.getSrc()->succ_begin() == E.getDst()) 2048b38911f16b4943548db6a3695fc6ae23070b25d2Ted Kremenek Out << "true"; 2049b38911f16b4943548db6a3695fc6ae23070b25d2Ted Kremenek else 20501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Out << "false"; 2051b38911f16b4943548db6a3695fc6ae23070b25d2Ted Kremenek } 20521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2053b38911f16b4943548db6a3695fc6ae23070b25d2Ted Kremenek Out << "\\l"; 2054b38911f16b4943548db6a3695fc6ae23070b25d2Ted Kremenek } 20551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 205610f51e8785e43d5a22acc2d2a638307c582949c2Ted Kremenek#if 0 205710f51e8785e43d5a22acc2d2a638307c582949c2Ted Kremenek // FIXME: Replace with a general scheme to determine 205810f51e8785e43d5a22acc2d2a638307c582949c2Ted Kremenek // the name of the check. 20594a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek if (GraphPrintCheckerState->isUndefControlFlow(N)) { 20604a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek Out << "\\|Control-flow based on\\lUndefined value.\\l"; 20613b4f6702860208692f6ef28401e68de4e3ff9af9Ted Kremenek } 206210f51e8785e43d5a22acc2d2a638307c582949c2Ted Kremenek#endif 2063aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek } 2064aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek } 20651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 20668bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek ProgramStateRef state = N->getState(); 206731ba6135375433b617a8587ea6cc836a014ebd86Roman Divacky Out << "\\|StateID: " << (const void*) state.getPtr() 206831ba6135375433b617a8587ea6cc836a014ebd86Roman Divacky << " NodeID: " << (const void*) N << "\\|"; 20695eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek state->printDOT(Out); 2070ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek 2071ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek Out << "\\l"; 2072ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek 2073ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek if (const ProgramPointTag *tag = Loc.getTag()) { 2074ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek Out << "\\|Tag: " << tag->getTagDescription(); 2075ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek Out << "\\l"; 2076ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek } 2077aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek return Out.str(); 2078aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek } 2079aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek}; 20801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump} // end llvm namespace 2081aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek#endif 2082aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek 2083ffe0f43806d4823271c2406c1fccc2373115c36aTed Kremenek#ifndef NDEBUG 20847ec07fd91f6eae8bd619ebb8512805222ca41c92Ted Kremenektemplate <typename ITERATOR> 20859c378f705405d37f49795d5e915989de774fe11fTed KremenekExplodedNode *GetGraphNode(ITERATOR I) { return *I; } 20867ec07fd91f6eae8bd619ebb8512805222ca41c92Ted Kremenek 2087031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xutemplate <> ExplodedNode* 2088031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing XuGetGraphNode<llvm::DenseMap<ExplodedNode*, Expr*>::iterator> 2089031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu (llvm::DenseMap<ExplodedNode*, Expr*>::iterator I) { 20907ec07fd91f6eae8bd619ebb8512805222ca41c92Ted Kremenek return I->first; 20917ec07fd91f6eae8bd619ebb8512805222ca41c92Ted Kremenek} 2092ffe0f43806d4823271c2406c1fccc2373115c36aTed Kremenek#endif 2093ffe0f43806d4823271c2406c1fccc2373115c36aTed Kremenek 2094d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisvoid ExprEngine::ViewGraph(bool trim) { 20951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump#ifndef NDEBUG 2096ffe0f43806d4823271c2406c1fccc2373115c36aTed Kremenek if (trim) { 2097031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu std::vector<ExplodedNode*> Src; 2098940abcc574580e454689be801f38a3d4d41ab01fTed Kremenek 2099940abcc574580e454689be801f38a3d4d41ab01fTed Kremenek // Flush any outstanding reports to make sure we cover all the nodes. 2100940abcc574580e454689be801f38a3d4d41ab01fTed Kremenek // This does not cause them to get displayed. 2101940abcc574580e454689be801f38a3d4d41ab01fTed Kremenek for (BugReporter::iterator I=BR.begin(), E=BR.end(); I!=E; ++I) 2102940abcc574580e454689be801f38a3d4d41ab01fTed Kremenek const_cast<BugType*>(*I)->FlushReports(BR); 2103940abcc574580e454689be801f38a3d4d41ab01fTed Kremenek 2104940abcc574580e454689be801f38a3d4d41ab01fTed Kremenek // Iterate through the reports and get their nodes. 2105404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis for (BugReporter::EQClasses_iterator 2106404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis EI = BR.EQClasses_begin(), EE = BR.EQClasses_end(); EI != EE; ++EI) { 21074a5f724538cbc275370c9504e8169ce92503256cBenjamin Kramer ExplodedNode *N = const_cast<ExplodedNode*>(EI->begin()->getErrorNode()); 2108404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis if (N) Src.push_back(N); 2109940abcc574580e454689be801f38a3d4d41ab01fTed Kremenek } 21101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 21117ec07fd91f6eae8bd619ebb8512805222ca41c92Ted Kremenek ViewGraph(&Src[0], &Src[0]+Src.size()); 2112ffe0f43806d4823271c2406c1fccc2373115c36aTed Kremenek } 2113493d7a26d5ea319770ba904b43f2740d43b820cbTed Kremenek else { 2114493d7a26d5ea319770ba904b43f2740d43b820cbTed Kremenek GraphPrintCheckerState = this; 2115493d7a26d5ea319770ba904b43f2740d43b820cbTed Kremenek GraphPrintSourceManager = &getContext().getSourceManager(); 2116ae6814efb6c41bd0c0f6413d25097105284d5be7Ted Kremenek 2117d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis llvm::ViewGraph(*G.roots_begin(), "ExprEngine"); 21181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2119493d7a26d5ea319770ba904b43f2740d43b820cbTed Kremenek GraphPrintCheckerState = NULL; 2120493d7a26d5ea319770ba904b43f2740d43b820cbTed Kremenek GraphPrintSourceManager = NULL; 2121493d7a26d5ea319770ba904b43f2740d43b820cbTed Kremenek } 2122493d7a26d5ea319770ba904b43f2740d43b820cbTed Kremenek#endif 2123493d7a26d5ea319770ba904b43f2740d43b820cbTed Kremenek} 2124493d7a26d5ea319770ba904b43f2740d43b820cbTed Kremenek 2125d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisvoid ExprEngine::ViewGraph(ExplodedNode** Beg, ExplodedNode** End) { 2126493d7a26d5ea319770ba904b43f2740d43b820cbTed Kremenek#ifndef NDEBUG 2127493d7a26d5ea319770ba904b43f2740d43b820cbTed Kremenek GraphPrintCheckerState = this; 2128493d7a26d5ea319770ba904b43f2740d43b820cbTed Kremenek GraphPrintSourceManager = &getContext().getSourceManager(); 21291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2130031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu std::auto_ptr<ExplodedGraph> TrimmedG(G.Trim(Beg, End).first); 2131493d7a26d5ea319770ba904b43f2740d43b820cbTed Kremenek 2132cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek if (!TrimmedG.get()) 21336cb7c1a43b0c8f739d1f54b7fdae5ede86033496Benjamin Kramer llvm::errs() << "warning: Trimmed ExplodedGraph is empty.\n"; 2134cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek else 2135d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis llvm::ViewGraph(*TrimmedG->roots_begin(), "TrimmedExprEngine"); 21361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 21373b4f6702860208692f6ef28401e68de4e3ff9af9Ted Kremenek GraphPrintCheckerState = NULL; 2138e97ca065c91ff9ca2a2a42eb443eaa553c40441cTed Kremenek GraphPrintSourceManager = NULL; 2139e01c98767dfd7153c3c84637c36659e3bbe16ff7Ted Kremenek#endif 2140ee98546b0d5f3439c4a590b0d7d1545af794a0ecTed Kremenek} 2141