ExprEngine.cpp revision 6960d08b4ddf389d7c81504df7f16dc645120482
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 189b663716449b618ba0390b1dbebc54fa8e971124Ted Kremenek#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h" 19199c3d6cd16aebbb9c7f0d42af9d922c9628bf70Ken Dyck#include "clang/AST/CharUnits.h" 2016f0049415ec596504891259e2a83e19871c0d52Chris Lattner#include "clang/AST/ParentMap.h" 21337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek#include "clang/AST/StmtCXX.h" 2255fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/AST/StmtObjC.h" 231b63e4f732dbc73d90abf886b4d21f8e3a165f6dChris Lattner#include "clang/Basic/Builtins.h" 240bed8a12f2878d3cd94fb8bdba55b593d92dd11aTed Kremenek#include "clang/Basic/PrettyStackTrace.h" 2555fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Basic/SourceManager.h" 2655fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" 2755fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/StaticAnalyzer/Core/CheckerManager.h" 2855fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h" 2955fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" 306cb7c1a43b0c8f739d1f54b7fdae5ede86033496Benjamin Kramer#include "llvm/ADT/ImmutableList.h" 31c2994283aa7538b7420c8e398cde7afa328d7042Anna Zaks#include "llvm/ADT/Statistic.h" 3255fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "llvm/Support/raw_ostream.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, 27184c484545c5906ba55143e212b4a5275ab55889fJordan Rose const LocationContext *LC, 2720b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks const Stmt *DiagnosticStmt, 2730b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks ProgramPoint::Kind K) { 2740b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks assert((K == ProgramPoint::PreStmtPurgeDeadSymbolsKind || 27584c484545c5906ba55143e212b4a5275ab55889fJordan Rose ReferenceStmt == 0 || isa<ReturnStmt>(ReferenceStmt)) 2768501b7a1c4c4a9ba0ea6cb8e500e601ef3759debAnna Zaks && "PostStmt is not generally supported by the SymbolReaper yet"); 27784c484545c5906ba55143e212b4a5275ab55889fJordan Rose assert(LC && "Must pass the current (or expiring) LocationContext"); 27884c484545c5906ba55143e212b4a5275ab55889fJordan Rose 27984c484545c5906ba55143e212b4a5275ab55889fJordan Rose if (!DiagnosticStmt) { 28084c484545c5906ba55143e212b4a5275ab55889fJordan Rose DiagnosticStmt = ReferenceStmt; 28184c484545c5906ba55143e212b4a5275ab55889fJordan Rose assert(DiagnosticStmt && "Required for clearing a LocationContext"); 28284c484545c5906ba55143e212b4a5275ab55889fJordan Rose } 28384c484545c5906ba55143e212b4a5275ab55889fJordan Rose 2840b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks NumRemoveDeadBindings++; 2850b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks CleanedState = Pred->getState(); 28684c484545c5906ba55143e212b4a5275ab55889fJordan Rose 28784c484545c5906ba55143e212b4a5275ab55889fJordan Rose // LC is the location context being destroyed, but SymbolReaper wants a 28884c484545c5906ba55143e212b4a5275ab55889fJordan Rose // location context that is still live. (If this is the top-level stack 28984c484545c5906ba55143e212b4a5275ab55889fJordan Rose // frame, this will be null.) 29084c484545c5906ba55143e212b4a5275ab55889fJordan Rose if (!ReferenceStmt) { 29184c484545c5906ba55143e212b4a5275ab55889fJordan Rose assert(K == ProgramPoint::PostStmtPurgeDeadSymbolsKind && 29284c484545c5906ba55143e212b4a5275ab55889fJordan Rose "Use PostStmtPurgeDeadSymbolsKind for clearing a LocationContext"); 29384c484545c5906ba55143e212b4a5275ab55889fJordan Rose LC = LC->getParent(); 29484c484545c5906ba55143e212b4a5275ab55889fJordan Rose } 29584c484545c5906ba55143e212b4a5275ab55889fJordan Rose 29684c484545c5906ba55143e212b4a5275ab55889fJordan Rose const StackFrameContext *SFC = LC ? LC->getCurrentStackFrame() : 0; 29784c484545c5906ba55143e212b4a5275ab55889fJordan Rose SymbolReaper SymReaper(SFC, ReferenceStmt, SymMgr, getStoreManager()); 2980b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks 2990b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks getCheckerManager().runCheckersForLiveSymbols(CleanedState, SymReaper); 3000b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks 3010b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks // Create a state in which dead bindings are removed from the environment 3020b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks // and the store. TODO: The function should just return new env and store, 3030b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks // not a new state. 3040b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks CleanedState = StateMgr.removeDeadBindings(CleanedState, SFC, SymReaper); 305241677a13cc46647a8f5098b3e3239bd9480dca2Ted Kremenek 30677d7ef8d8a80ccb2ab3d25c80810571e3ab14ee4Ted Kremenek // Process any special transfer function for dead symbols. 307f185cc1ac77a84139c603eee3473b88dcb839c68Anna Zaks // A tag to track convenience transitions, which can be removed at cleanup. 308f185cc1ac77a84139c603eee3473b88dcb839c68Anna Zaks static SimpleProgramPointTag cleanupTag("ExprEngine : Clean Node"); 3096bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks if (!SymReaper.hasDeadSymbols()) { 3106bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks // Generate a CleanedNode that has the environment and store cleaned 3116bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks // up. Since no symbols are dead, we can optimize and not clean out 3126bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks // the constraint manager. 31366c486f275531df6362b3511fc3af6563561801bTed Kremenek StmtNodeBuilder Bldr(Pred, Out, *currBldrCtx); 314fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose Bldr.generateNode(DiagnosticStmt, Pred, CleanedState, &cleanupTag, K); 3151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3166bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks } else { 3176bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks // Call checkers with the non-cleaned state so that they could query the 3186bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks // values of the soon to be dead symbols. 319fe27971d54d26997149d6b84057f04ff398d1d5dJordy Rose ExplodedNodeSet CheckedSet; 3200b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks getCheckerManager().runCheckersForDeadSymbols(CheckedSet, Pred, SymReaper, 3210b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks DiagnosticStmt, *this, K); 322183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis 323fe27971d54d26997149d6b84057f04ff398d1d5dJordy Rose // For each node in CheckedSet, generate CleanedNodes that have the 324fe27971d54d26997149d6b84057f04ff398d1d5dJordy Rose // environment, the store, and the constraints cleaned up but have the 325fe27971d54d26997149d6b84057f04ff398d1d5dJordy Rose // user-supplied states as the predecessors. 32666c486f275531df6362b3511fc3af6563561801bTed Kremenek StmtNodeBuilder Bldr(CheckedSet, Out, *currBldrCtx); 327fe27971d54d26997149d6b84057f04ff398d1d5dJordy Rose for (ExplodedNodeSet::const_iterator 328fe27971d54d26997149d6b84057f04ff398d1d5dJordy Rose I = CheckedSet.begin(), E = CheckedSet.end(); I != E; ++I) { 3298bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek ProgramStateRef CheckerState = (*I)->getState(); 3306bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks 3316bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks // The constraint manager has not been cleaned up yet, so clean up now. 3326bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks CheckerState = getConstraintManager().removeDeadBindings(CheckerState, 3336bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks SymReaper); 3346bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks 3350b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks assert(StateMgr.haveEqualEnvironments(CheckerState, Pred->getState()) && 3366bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks "Checkers are not allowed to modify the Environment as a part of " 3376bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks "checkDeadSymbols processing."); 3380b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks assert(StateMgr.haveEqualStores(CheckerState, Pred->getState()) && 3396bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks "Checkers are not allowed to modify the Store as a part of " 3406bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks "checkDeadSymbols processing."); 3416bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks 3426bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks // Create a state based on CleanedState with CheckerState GDM and 3436bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks // generate a transition to that state. 3448bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek ProgramStateRef CleanedCheckerSt = 3456bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks StateMgr.getPersistentStateWithGDM(CleanedState, CheckerState); 346fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose Bldr.generateNode(DiagnosticStmt, *I, CleanedCheckerSt, &cleanupTag, K); 3476bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks } 34877d7ef8d8a80ccb2ab3d25c80810571e3ab14ee4Ted Kremenek } 3490b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks} 3500b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks 3510b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaksvoid ExprEngine::ProcessStmt(const CFGStmt S, 3520b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks ExplodedNode *Pred) { 3530b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks // Reclaim any unnecessary nodes in the ExplodedGraph. 3540b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks G.reclaimRecentlyAllocatedNodes(); 3550b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks 35666c486f275531df6362b3511fc3af6563561801bTed Kremenek currStmt = S.getStmt(); 3570b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(), 35866c486f275531df6362b3511fc3af6563561801bTed Kremenek currStmt->getLocStart(), 3590b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks "Error evaluating statement"); 3601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3610b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks // Remove dead bindings and symbols. 3620b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks EntryNode = Pred; 3630b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks ExplodedNodeSet CleanedStates; 3640b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks if (shouldRemoveDeadBindings(AMgr, S, Pred, EntryNode->getLocationContext())){ 36584c484545c5906ba55143e212b4a5275ab55889fJordan Rose removeDead(EntryNode, CleanedStates, currStmt, Pred->getLocationContext()); 3660b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks } else 3670b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks CleanedStates.Add(EntryNode); 3680b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks 3690b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks // Visit the statement. 370dd7ddf2b2296f95e7591ca3f9791f0eb9a15ee42Anna Zaks ExplodedNodeSet Dst; 3710b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks for (ExplodedNodeSet::iterator I = CleanedStates.begin(), 3720b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks E = CleanedStates.end(); I != E; ++I) { 373dd7ddf2b2296f95e7591ca3f9791f0eb9a15ee42Anna Zaks ExplodedNodeSet DstI; 3741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // Visit the statement. 37566c486f275531df6362b3511fc3af6563561801bTed Kremenek Visit(currStmt, *I, DstI); 376dd7ddf2b2296f95e7591ca3f9791f0eb9a15ee42Anna Zaks Dst.insert(DstI); 377ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks } 378ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks 379dd7ddf2b2296f95e7591ca3f9791f0eb9a15ee42Anna Zaks // Enqueue the new nodes onto the work list. 38066c486f275531df6362b3511fc3af6563561801bTed Kremenek Engine.enqueue(Dst, currBldrCtx->getBlock(), currStmtIdx); 3811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 382e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek // NULL out these variables to cleanup. 383846d4e923bf11bcdc2816758aafa331795f29230Ted Kremenek CleanedState = NULL; 384846d4e923bf11bcdc2816758aafa331795f29230Ted Kremenek EntryNode = NULL; 38566c486f275531df6362b3511fc3af6563561801bTed Kremenek currStmt = 0; 386e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek} 387e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek 388d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisvoid ExprEngine::ProcessInitializer(const CFGInitializer Init, 389056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks ExplodedNode *Pred) { 390cbb67480094b3bcb5b715acd827cbad55e2a204cSean Hunt const CXXCtorInitializer *BMI = Init.getInitializer(); 391563ea2335d7d0df44bbfe8941f64523e8af1fc14Jordan Rose 392563ea2335d7d0df44bbfe8941f64523e8af1fc14Jordan Rose PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(), 393563ea2335d7d0df44bbfe8941f64523e8af1fc14Jordan Rose BMI->getSourceLocation(), 394563ea2335d7d0df44bbfe8941f64523e8af1fc14Jordan Rose "Error evaluating initializer"); 395563ea2335d7d0df44bbfe8941f64523e8af1fc14Jordan Rose 39666c486f275531df6362b3511fc3af6563561801bTed Kremenek // We don't set EntryNode and currStmt. And we don't clean up state. 397056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks const StackFrameContext *stackFrame = 398056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks cast<StackFrameContext>(Pred->getLocationContext()); 399056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks const CXXConstructorDecl *decl = 400056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks cast<CXXConstructorDecl>(stackFrame->getDecl()); 4013682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose 4023682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose ProgramStateRef State = Pred->getState(); 4033a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose SVal thisVal = State->getSVal(svalBuilder.getCXXThis(decl, stackFrame)); 4049dc84c9455df2a77195147d0210c915dc1775a88Zhongxing Xu 4053682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose PostInitializer PP(BMI, stackFrame); 4063682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose ExplodedNodeSet Tmp(Pred); 4073682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose 4083a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose // Evaluate the initializer, if necessary 40900eb3f9c5b33e3d99aee1f8b75dd9c9678fdd66bFrancois Pichet if (BMI->isAnyMemberInitializer()) { 4103a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose // Constructors build the object directly in the field, 4113a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose // but non-objects must be copied in from the initializer. 4123682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose const Expr *Init = BMI->getInit(); 4133682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose if (!isa<CXXConstructExpr>(Init)) { 4143a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose SVal FieldLoc; 4153a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose if (BMI->isIndirectMemberInitializer()) 4163a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose FieldLoc = State->getLValue(BMI->getIndirectMember(), thisVal); 4173a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose else 4183a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose FieldLoc = State->getLValue(BMI->getMember(), thisVal); 4193a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose 4203a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose SVal InitVal = State->getSVal(BMI->getInit(), stackFrame); 4213682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose 4223682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose Tmp.clear(); 4233682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose evalBind(Tmp, Init, Pred, FieldLoc, InitVal, /*isInit=*/true, &PP); 4243a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose } 425056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks } else { 426563ea2335d7d0df44bbfe8941f64523e8af1fc14Jordan Rose assert(BMI->isBaseInitializer() || BMI->isDelegatingInitializer()); 427888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose // We already did all the work when visiting the CXXConstructExpr. 428056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks } 429dd7ddf2b2296f95e7591ca3f9791f0eb9a15ee42Anna Zaks 4303682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose // Construct PostInitializer nodes whether the state changed or not, 4313a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose // so that the diagnostics don't get confused. 4323682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose ExplodedNodeSet Dst; 4333682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose NodeBuilder Bldr(Tmp, Dst, *currBldrCtx); 4343682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose for (ExplodedNodeSet::iterator I = Tmp.begin(), E = Tmp.end(); I != E; ++I) { 4353682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose ExplodedNode *N = *I; 4363682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose Bldr.generateNode(PP, N->getState(), N); 4373682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose } 4383a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose 439dd7ddf2b2296f95e7591ca3f9791f0eb9a15ee42Anna Zaks // Enqueue the new nodes onto the work list. 44066c486f275531df6362b3511fc3af6563561801bTed Kremenek Engine.enqueue(Dst, currBldrCtx->getBlock(), currStmtIdx); 4419c6cd67ea416bace666d614c84d5531124287653Zhongxing Xu} 4429c6cd67ea416bace666d614c84d5531124287653Zhongxing Xu 443d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisvoid ExprEngine::ProcessImplicitDtor(const CFGImplicitDtor D, 444ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks ExplodedNode *Pred) { 445ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks ExplodedNodeSet Dst; 4463c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek switch (D.getKind()) { 4474ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu case CFGElement::AutomaticObjectDtor: 448056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks ProcessAutomaticObjDtor(cast<CFGAutomaticObjDtor>(D), Pred, Dst); 4494ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu break; 4504ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu case CFGElement::BaseDtor: 451056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks ProcessBaseDtor(cast<CFGBaseDtor>(D), Pred, Dst); 4524ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu break; 4534ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu case CFGElement::MemberDtor: 454056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks ProcessMemberDtor(cast<CFGMemberDtor>(D), Pred, Dst); 4554ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu break; 4564ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu case CFGElement::TemporaryDtor: 457056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks ProcessTemporaryDtor(cast<CFGTemporaryDtor>(D), Pred, Dst); 4584ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu break; 4594ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu default: 4604ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu llvm_unreachable("Unexpected dtor kind."); 4614ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu } 462ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks 463dd7ddf2b2296f95e7591ca3f9791f0eb9a15ee42Anna Zaks // Enqueue the new nodes onto the work list. 46466c486f275531df6362b3511fc3af6563561801bTed Kremenek Engine.enqueue(Dst, currBldrCtx->getBlock(), currStmtIdx); 4654ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu} 4664ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu 467056c4b46335a3bd2612414735d5749ee159c0165Anna Zaksvoid ExprEngine::ProcessAutomaticObjDtor(const CFGAutomaticObjDtor Dtor, 468056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks ExplodedNode *Pred, 469056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks ExplodedNodeSet &Dst) { 4708bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek ProgramStateRef state = Pred->getState(); 471056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks const VarDecl *varDecl = Dtor.getVarDecl(); 4722210490e6d099b7a5b4f68f44a136e4dcf3cdea2Zhongxing Xu 4732210490e6d099b7a5b4f68f44a136e4dcf3cdea2Zhongxing Xu QualType varType = varDecl->getType(); 4742210490e6d099b7a5b4f68f44a136e4dcf3cdea2Zhongxing Xu 4752210490e6d099b7a5b4f68f44a136e4dcf3cdea2Zhongxing Xu if (const ReferenceType *refType = varType->getAs<ReferenceType>()) 4762210490e6d099b7a5b4f68f44a136e4dcf3cdea2Zhongxing Xu varType = refType->getPointeeType(); 4772210490e6d099b7a5b4f68f44a136e4dcf3cdea2Zhongxing Xu 478056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks Loc dest = state->getLValue(varDecl, Pred->getLocationContext()); 479b13453bd8a91f331d0910ca95ad52aa41b52f648Zhongxing Xu 480888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose VisitCXXDestructor(varType, cast<loc::MemRegionVal>(dest).getRegion(), 481200fa2e70d52ae6d620e81cd45536071fdde70c0Jordan Rose Dtor.getTriggerStmt(), /*IsBase=*/false, Pred, Dst); 4824ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu} 4834ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu 484d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisvoid ExprEngine::ProcessBaseDtor(const CFGBaseDtor D, 485888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose ExplodedNode *Pred, ExplodedNodeSet &Dst) { 486888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose const LocationContext *LCtx = Pred->getLocationContext(); 487888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose ProgramStateRef State = Pred->getState(); 488888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose 489888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose const CXXDestructorDecl *CurDtor = cast<CXXDestructorDecl>(LCtx->getDecl()); 490888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose Loc ThisPtr = getSValBuilder().getCXXThis(CurDtor, 491888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose LCtx->getCurrentStackFrame()); 492888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose SVal ThisVal = Pred->getState()->getSVal(ThisPtr); 493888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose 494888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose // Create the base object region. 495888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose QualType BaseTy = D.getBaseSpecifier()->getType(); 496888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose SVal BaseVal = getStoreManager().evalDerivedToBase(ThisVal, BaseTy); 497888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose 498888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose VisitCXXDestructor(BaseTy, cast<loc::MemRegionVal>(BaseVal).getRegion(), 499200fa2e70d52ae6d620e81cd45536071fdde70c0Jordan Rose CurDtor->getBody(), /*IsBase=*/true, Pred, Dst); 500888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose} 5014ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu 502d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisvoid ExprEngine::ProcessMemberDtor(const CFGMemberDtor D, 5033a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose ExplodedNode *Pred, ExplodedNodeSet &Dst) { 5043a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose const FieldDecl *Member = D.getFieldDecl(); 5053a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose ProgramStateRef State = Pred->getState(); 5063a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose const LocationContext *LCtx = Pred->getLocationContext(); 5073a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose 5083a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose const CXXDestructorDecl *CurDtor = cast<CXXDestructorDecl>(LCtx->getDecl()); 5093a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose Loc ThisVal = getSValBuilder().getCXXThis(CurDtor, 5103a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose LCtx->getCurrentStackFrame()); 5113a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose SVal FieldVal = State->getLValue(Member, cast<Loc>(State->getSVal(ThisVal))); 5123a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose 5133a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose VisitCXXDestructor(Member->getType(), 5143a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose cast<loc::MemRegionVal>(FieldVal).getRegion(), 515200fa2e70d52ae6d620e81cd45536071fdde70c0Jordan Rose CurDtor->getBody(), /*IsBase=*/false, Pred, Dst); 5163a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose} 5174ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu 518d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisvoid ExprEngine::ProcessTemporaryDtor(const CFGTemporaryDtor D, 519056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks ExplodedNode *Pred, 520056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks ExplodedNodeSet &Dst) {} 5219c6cd67ea416bace666d614c84d5531124287653Zhongxing Xu 52248b6247804eacc262cc5508e0fbb74ed819fbb6eJordan Rosevoid ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred, 5236889679d72859960e0fc8d1080487f63c4df1e0aAnna Zaks ExplodedNodeSet &DstTop) { 5240bed8a12f2878d3cd94fb8bdba55b593d92dd11aTed Kremenek PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(), 5250bed8a12f2878d3cd94fb8bdba55b593d92dd11aTed Kremenek S->getLocStart(), 5260bed8a12f2878d3cd94fb8bdba55b593d92dd11aTed Kremenek "Error evaluating statement"); 5276889679d72859960e0fc8d1080487f63c4df1e0aAnna Zaks ExplodedNodeSet Dst; 52866c486f275531df6362b3511fc3af6563561801bTed Kremenek StmtNodeBuilder Bldr(Pred, DstTop, *currBldrCtx); 5290bed8a12f2878d3cd94fb8bdba55b593d92dd11aTed Kremenek 530f6a1648197562e0b133440d612d9af297d0a86ccJohn McCall // Expressions to ignore. 531f6a1648197562e0b133440d612d9af297d0a86ccJohn McCall if (const Expr *Ex = dyn_cast<Expr>(S)) 532892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek S = Ex->IgnoreParens(); 533f6a1648197562e0b133440d612d9af297d0a86ccJohn McCall 534e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek // FIXME: add metadata to the CFG so that we can disable 535e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek // this check when we KNOW that there is no block-level subexpression. 536e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek // The motivation is that this check requires a hashtable lookup. 5371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 53866c486f275531df6362b3511fc3af6563561801bTed Kremenek if (S != currStmt && Pred->getLocationContext()->getCFG()->isBlkExpr(S)) 539e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek return; 5401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 541e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek switch (S->getStmtClass()) { 542f85e193739c953358c865005855253af4f68a497John McCall // C++ and ARC stuff we don't support yet. 543f85e193739c953358c865005855253af4f68a497John McCall case Expr::ObjCIndirectCopyRestoreExprClass: 5441b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::CXXDependentScopeMemberExprClass: 5451b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::CXXPseudoDestructorExprClass: 5461b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::CXXTryStmtClass: 5471b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::CXXTypeidExprClass: 5489be88403e965cc49af76c9d33d818781d44b333eFrancois Pichet case Stmt::CXXUuidofExprClass: 549c768a0c46e6c064c3281d663777ee95aea8652eeTed Kremenek case Stmt::CXXUnresolvedConstructExprClass: 5501b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::DependentScopeDeclRefExprClass: 5511b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::UnaryTypeTraitExprClass: 5526ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet case Stmt::BinaryTypeTraitExprClass: 5534ca8ac2e61c37ddadf37024af86f3e1019af8532Douglas Gregor case Stmt::TypeTraitExprClass: 55421ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley case Stmt::ArrayTypeTraitExprClass: 555552622067dc45013d240f73952fece703f5e63bdJohn Wiegley case Stmt::ExpressionTraitExprClass: 5561b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::UnresolvedLookupExprClass: 557c768a0c46e6c064c3281d663777ee95aea8652eeTed Kremenek case Stmt::UnresolvedMemberExprClass: 5586b219d082434394c1ac401390ec1d1967727815aSebastian Redl case Stmt::CXXNoexceptExprClass: 559be230c36e32142cbdcdbe9c97511d097beeecbabDouglas Gregor case Stmt::PackExpansionExprClass: 560c7793c73ba8a343de3f2552d984851985a46f159Douglas Gregor case Stmt::SubstNonTypeTemplateParmPackExprClass: 5619a4db032ecd991626d236a502e770126db32bd31Richard Smith case Stmt::FunctionParmPackExprClass: 56228bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley case Stmt::SEHTryStmtClass: 56328bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley case Stmt::SEHExceptStmtClass: 56401d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor case Stmt::LambdaExprClass: 565ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks case Stmt::SEHFinallyStmtClass: { 566fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose const ExplodedNode *node = Bldr.generateSink(S, Pred, Pred->getState()); 56766c486f275531df6362b3511fc3af6563561801bTed Kremenek Engine.addAbortedBlock(node, currBldrCtx->getBlock()); 568c768a0c46e6c064c3281d663777ee95aea8652eeTed Kremenek break; 569c768a0c46e6c064c3281d663777ee95aea8652eeTed Kremenek } 5705fe98728dca1f3a7a378ce1a21984a0f8a0c0b8bTed Kremenek 571f6a1648197562e0b133440d612d9af297d0a86ccJohn McCall case Stmt::ParenExprClass: 572f6a1648197562e0b133440d612d9af297d0a86ccJohn McCall llvm_unreachable("ParenExprs already handled."); 573f111d935722ed488144600cea5ed03a6b5069e8fPeter Collingbourne case Stmt::GenericSelectionExprClass: 574f111d935722ed488144600cea5ed03a6b5069e8fPeter Collingbourne llvm_unreachable("GenericSelectionExprs already handled."); 5751b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek // Cases that should never be evaluated simply because they shouldn't 5761b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek // appear in the CFG. 5771b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::BreakStmtClass: 5781b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::CaseStmtClass: 5791b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::CompoundStmtClass: 5801b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::ContinueStmtClass: 58146eaf7789a1059a7b42b7dbd183150c72df5738fTed Kremenek case Stmt::CXXForRangeStmtClass: 5821b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::DefaultStmtClass: 5831b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::DoStmtClass: 584d40066b0fb883839a9100e5455e33190b9b8abacTed Kremenek case Stmt::ForStmtClass: 5851b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::GotoStmtClass: 586d40066b0fb883839a9100e5455e33190b9b8abacTed Kremenek case Stmt::IfStmtClass: 5871b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::IndirectGotoStmtClass: 5881b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::LabelStmtClass: 589534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith case Stmt::AttributedStmtClass: 5901b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::NoStmtClass: 5911b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::NullStmtClass: 592d40066b0fb883839a9100e5455e33190b9b8abacTed Kremenek case Stmt::SwitchStmtClass: 593d40066b0fb883839a9100e5455e33190b9b8abacTed Kremenek case Stmt::WhileStmtClass: 594ba0513de93d2fab6db5ab30b6927209fcc883078Douglas Gregor case Expr::MSDependentExistsStmtClass: 5951b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek llvm_unreachable("Stmt should not be in analyzer evaluation loop"); 5961b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek 5974ccc4cc5d4e7c5c436d5f45065d3639cfc7c6e48Jordan Rose case Stmt::ObjCSubscriptRefExprClass: 5984ccc4cc5d4e7c5c436d5f45065d3639cfc7c6e48Jordan Rose case Stmt::ObjCPropertyRefExprClass: 5994ccc4cc5d4e7c5c436d5f45065d3639cfc7c6e48Jordan Rose llvm_unreachable("These are handled by PseudoObjectExpr"); 6004ccc4cc5d4e7c5c436d5f45065d3639cfc7c6e48Jordan Rose 6018ad9cbc518a603176462f1fa1efe389023590082Ted Kremenek case Stmt::GNUNullExprClass: { 6028f08426e6f54ed20b959018f24dbea106a00b4adJordy Rose // GNU __null is a pointer-width integer, not an actual pointer. 6038bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek ProgramStateRef state = Pred->getState(); 6045eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek state = state->BindExpr(S, Pred->getLocationContext(), 6055eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek svalBuilder.makeIntValWithPtrWidth(0, false)); 606ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.generateNode(S, Pred, state); 6078ad9cbc518a603176462f1fa1efe389023590082Ted Kremenek break; 6088ad9cbc518a603176462f1fa1efe389023590082Ted Kremenek } 6098ad9cbc518a603176462f1fa1efe389023590082Ted Kremenek 6104beaa9f51b2da57c64740cef2bd1c2fdb0c325d5Ted Kremenek case Stmt::ObjCAtSynchronizedStmtClass: 611ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 6124beaa9f51b2da57c64740cef2bd1c2fdb0c325d5Ted Kremenek VisitObjCAtSynchronizedStmt(cast<ObjCAtSynchronizedStmt>(S), Pred, Dst); 613ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 6144beaa9f51b2da57c64740cef2bd1c2fdb0c325d5Ted Kremenek break; 6154beaa9f51b2da57c64740cef2bd1c2fdb0c325d5Ted Kremenek 616ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks case Stmt::ExprWithCleanupsClass: 617e711d7e7875920fee4180a26bfc67d67f0f71a2cErik Verbruggen // Handled due to fully linearised CFG. 618f85e193739c953358c865005855253af4f68a497John McCall break; 619f85e193739c953358c865005855253af4f68a497John McCall 6201b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek // Cases not handled yet; but will handle some day. 6211b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::DesignatedInitExprClass: 6221b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::ExtVectorElementExprClass: 6231b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::ImaginaryLiteralClass: 6241b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::ObjCAtCatchStmtClass: 6251b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::ObjCAtFinallyStmtClass: 6261b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::ObjCAtTryStmtClass: 627f85e193739c953358c865005855253af4f68a497John McCall case Stmt::ObjCAutoreleasePoolStmtClass: 6281b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::ObjCEncodeExprClass: 6291b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::ObjCIsaExprClass: 6301b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::ObjCProtocolExprClass: 6311b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::ObjCSelectorExprClass: 6321b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::ParenListExprClass: 6331b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::PredefinedExprClass: 6341b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::ShuffleVectorExprClass: 6351b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::VAArgExprClass: 636e08ce650a2b02410eddd1f60a4aa6b3d4be71e73Peter Collingbourne case Stmt::CUDAKernelCallExprClass: 63756ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall case Stmt::OpaqueValueExprClass: 63861eee0ca33b29e102f11bab77c8b74cc00e2392bTanya Lattner case Stmt::AsTypeExprClass: 639276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman case Stmt::AtomicExprClass: 640337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek // Fall through. 6411b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek 6421b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek // Cases we intentionally don't evaluate, since they don't need 6431b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek // to be explicitly evaluated. 644bc9ad74a13e83303a3a5251f8bacbbca17341c17Zhongxing Xu case Stmt::AddrLabelExprClass: 645bc9ad74a13e83303a3a5251f8bacbbca17341c17Zhongxing Xu case Stmt::IntegerLiteralClass: 646bc9ad74a13e83303a3a5251f8bacbbca17341c17Zhongxing Xu case Stmt::CharacterLiteralClass: 647c319c585c0d5899cba0dca2272e6e4909c8b9f16Ted Kremenek case Stmt::ImplicitValueInitExprClass: 648c319c585c0d5899cba0dca2272e6e4909c8b9f16Ted Kremenek case Stmt::CXXScalarValueInitExprClass: 649477323d58a0de352c6a61e08b5a83127c4adc904Zhongxing Xu case Stmt::CXXBoolLiteralExprClass: 6501a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek case Stmt::ObjCBoolLiteralExprClass: 651bc9ad74a13e83303a3a5251f8bacbbca17341c17Zhongxing Xu case Stmt::FloatingLiteralClass: 652f901a7de97f46ba2b1ff153f9fb83d00dc37cfcfDouglas Gregor case Stmt::SizeOfPackExprClass: 653e739a29c62c67eaec0af5c4d5c75f9e8f11228bdTed Kremenek case Stmt::StringLiteralClass: 654e739a29c62c67eaec0af5c4d5c75f9e8f11228bdTed Kremenek case Stmt::ObjCStringLiteralClass: 655cc2c4b293d8590346f26b7ecc16d299226b8794fTed Kremenek case Stmt::CXXBindTemporaryExprClass: 656b66529d04727dc686b97ea3d937fc9785792f505Jordan Rose case Stmt::CXXDefaultArgExprClass: 65769a0e5021c5c49a34aa25cd89b1e613a52097e65Jordan Rose case Stmt::SubstNonTypeTemplateParmExprClass: 658bdd4c848349d4091d66b052efa453e6d69a77e36Ted Kremenek case Stmt::CXXNullPtrLiteralExprClass: { 659bdd4c848349d4091d66b052efa453e6d69a77e36Ted Kremenek Bldr.takeNodes(Pred); 660bdd4c848349d4091d66b052efa453e6d69a77e36Ted Kremenek ExplodedNodeSet preVisit; 661bdd4c848349d4091d66b052efa453e6d69a77e36Ted Kremenek getCheckerManager().runCheckersForPreStmt(preVisit, Pred, S, *this); 662bdd4c848349d4091d66b052efa453e6d69a77e36Ted Kremenek getCheckerManager().runCheckersForPostStmt(Dst, preVisit, S, *this); 663bdd4c848349d4091d66b052efa453e6d69a77e36Ted Kremenek Bldr.addNodes(Dst); 664e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek break; 665bdd4c848349d4091d66b052efa453e6d69a77e36Ted Kremenek } 6661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 6671a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek case Expr::ObjCArrayLiteralClass: 66870fdbc366da85880aae5baebd3351e993ca05603Jordy Rose case Expr::ObjCDictionaryLiteralClass: 66970fdbc366da85880aae5baebd3351e993ca05603Jordy Rose // FIXME: explicitly model with a region and the actual contents 67070fdbc366da85880aae5baebd3351e993ca05603Jordy Rose // of the container. For now, conjure a symbol. 67170fdbc366da85880aae5baebd3351e993ca05603Jordy Rose case Expr::ObjCBoxedExprClass: { 6721a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek Bldr.takeNodes(Pred); 6731a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek 6741a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek ExplodedNodeSet preVisit; 6751a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek getCheckerManager().runCheckersForPreStmt(preVisit, Pred, S, *this); 6761a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek 6771a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek ExplodedNodeSet Tmp; 67866c486f275531df6362b3511fc3af6563561801bTed Kremenek StmtNodeBuilder Bldr2(preVisit, Tmp, *currBldrCtx); 6791a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek 68070fdbc366da85880aae5baebd3351e993ca05603Jordy Rose const Expr *Ex = cast<Expr>(S); 68170fdbc366da85880aae5baebd3351e993ca05603Jordy Rose QualType resultType = Ex->getType(); 68270fdbc366da85880aae5baebd3351e993ca05603Jordy Rose 6831a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek for (ExplodedNodeSet::iterator it = preVisit.begin(), et = preVisit.end(); 6841a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek it != et; ++it) { 6851a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek ExplodedNode *N = *it; 6861a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek const LocationContext *LCtx = N->getLocationContext(); 6873b1df8bb941a18c4a7256d7cfcbccb9de7e39995Ted Kremenek SVal result = svalBuilder.conjureSymbolVal(0, Ex, LCtx, resultType, 68866c486f275531df6362b3511fc3af6563561801bTed Kremenek currBldrCtx->blockCount()); 6891a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek ProgramStateRef state = N->getState()->BindExpr(Ex, LCtx, result); 6901a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek Bldr2.generateNode(S, N, state); 6911a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek } 6921a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek 6931a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek getCheckerManager().runCheckersForPostStmt(Dst, Tmp, S, *this); 6941a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek Bldr.addNodes(Dst); 6951a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek break; 6961a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek } 6971a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek 698540cbe2b60294fe7b926c26b4f1840f544fe3011Ted Kremenek case Stmt::ArraySubscriptExprClass: 699ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 700892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek VisitLvalArraySubscriptExpr(cast<ArraySubscriptExpr>(S), Pred, Dst); 701ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 702540cbe2b60294fe7b926c26b4f1840f544fe3011Ted Kremenek break; 7031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 704df5faf5e7ae6823d0af0b801c4ac26d47f2cee97Chad Rosier case Stmt::GCCAsmStmtClass: 705ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 706df5faf5e7ae6823d0af0b801c4ac26d47f2cee97Chad Rosier VisitGCCAsmStmt(cast<GCCAsmStmt>(S), Pred, Dst); 707ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 708e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek break; 709b9bbd592c7ea72ada8d982e40a729beb9b53371eTed Kremenek 7108cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier case Stmt::MSAsmStmtClass: 7118cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier Bldr.takeNodes(Pred); 7128cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier VisitMSAsmStmt(cast<MSAsmStmt>(S), Pred, Dst); 7138cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier Bldr.addNodes(Dst); 7148cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier break; 7158cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier 716c95ad9ff6e574aecdd759542d5578bc65d586d93Ted Kremenek case Stmt::BlockExprClass: 717ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 718c95ad9ff6e574aecdd759542d5578bc65d586d93Ted Kremenek VisitBlockExpr(cast<BlockExpr>(S), Pred, Dst); 719ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 720c95ad9ff6e574aecdd759542d5578bc65d586d93Ted Kremenek break; 721c95ad9ff6e574aecdd759542d5578bc65d586d93Ted Kremenek 722e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek case Stmt::BinaryOperatorClass: { 72303509aea098772644bf4662dc1c88634818ceeccZhongxing Xu const BinaryOperator* B = cast<BinaryOperator>(S); 724e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek if (B->isLogicalOp()) { 725ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 726e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek VisitLogicalExpr(B, Pred, Dst); 727ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 728e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek break; 729e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek } 7302de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall else if (B->getOpcode() == BO_Comma) { 7318bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek ProgramStateRef state = Pred->getState(); 732ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.generateNode(B, Pred, 7335eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek state->BindExpr(B, Pred->getLocationContext(), 7345eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek state->getSVal(B->getRHS(), 7355eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek Pred->getLocationContext()))); 736e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek break; 737e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek } 73806fb99fb403bff1651429923f666a2ebe2b1522fTed Kremenek 739ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 740ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks 7410caa2d47b84337e942b3f6652adfafe4ae506cfeTed Kremenek if (AMgr.options.eagerlyAssumeBinOpBifurcation && 742bb141217871e93767aa3f2de1b9946fa6d37066aZhongxing Xu (B->isRelationalOp() || B->isEqualityOp())) { 743031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu ExplodedNodeSet Tmp; 744892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Tmp); 7450caa2d47b84337e942b3f6652adfafe4ae506cfeTed Kremenek evalEagerlyAssumeBinOpBifurcation(Dst, Tmp, cast<Expr>(S)); 74648af2a9c1ed3259512f2d1431720add1fbe8fb5fTed Kremenek } 74748af2a9c1ed3259512f2d1431720add1fbe8fb5fTed Kremenek else 748892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Dst); 74948af2a9c1ed3259512f2d1431720add1fbe8fb5fTed Kremenek 750ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 751e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek break; 752e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek } 75306fb99fb403bff1651429923f666a2ebe2b1522fTed Kremenek 754f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose case Stmt::CXXOperatorCallExprClass: { 755f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose const CXXOperatorCallExpr *OCE = cast<CXXOperatorCallExpr>(S); 756f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose 757f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose // For instance method operators, make sure the 'this' argument has a 758f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose // valid region. 759f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose const Decl *Callee = OCE->getCalleeDecl(); 760f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose if (const CXXMethodDecl *MD = dyn_cast_or_null<CXXMethodDecl>(Callee)) { 761f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose if (MD->isInstance()) { 762f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose ProgramStateRef State = Pred->getState(); 763f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose const LocationContext *LCtx = Pred->getLocationContext(); 764f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose ProgramStateRef NewState = 765f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose createTemporaryRegionIfNeeded(State, LCtx, OCE->getArg(0)); 766f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose if (NewState != State) 767f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose Pred = Bldr.generateNode(OCE, Pred, NewState, /*Tag=*/0, 768f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose ProgramPoint::PreStmtKind); 769f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose } 770f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose } 771f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose // FALLTHROUGH 772f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose } 773b277159055933e610bbc80262b600d3ad7e0595cTed Kremenek case Stmt::CallExprClass: 7749fcce65e7e1307b5b8da9be13e4092d6bb94dc1dRichard Smith case Stmt::CXXMemberCallExprClass: 7759fcce65e7e1307b5b8da9be13e4092d6bb94dc1dRichard Smith case Stmt::UserDefinedLiteralClass: { 776ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 777b277159055933e610bbc80262b600d3ad7e0595cTed Kremenek VisitCallExpr(cast<CallExpr>(S), Pred, Dst); 778ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 77906fb99fb403bff1651429923f666a2ebe2b1522fTed Kremenek break; 780e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek } 781337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek 782337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek case Stmt::CXXCatchStmtClass: { 783337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek Bldr.takeNodes(Pred); 784337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek VisitCXXCatchStmt(cast<CXXCatchStmt>(S), Pred, Dst); 785337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek Bldr.addNodes(Dst); 786337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek break; 787337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek } 78806fb99fb403bff1651429923f666a2ebe2b1522fTed Kremenek 789744f1cd66bb6747ea71fbf1172698e7bf35ec88dTed Kremenek case Stmt::CXXTemporaryObjectExprClass: 790888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose case Stmt::CXXConstructExprClass: { 791ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 792888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose VisitCXXConstructExpr(cast<CXXConstructExpr>(S), Pred, Dst); 793ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 7947ce351db56fbce162a3b650518ce05b5c61ebf36Zhongxing Xu break; 7957ce351db56fbce162a3b650518ce05b5c61ebf36Zhongxing Xu } 7967ce351db56fbce162a3b650518ce05b5c61ebf36Zhongxing Xu 797856c6bcaea56e05255e9f3997ddd56b5c18a14f0Zhongxing Xu case Stmt::CXXNewExprClass: { 798ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 79903509aea098772644bf4662dc1c88634818ceeccZhongxing Xu const CXXNewExpr *NE = cast<CXXNewExpr>(S); 800856c6bcaea56e05255e9f3997ddd56b5c18a14f0Zhongxing Xu VisitCXXNewExpr(NE, Pred, Dst); 801ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 802856c6bcaea56e05255e9f3997ddd56b5c18a14f0Zhongxing Xu break; 803856c6bcaea56e05255e9f3997ddd56b5c18a14f0Zhongxing Xu } 804856c6bcaea56e05255e9f3997ddd56b5c18a14f0Zhongxing Xu 8056b8513829895e56a7b97e787ea74520bc626512eZhongxing Xu case Stmt::CXXDeleteExprClass: { 806ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 80703509aea098772644bf4662dc1c88634818ceeccZhongxing Xu const CXXDeleteExpr *CDE = cast<CXXDeleteExpr>(S); 8086b8513829895e56a7b97e787ea74520bc626512eZhongxing Xu VisitCXXDeleteExpr(CDE, Pred, Dst); 809ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 8106b8513829895e56a7b97e787ea74520bc626512eZhongxing Xu break; 8116b8513829895e56a7b97e787ea74520bc626512eZhongxing Xu } 812e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek // FIXME: ChooseExpr is really a constant. We need to fix 813e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek // the CFG do not model them as explicit control-flow. 8141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 815e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek case Stmt::ChooseExprClass: { // __builtin_choose_expr 816ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 8179c378f705405d37f49795d5e915989de774fe11fTed Kremenek const ChooseExpr *C = cast<ChooseExpr>(S); 818e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek VisitGuardedExpr(C, C->getLHS(), C->getRHS(), Pred, Dst); 819ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 820e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek break; 821e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek } 8221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 823e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek case Stmt::CompoundAssignOperatorClass: 824ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 825892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Dst); 826ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 827e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek break; 828f22679e3e5d5f5754931952e58112b4c863a4137Zhongxing Xu 829f22679e3e5d5f5754931952e58112b4c863a4137Zhongxing Xu case Stmt::CompoundLiteralExprClass: 830ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 831892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek VisitCompoundLiteralExpr(cast<CompoundLiteralExpr>(S), Pred, Dst); 832ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 833f22679e3e5d5f5754931952e58112b4c863a4137Zhongxing Xu break; 8341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 83556ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall case Stmt::BinaryConditionalOperatorClass: 836e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek case Stmt::ConditionalOperatorClass: { // '?' operator 837ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 83856ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall const AbstractConditionalOperator *C 83956ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall = cast<AbstractConditionalOperator>(S); 84056ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall VisitGuardedExpr(C, C->getTrueExpr(), C->getFalseExpr(), Pred, Dst); 841ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 842e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek break; 843e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek } 8441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 845bb141217871e93767aa3f2de1b9946fa6d37066aZhongxing Xu case Stmt::CXXThisExprClass: 846ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 847bb141217871e93767aa3f2de1b9946fa6d37066aZhongxing Xu VisitCXXThisExpr(cast<CXXThisExpr>(S), Pred, Dst); 848ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 849bb141217871e93767aa3f2de1b9946fa6d37066aZhongxing Xu break; 850bb141217871e93767aa3f2de1b9946fa6d37066aZhongxing Xu 851892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek case Stmt::DeclRefExprClass: { 852ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 853892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek const DeclRefExpr *DE = cast<DeclRefExpr>(S); 854892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek VisitCommonDeclRefExpr(DE, DE->getDecl(), Pred, Dst); 855ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 856e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek break; 857892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek } 8581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 859e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek case Stmt::DeclStmtClass: 860ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 861e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek VisitDeclStmt(cast<DeclStmt>(S), Pred, Dst); 862ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 863e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek break; 8641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 8650835a3cdeefe714b4959d31127ea155e56393125Argyrios Kyrtzidis case Stmt::ImplicitCastExprClass: 8660d9d736c49b51691ced96759ec99399824e2a602Zhongxing Xu case Stmt::CStyleCastExprClass: 8670d9d736c49b51691ced96759ec99399824e2a602Zhongxing Xu case Stmt::CXXStaticCastExprClass: 8680d9d736c49b51691ced96759ec99399824e2a602Zhongxing Xu case Stmt::CXXDynamicCastExprClass: 8690d9d736c49b51691ced96759ec99399824e2a602Zhongxing Xu case Stmt::CXXReinterpretCastExprClass: 8700d9d736c49b51691ced96759ec99399824e2a602Zhongxing Xu case Stmt::CXXConstCastExprClass: 871f85e193739c953358c865005855253af4f68a497John McCall case Stmt::CXXFunctionalCastExprClass: 872f85e193739c953358c865005855253af4f68a497John McCall case Stmt::ObjCBridgedCastExprClass: { 873ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 8749c378f705405d37f49795d5e915989de774fe11fTed Kremenek const CastExpr *C = cast<CastExpr>(S); 875f85e193739c953358c865005855253af4f68a497John McCall // Handle the previsit checks. 876f85e193739c953358c865005855253af4f68a497John McCall ExplodedNodeSet dstPrevisit; 877f85e193739c953358c865005855253af4f68a497John McCall getCheckerManager().runCheckersForPreStmt(dstPrevisit, Pred, C, *this); 878f85e193739c953358c865005855253af4f68a497John McCall 879f85e193739c953358c865005855253af4f68a497John McCall // Handle the expression itself. 880f85e193739c953358c865005855253af4f68a497John McCall ExplodedNodeSet dstExpr; 881f85e193739c953358c865005855253af4f68a497John McCall for (ExplodedNodeSet::iterator i = dstPrevisit.begin(), 882f85e193739c953358c865005855253af4f68a497John McCall e = dstPrevisit.end(); i != e ; ++i) { 883f85e193739c953358c865005855253af4f68a497John McCall VisitCast(C, C->getSubExpr(), *i, dstExpr); 884f85e193739c953358c865005855253af4f68a497John McCall } 885f85e193739c953358c865005855253af4f68a497John McCall 886f85e193739c953358c865005855253af4f68a497John McCall // Handle the postvisit checks. 887f85e193739c953358c865005855253af4f68a497John McCall getCheckerManager().runCheckersForPostStmt(Dst, dstExpr, C, *this); 888ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 889e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek break; 890e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek } 891b9bbd592c7ea72ada8d982e40a729beb9b53371eTed Kremenek 89203e80030515c800d1ab44125b9052dfffd1bd04cDouglas Gregor case Expr::MaterializeTemporaryExprClass: { 893ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 894c210cb7a358d14cdd93b58562f33ff5ed2d895c1Jordan Rose const MaterializeTemporaryExpr *MTE = cast<MaterializeTemporaryExpr>(S); 895c210cb7a358d14cdd93b58562f33ff5ed2d895c1Jordan Rose CreateCXXTemporaryObject(MTE, Pred, Dst); 896ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 89703e80030515c800d1ab44125b9052dfffd1bd04cDouglas Gregor break; 89803e80030515c800d1ab44125b9052dfffd1bd04cDouglas Gregor } 89903e80030515c800d1ab44125b9052dfffd1bd04cDouglas Gregor 900c4f8706b6539e06a5de153bd72850bb2e0a71456Zhongxing Xu case Stmt::InitListExprClass: 901ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 902c4f8706b6539e06a5de153bd72850bb2e0a71456Zhongxing Xu VisitInitListExpr(cast<InitListExpr>(S), Pred, Dst); 903ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 904c4f8706b6539e06a5de153bd72850bb2e0a71456Zhongxing Xu break; 9051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 90697ed4f68f5dba3e21e7a490ef0f9ffd3bfead7f8Ted Kremenek case Stmt::MemberExprClass: 907ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 908892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek VisitMemberExpr(cast<MemberExpr>(S), Pred, Dst); 909ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 910469ecbded3616416ef938ed94a67f86149faf226Ted Kremenek break; 911ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks 91297ed4f68f5dba3e21e7a490ef0f9ffd3bfead7f8Ted Kremenek case Stmt::ObjCIvarRefExprClass: 913ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 914892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek VisitLvalObjCIvarRefExpr(cast<ObjCIvarRefExpr>(S), Pred, Dst); 915ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 91697ed4f68f5dba3e21e7a490ef0f9ffd3bfead7f8Ted Kremenek break; 917af3374187c47acea45706eab6744be6b1c66a856Ted Kremenek 918af3374187c47acea45706eab6744be6b1c66a856Ted Kremenek case Stmt::ObjCForCollectionStmtClass: 919ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 920af3374187c47acea45706eab6744be6b1c66a856Ted Kremenek VisitObjCForCollectionStmt(cast<ObjCForCollectionStmt>(S), Pred, Dst); 921ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 922af3374187c47acea45706eab6744be6b1c66a856Ted Kremenek break; 9231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 924d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose case Stmt::ObjCMessageExprClass: 925ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 926d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose VisitObjCMessage(cast<ObjCMessageExpr>(S), Pred, Dst); 927ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 928e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek break; 9291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 930c32a453e40b2c8878fed10512fb2f570b7aba576Jordan Rose case Stmt::ObjCAtThrowStmtClass: 931c32a453e40b2c8878fed10512fb2f570b7aba576Jordan Rose case Stmt::CXXThrowExprClass: 932bbfd07a0c94f659beaf74316029ef73769cefb81Ted Kremenek // FIXME: This is not complete. We basically treat @throw as 933bbfd07a0c94f659beaf74316029ef73769cefb81Ted Kremenek // an abort. 934fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose Bldr.generateSink(S, Pred, Pred->getState()); 935bbfd07a0c94f659beaf74316029ef73769cefb81Ted Kremenek break; 9361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 9371b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek case Stmt::ReturnStmtClass: 938ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 9391b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek VisitReturnStmt(cast<ReturnStmt>(S), Pred, Dst); 940ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 9411b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek break; 9421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 9438ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor case Stmt::OffsetOfExprClass: 944ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 9458ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor VisitOffsetOfExpr(cast<OffsetOfExpr>(S), Pred, Dst); 946ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 9478ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor break; 9488ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor 949f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne case Stmt::UnaryExprOrTypeTraitExprClass: 950ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 951f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne VisitUnaryExprOrTypeTraitExpr(cast<UnaryExprOrTypeTraitExpr>(S), 952f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne Pred, Dst); 953ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 954e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek break; 9551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 956e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek case Stmt::StmtExprClass: { 9579c378f705405d37f49795d5e915989de774fe11fTed Kremenek const StmtExpr *SE = cast<StmtExpr>(S); 958a3d1eb85853eae7b719f679b40923826b5e4b7dfTed Kremenek 959a3d1eb85853eae7b719f679b40923826b5e4b7dfTed Kremenek if (SE->getSubStmt()->body_empty()) { 960a3d1eb85853eae7b719f679b40923826b5e4b7dfTed Kremenek // Empty statement expression. 961a3d1eb85853eae7b719f679b40923826b5e4b7dfTed Kremenek assert(SE->getType() == getContext().VoidTy 962a3d1eb85853eae7b719f679b40923826b5e4b7dfTed Kremenek && "Empty statement expression must have void type."); 963a3d1eb85853eae7b719f679b40923826b5e4b7dfTed Kremenek break; 964a3d1eb85853eae7b719f679b40923826b5e4b7dfTed Kremenek } 9651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 9669c378f705405d37f49795d5e915989de774fe11fTed Kremenek if (Expr *LastExpr = dyn_cast<Expr>(*SE->getSubStmt()->body_rbegin())) { 9678bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek ProgramStateRef state = Pred->getState(); 968ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.generateNode(SE, Pred, 9695eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek state->BindExpr(SE, Pred->getLocationContext(), 9705eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek state->getSVal(LastExpr, 9715eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek Pred->getLocationContext()))); 972a3d1eb85853eae7b719f679b40923826b5e4b7dfTed Kremenek } 973e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek break; 974e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek } 9756987c7b74146b9658b1925c5981f8b0cd0672b55Zhongxing Xu 97672374594c5d9ade02451bc85cf9dfa5b0ea106e7Ted Kremenek case Stmt::UnaryOperatorClass: { 977ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 97803509aea098772644bf4662dc1c88634818ceeccZhongxing Xu const UnaryOperator *U = cast<UnaryOperator>(S); 9790caa2d47b84337e942b3f6652adfafe4ae506cfeTed Kremenek if (AMgr.options.eagerlyAssumeBinOpBifurcation && (U->getOpcode() == UO_LNot)) { 980031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu ExplodedNodeSet Tmp; 981892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek VisitUnaryOperator(U, Pred, Tmp); 9820caa2d47b84337e942b3f6652adfafe4ae506cfeTed Kremenek evalEagerlyAssumeBinOpBifurcation(Dst, Tmp, U); 98372374594c5d9ade02451bc85cf9dfa5b0ea106e7Ted Kremenek } 98472374594c5d9ade02451bc85cf9dfa5b0ea106e7Ted Kremenek else 985892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek VisitUnaryOperator(U, Pred, Dst); 986ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 9871b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek break; 98872374594c5d9ade02451bc85cf9dfa5b0ea106e7Ted Kremenek } 9894b9c2d235fb9449e249d74f48ecfec601650de93John McCall 9904b9c2d235fb9449e249d74f48ecfec601650de93John McCall case Stmt::PseudoObjectExprClass: { 9914b9c2d235fb9449e249d74f48ecfec601650de93John McCall Bldr.takeNodes(Pred); 9928bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek ProgramStateRef state = Pred->getState(); 9934b9c2d235fb9449e249d74f48ecfec601650de93John McCall const PseudoObjectExpr *PE = cast<PseudoObjectExpr>(S); 9944b9c2d235fb9449e249d74f48ecfec601650de93John McCall if (const Expr *Result = PE->getResultExpr()) { 9955eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek SVal V = state->getSVal(Result, Pred->getLocationContext()); 9965eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek Bldr.generateNode(S, Pred, 9975eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek state->BindExpr(S, Pred->getLocationContext(), V)); 9984b9c2d235fb9449e249d74f48ecfec601650de93John McCall } 9994b9c2d235fb9449e249d74f48ecfec601650de93John McCall else 10005eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek Bldr.generateNode(S, Pred, 10015eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek state->BindExpr(S, Pred->getLocationContext(), 10025eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek UnknownVal())); 10034b9c2d235fb9449e249d74f48ecfec601650de93John McCall 10044b9c2d235fb9449e249d74f48ecfec601650de93John McCall Bldr.addNodes(Dst); 10054b9c2d235fb9449e249d74f48ecfec601650de93John McCall break; 10064b9c2d235fb9449e249d74f48ecfec601650de93John McCall } 10071b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek } 10081b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek} 10091b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek 10105903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaksbool ExprEngine::replayWithoutInlining(ExplodedNode *N, 10115903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks const LocationContext *CalleeLC) { 10125903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks const StackFrameContext *CalleeSF = CalleeLC->getCurrentStackFrame(); 10135903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks const StackFrameContext *CallerSF = CalleeSF->getParent()->getCurrentStackFrame(); 10145903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks assert(CalleeSF && CallerSF); 10155903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks ExplodedNode *BeforeProcessingCall = 0; 101628038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose const Stmt *CE = CalleeSF->getCallSite(); 10175903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks 10185903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks // Find the first node before we started processing the call expression. 10195903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks while (N) { 10205903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks ProgramPoint L = N->getLocation(); 10215903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks BeforeProcessingCall = N; 10225903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks N = N->pred_empty() ? NULL : *(N->pred_begin()); 10235903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks 10245903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks // Skip the nodes corresponding to the inlined code. 10255903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks if (L.getLocationContext()->getCurrentStackFrame() != CallerSF) 10265903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks continue; 10275903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks // We reached the caller. Find the node right before we started 102828038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose // processing the call. 10290b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks if (L.isPurgeKind()) 10305903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks continue; 103128038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose if (isa<PreImplicitCall>(&L)) 103228038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose continue; 1033852aa0d2c5d2d1faf2d77b5aa3c0848068a342c5Jordan Rose if (isa<CallEnter>(&L)) 1034852aa0d2c5d2d1faf2d77b5aa3c0848068a342c5Jordan Rose continue; 10355903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks if (const StmtPoint *SP = dyn_cast<StmtPoint>(&L)) 103628038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose if (SP->getStmt() == CE) 10375903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks continue; 10385903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks break; 10395903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks } 10405903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks 1041253955ca25c7e7049963b5db613c0cd15d66e4f8Anna Zaks if (!BeforeProcessingCall) 10425903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks return false; 10435903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks 10445903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks // TODO: Clean up the unneeded nodes. 10455903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks 10465903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks // Build an Epsilon node from which we will restart the analyzes. 104728038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose // Note that CE is permitted to be NULL! 10485903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks ProgramPoint NewNodeLoc = 10495903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks EpsilonPoint(BeforeProcessingCall->getLocationContext(), CE); 10505903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks // Add the special flag to GDM to signal retrying with no inlining. 10515903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks // Note, changing the state ensures that we are not going to cache out. 10525903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks ProgramStateRef NewNodeState = BeforeProcessingCall->getState(); 10535903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks NewNodeState = NewNodeState->set<ReplayWithoutInlining>((void*)CE); 10545903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks 10555903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks // Make the new node a successor of BeforeProcessingCall. 10565903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks bool IsNew = false; 10575903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks ExplodedNode *NewNode = G.getNode(NewNodeLoc, NewNodeState, false, &IsNew); 1058253955ca25c7e7049963b5db613c0cd15d66e4f8Anna Zaks // We cached out at this point. Caching out is common due to us backtracking 1059253955ca25c7e7049963b5db613c0cd15d66e4f8Anna Zaks // from the inlined function, which might spawn several paths. 1060253955ca25c7e7049963b5db613c0cd15d66e4f8Anna Zaks if (!IsNew) 1061253955ca25c7e7049963b5db613c0cd15d66e4f8Anna Zaks return true; 1062253955ca25c7e7049963b5db613c0cd15d66e4f8Anna Zaks 10635903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks NewNode->addPredecessor(BeforeProcessingCall, G); 10645903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks 10655903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks // Add the new node to the work list. 10665903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks Engine.enqueueStmtNode(NewNode, CalleeSF->getCallSiteBlock(), 10675903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks CalleeSF->getIndex()); 10685903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks NumTimesRetriedWithoutInlining++; 10695903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks return true; 10705903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks} 10715903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks 1072c03a39e16762627b421247b12a2658be630a3300Anna Zaks/// Block entrance. (Update counters). 1073253955ca25c7e7049963b5db613c0cd15d66e4f8Anna Zaksvoid ExprEngine::processCFGBlockEntrance(const BlockEdge &L, 1074b355be838a22a511d078504b2277f70aea52ca85Anna Zaks NodeBuilderWithSinks &nodeBuilder, 1075b355be838a22a511d078504b2277f70aea52ca85Anna Zaks ExplodedNode *Pred) { 107627c54e57c4a012dcdf2b40cf985b70d0b9caa69eTed Kremenek 107727c54e57c4a012dcdf2b40cf985b70d0b9caa69eTed Kremenek // FIXME: Refactor this into a checker. 10782fa9d72d4d23ccdcd4137946e5ebafac7a04f04cTed Kremenek if (nodeBuilder.getContext().blockCount() >= AMgr.options.maxBlockVisitOnPath) { 1079ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek static SimpleProgramPointTag tag("ExprEngine : Block count exceeded"); 1080253955ca25c7e7049963b5db613c0cd15d66e4f8Anna Zaks const ExplodedNode *Sink = 1081b355be838a22a511d078504b2277f70aea52ca85Anna Zaks nodeBuilder.generateSink(Pred->getState(), Pred, &tag); 1082749bbe6f5f23676244f12a0d41511c8e73516febAnna Zaks 1083749bbe6f5f23676244f12a0d41511c8e73516febAnna Zaks // Check if we stopped at the top level function or not. 1084749bbe6f5f23676244f12a0d41511c8e73516febAnna Zaks // Root node should have the location context of the top most function. 1085b355be838a22a511d078504b2277f70aea52ca85Anna Zaks const LocationContext *CalleeLC = Pred->getLocation().getLocationContext(); 10863bbd8cd831788c506f2980293eb3c7e1b3ca2501Anna Zaks const LocationContext *CalleeSF = CalleeLC->getCurrentStackFrame(); 10875903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks const LocationContext *RootLC = 10885903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks (*G.roots_begin())->getLocation().getLocationContext(); 10893bbd8cd831788c506f2980293eb3c7e1b3ca2501Anna Zaks if (RootLC->getCurrentStackFrame() != CalleeSF) { 1090e62f048960645b79363408fdead53fec2a063c52Anna Zaks Engine.FunctionSummaries->markReachedMaxBlockCount(CalleeSF->getDecl()); 10913bbd8cd831788c506f2980293eb3c7e1b3ca2501Anna Zaks 10925903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks // Re-run the call evaluation without inlining it, by storing the 10935903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks // no-inlining policy in the state and enqueuing the new work item on 10945903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks // the list. Replay should almost never fail. Use the stats to catch it 10955903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks // if it does. 1096255d4d4226b24036ceb11228fbb74286e58620f7Ted Kremenek if ((!AMgr.options.NoRetryExhausted && 1097b355be838a22a511d078504b2277f70aea52ca85Anna Zaks replayWithoutInlining(Pred, CalleeLC))) 1098253955ca25c7e7049963b5db613c0cd15d66e4f8Anna Zaks return; 1099253955ca25c7e7049963b5db613c0cd15d66e4f8Anna Zaks NumMaxBlockCountReachedInInlined++; 11005903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks } else 1101749bbe6f5f23676244f12a0d41511c8e73516febAnna Zaks NumMaxBlockCountReached++; 1102253955ca25c7e7049963b5db613c0cd15d66e4f8Anna Zaks 1103253955ca25c7e7049963b5db613c0cd15d66e4f8Anna Zaks // Make sink nodes as exhausted(for stats) only if retry failed. 1104253955ca25c7e7049963b5db613c0cd15d66e4f8Anna Zaks Engine.blocksExhausted.push_back(std::make_pair(L, Sink)); 110527c54e57c4a012dcdf2b40cf985b70d0b9caa69eTed Kremenek } 1106e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek} 1107e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek 1108e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek//===----------------------------------------------------------------------===// 1109e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek// Branch processing. 1110e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek//===----------------------------------------------------------------------===// 1111e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek 11126ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek/// RecoverCastedSymbol - A helper function for ProcessBranch that is used 11136ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek/// to try to recover some path-sensitivity for casts of symbolic 11146ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek/// integers that promote their values (which are currently not tracked well). 11156ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek/// This function returns the SVal bound to Condition->IgnoreCasts if all the 11166ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek// cast(s) did was sign-extend the original value. 1117294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenekstatic SVal RecoverCastedSymbol(ProgramStateManager& StateMgr, 11188bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek ProgramStateRef state, 1119294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const Stmt *Condition, 11205eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek const LocationContext *LCtx, 1121294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ASTContext &Ctx) { 11226ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek 112303509aea098772644bf4662dc1c88634818ceeccZhongxing Xu const Expr *Ex = dyn_cast<Expr>(Condition); 11246ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek if (!Ex) 11256ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek return UnknownVal(); 11266ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek 11276ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek uint64_t bits = 0; 11286ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek bool bitsInit = false; 11291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 113003509aea098772644bf4662dc1c88634818ceeccZhongxing Xu while (const CastExpr *CE = dyn_cast<CastExpr>(Ex)) { 11316ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek QualType T = CE->getType(); 11326ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek 11336ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek if (!T->isIntegerType()) 11346ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek return UnknownVal(); 11351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 11366ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek uint64_t newBits = Ctx.getTypeSize(T); 11376ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek if (!bitsInit || newBits < bits) { 11386ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek bitsInit = true; 11396ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek bits = newBits; 11406ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek } 11411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 11426ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek Ex = CE->getSubExpr(); 11436ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek } 11446ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek 11456ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek // We reached a non-cast. Is it a symbolic value? 11466ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek QualType T = Ex->getType(); 11476ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek 11486ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek if (!bitsInit || !T->isIntegerType() || Ctx.getTypeSize(T) > bits) 11496ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek return UnknownVal(); 11501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 11515eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek return state->getSVal(Ex, LCtx); 11526ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek} 11536ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek 11543f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenekstatic const Stmt *ResolveCondition(const Stmt *Condition, 11553f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek const CFGBlock *B) { 11563f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek if (const Expr *Ex = dyn_cast<Expr>(Condition)) 11573f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek Condition = Ex->IgnoreParens(); 11583f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 11593f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek const BinaryOperator *BO = dyn_cast<BinaryOperator>(Condition); 11603f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek if (!BO || !BO->isLogicalOp()) 11613f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek return Condition; 11623f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 11633f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // For logical operations, we still have the case where some branches 11643f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // use the traditional "merge" approach and others sink the branch 11653f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // directly into the basic blocks representing the logical operation. 11663f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // We need to distinguish between those two cases here. 11673f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 11683f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // The invariants are still shifting, but it is possible that the 11693f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // last element in a CFGBlock is not a CFGStmt. Look for the last 11703f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // CFGStmt as the value of the condition. 11713f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek CFGBlock::const_reverse_iterator I = B->rbegin(), E = B->rend(); 11723f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek for (; I != E; ++I) { 11733f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek CFGElement Elem = *I; 11743f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek CFGStmt *CS = dyn_cast<CFGStmt>(&Elem); 11753f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek if (!CS) 11763f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek continue; 11773f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek if (CS->getStmt() != Condition) 11783f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek break; 11793f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek return Condition; 11803f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek } 11813f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 11823f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek assert(I != E); 11833f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 11843f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek while (Condition) { 11853f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek BO = dyn_cast<BinaryOperator>(Condition); 11863f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek if (!BO || !BO->isLogicalOp()) 11873f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek return Condition; 11883f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek Condition = BO->getRHS()->IgnoreParens(); 11893f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek } 11903f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek llvm_unreachable("could not resolve condition"); 11913f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek} 11923f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 11939c378f705405d37f49795d5e915989de774fe11fTed Kremenekvoid ExprEngine::processBranch(const Stmt *Condition, const Stmt *Term, 1194a19f4af7a94835ce4693bfe12d6270754e79eb56Anna Zaks NodeBuilderContext& BldCtx, 1195ad62deeb70e97da6bd514dd390ea1ce6af6ad81dAnna Zaks ExplodedNode *Pred, 11961aae01a8308d2f8e31adab3f4d7ac35543aac680Anna Zaks ExplodedNodeSet &Dst, 1197a19f4af7a94835ce4693bfe12d6270754e79eb56Anna Zaks const CFGBlock *DstT, 1198a19f4af7a94835ce4693bfe12d6270754e79eb56Anna Zaks const CFGBlock *DstF) { 119966c486f275531df6362b3511fc3af6563561801bTed Kremenek currBldrCtx = &BldCtx; 1200f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks 1201b2331834a0515c80862ee51325c758a053829f15Ted Kremenek // Check for NULL conditions; e.g. "for(;;)" 12021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (!Condition) { 12031aae01a8308d2f8e31adab3f4d7ac35543aac680Anna Zaks BranchNodeBuilder NullCondBldr(Pred, Dst, BldCtx, DstT, DstF); 1204a19f4af7a94835ce4693bfe12d6270754e79eb56Anna Zaks NullCondBldr.markInfeasible(false); 12054e82d3cf6fd4c907265e3fa3aac0a835c35dc759Anna Zaks NullCondBldr.generateNode(Pred->getState(), true, Pred); 1206b2331834a0515c80862ee51325c758a053829f15Ted Kremenek return; 1207b2331834a0515c80862ee51325c758a053829f15Ted Kremenek } 12081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 12093f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 12103f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // Resolve the condition in the precense of nested '||' and '&&'. 12113f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek if (const Expr *Ex = dyn_cast<Expr>(Condition)) 12123f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek Condition = Ex->IgnoreParens(); 12133f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 12143f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek Condition = ResolveCondition(Condition, BldCtx.getBlock()); 121521028dd8850c64a414f7a82dfddcc291351203d6Ted Kremenek PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(), 121621028dd8850c64a414f7a82dfddcc291351203d6Ted Kremenek Condition->getLocStart(), 121721028dd8850c64a414f7a82dfddcc291351203d6Ted Kremenek "Error evaluating branch"); 12180fb0bc4067d6c9d7c0e655300ef309b05d3adfc9Ted Kremenek 1219f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks ExplodedNodeSet CheckersOutSet; 1220f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks getCheckerManager().runCheckersForBranchCondition(Condition, CheckersOutSet, 12214e82d3cf6fd4c907265e3fa3aac0a835c35dc759Anna Zaks Pred, *this); 12228ff5c41f2bde7ebbe568b4c15e59f14b8befae66Anna Zaks // We generated only sinks. 1223f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks if (CheckersOutSet.empty()) 12248ff5c41f2bde7ebbe568b4c15e59f14b8befae66Anna Zaks return; 12251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1226f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks BranchNodeBuilder builder(CheckersOutSet, Dst, BldCtx, DstT, DstF); 1227f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks for (NodeBuilder::iterator I = CheckersOutSet.begin(), 1228f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks E = CheckersOutSet.end(); E != I; ++I) { 1229cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks ExplodedNode *PredI = *I; 1230cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks 1231cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks if (PredI->isSink()) 1232cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks continue; 1233cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks 12348bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek ProgramStateRef PrevState = Pred->getState(); 12355eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek SVal X = PrevState->getSVal(Condition, Pred->getLocationContext()); 1236cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks 1237cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks if (X.isUnknownOrUndef()) { 1238cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks // Give it a chance to recover from unknown. 1239cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks if (const Expr *Ex = dyn_cast<Expr>(Condition)) { 1240cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks if (Ex->getType()->isIntegerType()) { 1241cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks // Try to recover some path-sensitivity. Right now casts of symbolic 1242cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks // integers that promote their values are currently not tracked well. 1243cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks // If 'Condition' is such an expression, try and recover the 1244cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks // underlying value and use that instead. 1245cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks SVal recovered = RecoverCastedSymbol(getStateManager(), 1246cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks PrevState, Condition, 12475eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek Pred->getLocationContext(), 1248cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks getContext()); 1249cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks 1250cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks if (!recovered.isUnknown()) { 1251cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks X = recovered; 1252cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks } 12530835e4cccfef3ea5346962722b79484f6b3ca602Zhongxing Xu } 1254b38911f16b4943548db6a3695fc6ae23070b25d2Ted Kremenek } 12550835e4cccfef3ea5346962722b79484f6b3ca602Zhongxing Xu } 12565eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek 12570835e4cccfef3ea5346962722b79484f6b3ca602Zhongxing Xu // If the condition is still unknown, give up. 125873c498a08f4968b6987d1453c7b77929dcc6d5f7Argyrios Kyrtzidis if (X.isUnknownOrUndef()) { 1259829846b5002d7f8d6a54b9c58c3ecf7cac56d2ccTed Kremenek builder.generateNode(PrevState, true, PredI); 1260829846b5002d7f8d6a54b9c58c3ecf7cac56d2ccTed Kremenek builder.generateNode(PrevState, false, PredI); 1261cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks continue; 12621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 12631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1264cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks DefinedSVal V = cast<DefinedSVal>(X); 12650835e4cccfef3ea5346962722b79484f6b3ca602Zhongxing Xu 12666960d08b4ddf389d7c81504df7f16dc645120482Jordan Rose ProgramStateRef StTrue, StFalse; 12676960d08b4ddf389d7c81504df7f16dc645120482Jordan Rose tie(StTrue, StFalse) = PrevState->assume(V); 12686960d08b4ddf389d7c81504df7f16dc645120482Jordan Rose 1269cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks // Process the true branch. 1270cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks if (builder.isFeasible(true)) { 12716960d08b4ddf389d7c81504df7f16dc645120482Jordan Rose if (StTrue) 12726960d08b4ddf389d7c81504df7f16dc645120482Jordan Rose builder.generateNode(StTrue, true, PredI); 1273cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks else 1274cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks builder.markInfeasible(true); 1275cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks } 12761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1277cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks // Process the false branch. 1278cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks if (builder.isFeasible(false)) { 12796960d08b4ddf389d7c81504df7f16dc645120482Jordan Rose if (StFalse) 12806960d08b4ddf389d7c81504df7f16dc645120482Jordan Rose builder.generateNode(StFalse, false, PredI); 1281cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks else 1282cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks builder.markInfeasible(false); 1283cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks } 1284cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks } 128566c486f275531df6362b3511fc3af6563561801bTed Kremenek currBldrCtx = 0; 1286f233d48cfc513b045e2c2cfca5c175220fbd0a82Ted Kremenek} 1287f233d48cfc513b045e2c2cfca5c175220fbd0a82Ted Kremenek 1288e36de1fe51c39d9161915dd3dbef880954af6476Ted Kremenek/// processIndirectGoto - Called by CoreEngine. Used to generate successor 1289754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek/// nodes by processing the 'effects' of a computed goto jump. 1290ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattnervoid ExprEngine::processIndirectGoto(IndirectGotoNodeBuilder &builder) { 1291754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek 12928bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek ProgramStateRef state = builder.getState(); 12935eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek SVal V = state->getSVal(builder.getTarget(), builder.getLocationContext()); 12941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1295754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek // Three possibilities: 1296754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek // 1297754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek // (1) We know the computed label. 12984a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek // (2) The label is NULL (or some other constant), or Undefined. 1299754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek // (3) We have no clue about the label. Dispatch to all targets. 1300754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek // 13011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1302d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis typedef IndirectGotoNodeBuilder::iterator iterator; 1303754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek 13041c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu if (isa<loc::GotoLabel>(V)) { 1305ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattner const LabelDecl *L = cast<loc::GotoLabel>(V).getLabel(); 13061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1307ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattner for (iterator I = builder.begin(), E = builder.end(); I != E; ++I) { 130824f1a967741ff9f8025ee23be12ba6feacc31f77Ted Kremenek if (I.getLabel() == L) { 1309a8538d902fce9cfec20f39b34492268b51643819Ted Kremenek builder.generateNode(I, state); 1310754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek return; 1311754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek } 1312754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek } 13131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1314b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie llvm_unreachable("No block with label."); 1315754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek } 1316754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek 13171c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu if (isa<loc::ConcreteInt>(V) || isa<UndefinedVal>(V)) { 1318754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek // Dispatch to the first target and mark it as a sink. 13192055effed54d614b51e3501a174c9b1fe92e4de4Zhongxing Xu //ExplodedNode* N = builder.generateNode(builder.begin(), state, true); 13202055effed54d614b51e3501a174c9b1fe92e4de4Zhongxing Xu // FIXME: add checker visit. 13212055effed54d614b51e3501a174c9b1fe92e4de4Zhongxing Xu // UndefBranches.insert(N); 1322754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek return; 1323754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek } 13241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1325754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek // This is really a catch-all. We don't support symbolics yet. 1326b3cfd58c9b13325d994e5f9b5065e6a22d91911dTed Kremenek // FIXME: Implement dispatch for symbolic pointers. 13271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1328754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek for (iterator I=builder.begin(), E=builder.end(); I != E; ++I) 1329a8538d902fce9cfec20f39b34492268b51643819Ted Kremenek builder.generateNode(I, state); 1330754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek} 1331f233d48cfc513b045e2c2cfca5c175220fbd0a82Ted Kremenek 1332d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis/// ProcessEndPath - Called by CoreEngine. Used to generate end-of-path 133373099bfea9f5d4ec05265170bbefec3d76fb6b5eTed Kremenek/// nodes when the control reaches the end of a function. 1334b355be838a22a511d078504b2277f70aea52ca85Anna Zaksvoid ExprEngine::processEndOfFunction(NodeBuilderContext& BC, 1335b355be838a22a511d078504b2277f70aea52ca85Anna Zaks ExplodedNode *Pred) { 1336b355be838a22a511d078504b2277f70aea52ca85Anna Zaks StateMgr.EndPath(Pred->getState()); 13378501b7a1c4c4a9ba0ea6cb8e500e601ef3759debAnna Zaks 1338af498a28797c075c48d7e943df5f5a8e78ed8eb0Anna Zaks ExplodedNodeSet Dst; 13398501b7a1c4c4a9ba0ea6cb8e500e601ef3759debAnna Zaks if (Pred->getLocationContext()->inTopFrame()) { 13408501b7a1c4c4a9ba0ea6cb8e500e601ef3759debAnna Zaks // Remove dead symbols. 13418501b7a1c4c4a9ba0ea6cb8e500e601ef3759debAnna Zaks ExplodedNodeSet AfterRemovedDead; 13428501b7a1c4c4a9ba0ea6cb8e500e601ef3759debAnna Zaks removeDeadOnEndOfFunction(BC, Pred, AfterRemovedDead); 13438501b7a1c4c4a9ba0ea6cb8e500e601ef3759debAnna Zaks 13448501b7a1c4c4a9ba0ea6cb8e500e601ef3759debAnna Zaks // Notify checkers. 13458501b7a1c4c4a9ba0ea6cb8e500e601ef3759debAnna Zaks for (ExplodedNodeSet::iterator I = AfterRemovedDead.begin(), 13468501b7a1c4c4a9ba0ea6cb8e500e601ef3759debAnna Zaks E = AfterRemovedDead.end(); I != E; ++I) { 13478501b7a1c4c4a9ba0ea6cb8e500e601ef3759debAnna Zaks getCheckerManager().runCheckersForEndPath(BC, Dst, *I, *this); 13488501b7a1c4c4a9ba0ea6cb8e500e601ef3759debAnna Zaks } 13498501b7a1c4c4a9ba0ea6cb8e500e601ef3759debAnna Zaks } else { 13508501b7a1c4c4a9ba0ea6cb8e500e601ef3759debAnna Zaks getCheckerManager().runCheckersForEndPath(BC, Dst, Pred, *this); 13518501b7a1c4c4a9ba0ea6cb8e500e601ef3759debAnna Zaks } 13528501b7a1c4c4a9ba0ea6cb8e500e601ef3759debAnna Zaks 13534d2ae4a70336dc2aa11389b34946be152bb454c9Anna Zaks Engine.enqueueEndOfFunction(Dst); 135473099bfea9f5d4ec05265170bbefec3d76fb6b5eTed Kremenek} 135573099bfea9f5d4ec05265170bbefec3d76fb6b5eTed Kremenek 1356d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis/// ProcessSwitch - Called by CoreEngine. Used to generate successor 1357daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek/// nodes by processing the 'effects' of a switch statement. 1358e36de1fe51c39d9161915dd3dbef880954af6476Ted Kremenekvoid ExprEngine::processSwitch(SwitchNodeBuilder& builder) { 1359d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis typedef SwitchNodeBuilder::iterator iterator; 13608bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek ProgramStateRef state = builder.getState(); 13619c378f705405d37f49795d5e915989de774fe11fTed Kremenek const Expr *CondE = builder.getCondition(); 13625eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek SVal CondV_untested = state->getSVal(CondE, builder.getLocationContext()); 1363daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek 13645b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek if (CondV_untested.isUndef()) { 13652055effed54d614b51e3501a174c9b1fe92e4de4Zhongxing Xu //ExplodedNode* N = builder.generateDefaultCaseNode(state, true); 1366b9bbd592c7ea72ada8d982e40a729beb9b53371eTed Kremenek // FIXME: add checker 13672055effed54d614b51e3501a174c9b1fe92e4de4Zhongxing Xu //UndefBranches.insert(N); 13682055effed54d614b51e3501a174c9b1fe92e4de4Zhongxing Xu 1369daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek return; 1370daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek } 13715b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek DefinedOrUnknownSVal CondV = cast<DefinedOrUnknownSVal>(CondV_untested); 1372692416c214a3b234236dedcf875735a9cc29e90bTed Kremenek 13738bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek ProgramStateRef DefaultSt = state; 137434feff654c6304e0a59ceb1376989d28dbc956ffTed Kremenek 137534feff654c6304e0a59ceb1376989d28dbc956ffTed Kremenek iterator I = builder.begin(), EI = builder.end(); 137634feff654c6304e0a59ceb1376989d28dbc956ffTed Kremenek bool defaultIsFeasible = I == EI; 13771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 137834feff654c6304e0a59ceb1376989d28dbc956ffTed Kremenek for ( ; I != EI; ++I) { 1379e71f3d587844110d836c82250830b27b1651afdbTed Kremenek // Successor may be pruned out during CFG construction. 1380e71f3d587844110d836c82250830b27b1651afdbTed Kremenek if (!I.getBlock()) 1381e71f3d587844110d836c82250830b27b1651afdbTed Kremenek continue; 1382e71f3d587844110d836c82250830b27b1651afdbTed Kremenek 13839c378f705405d37f49795d5e915989de774fe11fTed Kremenek const CaseStmt *Case = I.getCase(); 138472afb3739da0da02158242ae41a50cfe0bea78b4Ted Kremenek 138572afb3739da0da02158242ae41a50cfe0bea78b4Ted Kremenek // Evaluate the LHS of the case value. 138685df96c1f04867e26ba069aa0cc6a4cd6a01292eRichard Smith llvm::APSInt V1 = Case->getLHS()->EvaluateKnownConstInt(getContext()); 138785df96c1f04867e26ba069aa0cc6a4cd6a01292eRichard Smith assert(V1.getBitWidth() == getContext().getTypeSize(CondE->getType())); 13881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1389daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek // Get the RHS of the case, if it exists. 139085df96c1f04867e26ba069aa0cc6a4cd6a01292eRichard Smith llvm::APSInt V2; 139185df96c1f04867e26ba069aa0cc6a4cd6a01292eRichard Smith if (const Expr *E = Case->getRHS()) 139285df96c1f04867e26ba069aa0cc6a4cd6a01292eRichard Smith V2 = E->EvaluateKnownConstInt(getContext()); 139314a1140c9f4e20b12a54db8745b74699b9872cd2Ted Kremenek else 139414a1140c9f4e20b12a54db8745b74699b9872cd2Ted Kremenek V2 = V1; 13951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1396daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek // FIXME: Eventually we should replace the logic below with a range 1397daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek // comparison, rather than concretize the values within the range. 1398aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek // This should be easy once we have "ranges" for NonLVals. 13991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 140014a1140c9f4e20b12a54db8745b74699b9872cd2Ted Kremenek do { 140185df96c1f04867e26ba069aa0cc6a4cd6a01292eRichard Smith nonloc::ConcreteInt CaseVal(getBasicVals().getValue(V1)); 14029c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek DefinedOrUnknownSVal Res = svalBuilder.evalEQ(DefaultSt ? DefaultSt : state, 140348569f9562740ac1f4b175cb17ce3d49035402c4Ted Kremenek CondV, CaseVal); 1404b9bbd592c7ea72ada8d982e40a729beb9b53371eTed Kremenek 14051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // Now "assume" that the case matches. 14068bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek if (ProgramStateRef stateNew = state->assume(Res, true)) { 1407a591bc04d21fa62ebffcb2c7814d738ca8f5e2f9Ted Kremenek builder.generateCaseStmtNode(I, stateNew); 14081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1409daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek // If CondV evaluates to a constant, then we know that this 1410daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek // is the *only* case that we can take, so stop evaluating the 1411daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek // others. 14121c96b24285d05c0eac455ae96d7c9ff43d42bc96Zhongxing Xu if (isa<nonloc::ConcreteInt>(CondV)) 1413daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek return; 1414daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek } 14151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1416daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek // Now "assume" that the case doesn't match. Add this state 1417daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek // to the default state (if it is feasible). 141848569f9562740ac1f4b175cb17ce3d49035402c4Ted Kremenek if (DefaultSt) { 14198bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek if (ProgramStateRef stateNew = DefaultSt->assume(Res, false)) { 142048569f9562740ac1f4b175cb17ce3d49035402c4Ted Kremenek defaultIsFeasible = true; 142148569f9562740ac1f4b175cb17ce3d49035402c4Ted Kremenek DefaultSt = stateNew; 142248569f9562740ac1f4b175cb17ce3d49035402c4Ted Kremenek } 142348569f9562740ac1f4b175cb17ce3d49035402c4Ted Kremenek else { 142448569f9562740ac1f4b175cb17ce3d49035402c4Ted Kremenek defaultIsFeasible = false; 142548569f9562740ac1f4b175cb17ce3d49035402c4Ted Kremenek DefaultSt = NULL; 142648569f9562740ac1f4b175cb17ce3d49035402c4Ted Kremenek } 14275014ab113eb211b8320ae30b173d7020352663c6Ted Kremenek } 1428b9bbd592c7ea72ada8d982e40a729beb9b53371eTed Kremenek 142914a1140c9f4e20b12a54db8745b74699b9872cd2Ted Kremenek // Concretize the next value in the range. 143085df96c1f04867e26ba069aa0cc6a4cd6a01292eRichard Smith if (V1 == V2) 143114a1140c9f4e20b12a54db8745b74699b9872cd2Ted Kremenek break; 14321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 143385df96c1f04867e26ba069aa0cc6a4cd6a01292eRichard Smith ++V1; 143485df96c1f04867e26ba069aa0cc6a4cd6a01292eRichard Smith assert (V1 <= V2); 14351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 143614a1140c9f4e20b12a54db8745b74699b9872cd2Ted Kremenek } while (true); 1437daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek } 14381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 14394d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek if (!defaultIsFeasible) 14404d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek return; 14414d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek 14424d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek // If we have switch(enum value), the default branch is not 14434d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek // feasible if all of the enum constants not covered by 'case:' statements 14444d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek // are not feasible values for the switch condition. 14454d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek // 14464d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek // Note that this isn't as accurate as it could be. Even if there isn't 14474d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek // a case for a particular enum value as long as that enum value isn't 14484d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek // feasible then it shouldn't be considered for making 'default:' reachable. 14494d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek const SwitchStmt *SS = builder.getSwitch(); 14504d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek const Expr *CondExpr = SS->getCond()->IgnoreParenImpCasts(); 14514d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek if (CondExpr->getType()->getAs<EnumType>()) { 14524d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek if (SS->isAllEnumCasesCovered()) 14534d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek return; 14544d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek } 14554d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek 14564d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek builder.generateDefaultCaseNode(DefaultSt); 1457daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek} 1458daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek 1459e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek//===----------------------------------------------------------------------===// 1460ec96a2d52d16e150baaf629cd35e3fabff5d8915Ted Kremenek// Transfer functions: Loads and stores. 1461e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek//===----------------------------------------------------------------------===// 1462d27f8169f4b68337a489547a41ac45bf7a5d1ddfTed Kremenek 1463d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisvoid ExprEngine::VisitCommonDeclRefExpr(const Expr *Ex, const NamedDecl *D, 1464d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis ExplodedNode *Pred, 1465d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis ExplodedNodeSet &Dst) { 146666c486f275531df6362b3511fc3af6563561801bTed Kremenek StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx); 1467ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks 14688bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek ProgramStateRef state = Pred->getState(); 14695eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek const LocationContext *LCtx = Pred->getLocationContext(); 14706d69b5d82281992e981caa9bc038e3f6cac6594aZhongxing Xu 14719c378f705405d37f49795d5e915989de774fe11fTed Kremenek if (const VarDecl *VD = dyn_cast<VarDecl>(D)) { 1472591b5f53c0e11d87401b4804bb1be1a53f95c619Anna Zaks assert(Ex->isGLValue()); 1473d17da2b99f323fa91b01e1dd119cc32e0ee8197dTed Kremenek SVal V = state->getLValue(VD, Pred->getLocationContext()); 1474a7581731b1453b51b26154d2409d42a5b6395079Zhongxing Xu 1475892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek // For references, the 'lvalue' is the pointer address stored in the 1476892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek // reference region. 1477892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek if (VD->getType()->isReferenceType()) { 1478892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek if (const MemRegion *R = V.getAsRegion()) 1479892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek V = state->getSVal(R); 1480892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek else 1481892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek V = UnknownVal(); 1482852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek } 14836d69b5d82281992e981caa9bc038e3f6cac6594aZhongxing Xu 1484fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose Bldr.generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V), 0, 1485ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks ProgramPoint::PostLValueKind); 1486852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek return; 1487892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek } 14889c378f705405d37f49795d5e915989de774fe11fTed Kremenek if (const EnumConstantDecl *ED = dyn_cast<EnumConstantDecl>(D)) { 1489591b5f53c0e11d87401b4804bb1be1a53f95c619Anna Zaks assert(!Ex->isGLValue()); 1490c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek SVal V = svalBuilder.makeIntVal(ED->getInitVal()); 14915eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek Bldr.generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V)); 14926d69b5d82281992e981caa9bc038e3f6cac6594aZhongxing Xu return; 1493892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek } 14949c378f705405d37f49795d5e915989de774fe11fTed Kremenek if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 1495c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek SVal V = svalBuilder.getFunctionPointer(FD); 1496fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose Bldr.generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V), 0, 1497ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks ProgramPoint::PostLValueKind); 14986d69b5d82281992e981caa9bc038e3f6cac6594aZhongxing Xu return; 14991b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek } 15005aac0b6ae95f137b1783f3e6227241fb457b8f8bTed Kremenek if (isa<FieldDecl>(D)) { 1501fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose // FIXME: Compute lvalue of field pointers-to-member. 15020156439a3d718ea0ef5922c38d189a60829c8a86Jordan Rose // Right now we just use a non-null void pointer, so that it gives proper 15030156439a3d718ea0ef5922c38d189a60829c8a86Jordan Rose // results in boolean contexts. 15040156439a3d718ea0ef5922c38d189a60829c8a86Jordan Rose SVal V = svalBuilder.conjureSymbolVal(Ex, LCtx, getContext().VoidPtrTy, 15050156439a3d718ea0ef5922c38d189a60829c8a86Jordan Rose currBldrCtx->blockCount()); 15060156439a3d718ea0ef5922c38d189a60829c8a86Jordan Rose state = state->assume(cast<DefinedOrUnknownSVal>(V), true); 15070156439a3d718ea0ef5922c38d189a60829c8a86Jordan Rose Bldr.generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V), 0, 1508fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose ProgramPoint::PostLValueKind); 15095aac0b6ae95f137b1783f3e6227241fb457b8f8bTed Kremenek return; 15105aac0b6ae95f137b1783f3e6227241fb457b8f8bTed Kremenek } 15115aac0b6ae95f137b1783f3e6227241fb457b8f8bTed Kremenek 1512fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose llvm_unreachable("Support for this Decl not implemented."); 15133271f8d315712885ac87747369bb1d9f4b1ea81fTed Kremenek} 15143271f8d315712885ac87747369bb1d9f4b1ea81fTed Kremenek 1515540cbe2b60294fe7b926c26b4f1840f544fe3011Ted Kremenek/// VisitArraySubscriptExpr - Transfer function for array accesses 15169c378f705405d37f49795d5e915989de774fe11fTed Kremenekvoid ExprEngine::VisitLvalArraySubscriptExpr(const ArraySubscriptExpr *A, 15179c378f705405d37f49795d5e915989de774fe11fTed Kremenek ExplodedNode *Pred, 15189c378f705405d37f49795d5e915989de774fe11fTed Kremenek ExplodedNodeSet &Dst){ 15191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 15209c378f705405d37f49795d5e915989de774fe11fTed Kremenek const Expr *Base = A->getBase()->IgnoreParens(); 15219c378f705405d37f49795d5e915989de774fe11fTed Kremenek const Expr *Idx = A->getIdx()->IgnoreParens(); 1522892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek 15231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 15248f3407ef22bc7efe6ca4169381e09d0d657ec192Ted Kremenek ExplodedNodeSet checkerPreStmt; 15258f3407ef22bc7efe6ca4169381e09d0d657ec192Ted Kremenek getCheckerManager().runCheckersForPreStmt(checkerPreStmt, Pred, A, *this); 15268f3407ef22bc7efe6ca4169381e09d0d657ec192Ted Kremenek 152766c486f275531df6362b3511fc3af6563561801bTed Kremenek StmtNodeBuilder Bldr(checkerPreStmt, Dst, *currBldrCtx); 1528ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks 15298f3407ef22bc7efe6ca4169381e09d0d657ec192Ted Kremenek for (ExplodedNodeSet::iterator it = checkerPreStmt.begin(), 15308f3407ef22bc7efe6ca4169381e09d0d657ec192Ted Kremenek ei = checkerPreStmt.end(); it != ei; ++it) { 15315eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek const LocationContext *LCtx = (*it)->getLocationContext(); 15328bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek ProgramStateRef state = (*it)->getState(); 15335eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek SVal V = state->getLValue(A->getType(), 15345eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek state->getSVal(Idx, LCtx), 15355eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek state->getSVal(Base, LCtx)); 1536591b5f53c0e11d87401b4804bb1be1a53f95c619Anna Zaks assert(A->isGLValue()); 1537fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose Bldr.generateNode(A, *it, state->BindExpr(A, LCtx, V), 0, 1538fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose ProgramPoint::PostLValueKind); 15391b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek } 1540540cbe2b60294fe7b926c26b4f1840f544fe3011Ted Kremenek} 1541540cbe2b60294fe7b926c26b4f1840f544fe3011Ted Kremenek 1542469ecbded3616416ef938ed94a67f86149faf226Ted Kremenek/// VisitMemberExpr - Transfer function for member expressions. 15439c378f705405d37f49795d5e915989de774fe11fTed Kremenekvoid ExprEngine::VisitMemberExpr(const MemberExpr *M, ExplodedNode *Pred, 15446889679d72859960e0fc8d1080487f63c4df1e0aAnna Zaks ExplodedNodeSet &TopDst) { 15451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 154666c486f275531df6362b3511fc3af6563561801bTed Kremenek StmtNodeBuilder Bldr(Pred, TopDst, *currBldrCtx); 15476889679d72859960e0fc8d1080487f63c4df1e0aAnna Zaks ExplodedNodeSet Dst; 1548603513d2294c437b37bcf47f326b686e31bd9e84Jordan Rose ValueDecl *Member = M->getMemberDecl(); 154910f77ad7fc5e5cf3f37a9b14ff5843468b8b84d2Ted Kremenek 1550603513d2294c437b37bcf47f326b686e31bd9e84Jordan Rose // Handle static member variables and enum constants accessed via 1551603513d2294c437b37bcf47f326b686e31bd9e84Jordan Rose // member syntax. 1552603513d2294c437b37bcf47f326b686e31bd9e84Jordan Rose if (isa<VarDecl>(Member) || isa<EnumConstantDecl>(Member)) { 1553ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 1554603513d2294c437b37bcf47f326b686e31bd9e84Jordan Rose VisitCommonDeclRefExpr(M, Member, Pred, Dst); 1555ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 15565bd04952d4ae7ca894f583583208f0cec4735a90Ted Kremenek return; 15575bd04952d4ae7ca894f583583208f0cec4735a90Ted Kremenek } 155810f77ad7fc5e5cf3f37a9b14ff5843468b8b84d2Ted Kremenek 1559f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose ProgramStateRef state = Pred->getState(); 1560f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose const LocationContext *LCtx = Pred->getLocationContext(); 1561f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose Expr *BaseExpr = M->getBase(); 1562f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose 156310f77ad7fc5e5cf3f37a9b14ff5843468b8b84d2Ted Kremenek // Handle C++ method calls. 1564603513d2294c437b37bcf47f326b686e31bd9e84Jordan Rose if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(Member)) { 1565f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose if (MD->isInstance()) 1566f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose state = createTemporaryRegionIfNeeded(state, LCtx, BaseExpr); 156710f77ad7fc5e5cf3f37a9b14ff5843468b8b84d2Ted Kremenek 1568f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose SVal MDVal = svalBuilder.getFunctionPointer(MD); 1569f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose state = state->BindExpr(M, LCtx, MDVal); 157020aa40342bd74895128860c081aa84cd85bfa68dJordan Rose 1571f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose Bldr.generateNode(M, Pred, state); 1572ce6644bc1e921833f9b3c10cf7d4a0b78e8d5dc9Jordan Rose return; 157320aa40342bd74895128860c081aa84cd85bfa68dJordan Rose } 157420aa40342bd74895128860c081aa84cd85bfa68dJordan Rose 1575f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose // Handle regular struct fields / member variables. 1576f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose state = createTemporaryRegionIfNeeded(state, LCtx, BaseExpr); 1577f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose SVal baseExprVal = state->getSVal(BaseExpr, LCtx); 1578d27a368f4800b447b970b7c438d0fb4da00838dcJordan Rose 1579603513d2294c437b37bcf47f326b686e31bd9e84Jordan Rose FieldDecl *field = cast<FieldDecl>(Member); 1580e3939d7446959afb6b650fe08e952d0f64ab6794Ted Kremenek SVal L = state->getLValue(field, baseExprVal); 15816b4be2ef4ce49717ff972434975ce3c34c9a1c4cJordan Rose if (M->isGLValue()) { 15826b4be2ef4ce49717ff972434975ce3c34c9a1c4cJordan Rose if (field->getType()->isReferenceType()) { 1583d27a368f4800b447b970b7c438d0fb4da00838dcJordan Rose if (const MemRegion *R = L.getAsRegion()) 1584d27a368f4800b447b970b7c438d0fb4da00838dcJordan Rose L = state->getSVal(R); 1585d27a368f4800b447b970b7c438d0fb4da00838dcJordan Rose else 15866b4be2ef4ce49717ff972434975ce3c34c9a1c4cJordan Rose L = UnknownVal(); 15876b4be2ef4ce49717ff972434975ce3c34c9a1c4cJordan Rose } 15886b4be2ef4ce49717ff972434975ce3c34c9a1c4cJordan Rose 1589d27a368f4800b447b970b7c438d0fb4da00838dcJordan Rose Bldr.generateNode(M, Pred, state->BindExpr(M, LCtx, L), 0, 1590d27a368f4800b447b970b7c438d0fb4da00838dcJordan Rose ProgramPoint::PostLValueKind); 15916b4be2ef4ce49717ff972434975ce3c34c9a1c4cJordan Rose } else { 1592ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 1593bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek evalLoad(Dst, M, M, Pred, state, L); 1594ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 1595ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks } 1596469ecbded3616416ef938ed94a67f86149faf226Ted Kremenek} 1597469ecbded3616416ef938ed94a67f86149faf226Ted Kremenek 15989c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek/// evalBind - Handle the semantics of binding a value to a specific location. 15999c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek/// This method is used by evalStore and (soon) VisitDeclStmt, and others. 16009c378f705405d37f49795d5e915989de774fe11fTed Kremenekvoid ExprEngine::evalBind(ExplodedNodeSet &Dst, const Stmt *StoreE, 160193bd5ca766c4d7906878f4ffe76ce1b2080e540bJordy Rose ExplodedNode *Pred, 160232a549a64922af0903bdb777613ae7ae4490b70fTed Kremenek SVal location, SVal Val, 16033682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose bool atDeclInit, const ProgramPoint *PP) { 16043682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose 16053682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose const LocationContext *LC = Pred->getLocationContext(); 16063682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose PostStmt PS(StoreE, LC); 16073682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose if (!PP) 16083682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose PP = &PS; 1609b9bbd592c7ea72ada8d982e40a729beb9b53371eTed Kremenek 1610b107c4b7efb907d75620cd3c17f82fe27dc5b745Ted Kremenek // Do a previsit of the bind. 1611fe27971d54d26997149d6b84057f04ff398d1d5dJordy Rose ExplodedNodeSet CheckedSet; 1612fe27971d54d26997149d6b84057f04ff398d1d5dJordy Rose getCheckerManager().runCheckersForBind(CheckedSet, Pred, location, Val, 16133682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose StoreE, *this, *PP); 1614b9bbd592c7ea72ada8d982e40a729beb9b53371eTed Kremenek 161532a549a64922af0903bdb777613ae7ae4490b70fTed Kremenek // If the location is not a 'Loc', it will already be handled by 161632a549a64922af0903bdb777613ae7ae4490b70fTed Kremenek // the checkers. There is nothing left to do. 161732a549a64922af0903bdb777613ae7ae4490b70fTed Kremenek if (!isa<Loc>(location)) { 161832a549a64922af0903bdb777613ae7ae4490b70fTed Kremenek Dst = CheckedSet; 161932a549a64922af0903bdb777613ae7ae4490b70fTed Kremenek return; 162032a549a64922af0903bdb777613ae7ae4490b70fTed Kremenek } 162132a549a64922af0903bdb777613ae7ae4490b70fTed Kremenek 16226b6152ba96c164a292cc0b8d8b1d4cecbec27a60Anna Zaks ExplodedNodeSet TmpDst; 162366c486f275531df6362b3511fc3af6563561801bTed Kremenek StmtNodeBuilder Bldr(CheckedSet, TmpDst, *currBldrCtx); 16246b6152ba96c164a292cc0b8d8b1d4cecbec27a60Anna Zaks 1625b107c4b7efb907d75620cd3c17f82fe27dc5b745Ted Kremenek for (ExplodedNodeSet::iterator I = CheckedSet.begin(), E = CheckedSet.end(); 1626b107c4b7efb907d75620cd3c17f82fe27dc5b745Ted Kremenek I!=E; ++I) { 16273d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks ExplodedNode *PredI = *I; 16283d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks ProgramStateRef state = PredI->getState(); 162932a549a64922af0903bdb777613ae7ae4490b70fTed Kremenek 163032a549a64922af0903bdb777613ae7ae4490b70fTed Kremenek // When binding the value, pass on the hint that this is a initialization. 163132a549a64922af0903bdb777613ae7ae4490b70fTed Kremenek // For initializations, we do not need to inform clients of region 163232a549a64922af0903bdb777613ae7ae4490b70fTed Kremenek // changes. 163332a549a64922af0903bdb777613ae7ae4490b70fTed Kremenek state = state->bindLoc(cast<Loc>(location), 163432a549a64922af0903bdb777613ae7ae4490b70fTed Kremenek Val, /* notifyChanges = */ !atDeclInit); 163532a549a64922af0903bdb777613ae7ae4490b70fTed Kremenek 16363d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks const MemRegion *LocReg = 0; 163732a549a64922af0903bdb777613ae7ae4490b70fTed Kremenek if (loc::MemRegionVal *LocRegVal = dyn_cast<loc::MemRegionVal>(&location)) { 16383d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks LocReg = LocRegVal->getRegion(); 163932a549a64922af0903bdb777613ae7ae4490b70fTed Kremenek } 16403682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose 16413d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks const ProgramPoint L = PostStore(StoreE, LC, LocReg, 0); 1642fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose Bldr.generateNode(L, state, PredI); 1643b107c4b7efb907d75620cd3c17f82fe27dc5b745Ted Kremenek } 16446b6152ba96c164a292cc0b8d8b1d4cecbec27a60Anna Zaks Dst.insert(TmpDst); 1645a8538d902fce9cfec20f39b34492268b51643819Ted Kremenek} 1646a8538d902fce9cfec20f39b34492268b51643819Ted Kremenek 16479c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek/// evalStore - Handle the semantics of a store via an assignment. 1648a8538d902fce9cfec20f39b34492268b51643819Ted Kremenek/// @param Dst The node set to store generated state nodes 16492e6f5b823912ae76211427cb8684c9eaa6e53a1fJames Dennett/// @param AssignE The assignment expression if the store happens in an 1650e8a4d7d0064b357a30fe7ee4f2ddc02f9ffc0357Zhongxing Xu/// assignment. 16512e6f5b823912ae76211427cb8684c9eaa6e53a1fJames Dennett/// @param LocationE The location expression that is stored to. 1652a8538d902fce9cfec20f39b34492268b51643819Ted Kremenek/// @param state The current simulation state 1653a8538d902fce9cfec20f39b34492268b51643819Ted Kremenek/// @param location The location to store the value 1654a8538d902fce9cfec20f39b34492268b51643819Ted Kremenek/// @param Val The value to be stored 16559c378f705405d37f49795d5e915989de774fe11fTed Kremenekvoid ExprEngine::evalStore(ExplodedNodeSet &Dst, const Expr *AssignE, 16569c378f705405d37f49795d5e915989de774fe11fTed Kremenek const Expr *LocationE, 16579c378f705405d37f49795d5e915989de774fe11fTed Kremenek ExplodedNode *Pred, 16588bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek ProgramStateRef state, SVal location, SVal Val, 1659ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek const ProgramPointTag *tag) { 166014429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis // Proceed with the store. We use AssignE as the anchor for the PostStore 166114429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis // ProgramPoint if it is non-NULL, and LocationE otherwise. 166214429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis const Expr *StoreE = AssignE ? AssignE : LocationE; 166314429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis 16641b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek // Evaluate the location (checks for bad dereferences). 1665b4b817d704287836b52b34369009e682f208aa2bTed Kremenek ExplodedNodeSet Tmp; 1666bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek evalLocation(Tmp, AssignE, LocationE, Pred, state, location, tag, false); 16671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1668b4b817d704287836b52b34369009e682f208aa2bTed Kremenek if (Tmp.empty()) 16691b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek return; 1670b0533965f1b4db020692e3b23ca7b3bc15bf5897Ted Kremenek 167173c498a08f4968b6987d1453c7b77929dcc6d5f7Argyrios Kyrtzidis if (location.isUndef()) 167273c498a08f4968b6987d1453c7b77929dcc6d5f7Argyrios Kyrtzidis return; 1673a8538d902fce9cfec20f39b34492268b51643819Ted Kremenek 1674b4b817d704287836b52b34369009e682f208aa2bTed Kremenek for (ExplodedNodeSet::iterator NI=Tmp.begin(), NE=Tmp.end(); NI!=NE; ++NI) 16753d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks evalBind(Dst, StoreE, *NI, location, Val, false); 16761b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek} 16771b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek 1678bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenekvoid ExprEngine::evalLoad(ExplodedNodeSet &Dst, 1679bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek const Expr *NodeEx, 1680bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek const Expr *BoundEx, 1681bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek ExplodedNode *Pred, 1682bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek ProgramStateRef state, 1683bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek SVal location, 1684bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek const ProgramPointTag *tag, 1685bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek QualType LoadTy) 1686bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek{ 1687cca8ab155e8c20b98ba2d90eb2b1c228895e06fdZhanyong Wan assert(!isa<NonLoc>(location) && "location cannot be a NonLoc."); 168814429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis 16895b8c69494881b7d35bc6244b4a19be0cc2eab368Jordan Rose // Are we loading from a region? This actually results in two loads; one 1690852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek // to fetch the address of the referenced value and one to fetch the 1691852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek // referenced value. 16929697934650354bed2e509d8e7e44f21a1fb00f76Ted Kremenek if (const TypedValueRegion *TR = 16939697934650354bed2e509d8e7e44f21a1fb00f76Ted Kremenek dyn_cast_or_null<TypedValueRegion>(location.getAsRegion())) { 1694b9bbd592c7ea72ada8d982e40a729beb9b53371eTed Kremenek 1695018220c343c103b7dfaa117a7a474c7a7fd6d068Zhongxing Xu QualType ValTy = TR->getValueType(); 1696852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek if (const ReferenceType *RT = ValTy->getAs<ReferenceType>()) { 1697ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek static SimpleProgramPointTag 1698ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek loadReferenceTag("ExprEngine : Load Reference"); 1699852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek ExplodedNodeSet Tmp; 1700bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek evalLoadCommon(Tmp, NodeEx, BoundEx, Pred, state, 1701bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek location, &loadReferenceTag, 1702852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek getContext().getPointerType(RT->getPointeeType())); 1703852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek 1704852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek // Perform the load from the referenced value. 1705852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end() ; I!=E; ++I) { 1706db5e8cd095d1ffdd18f5620ad2348b5f386bebe3Anna Zaks state = (*I)->getState(); 1707bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek location = state->getSVal(BoundEx, (*I)->getLocationContext()); 1708bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek evalLoadCommon(Dst, NodeEx, BoundEx, *I, state, location, tag, LoadTy); 1709b9bbd592c7ea72ada8d982e40a729beb9b53371eTed Kremenek } 1710852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek return; 1711852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek } 1712852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek } 1713b9bbd592c7ea72ada8d982e40a729beb9b53371eTed Kremenek 1714bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek evalLoadCommon(Dst, NodeEx, BoundEx, Pred, state, location, tag, LoadTy); 1715852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek} 1716852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek 1717bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenekvoid ExprEngine::evalLoadCommon(ExplodedNodeSet &Dst, 1718bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek const Expr *NodeEx, 1719bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek const Expr *BoundEx, 1720bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek ExplodedNode *Pred, 1721bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek ProgramStateRef state, 1722bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek SVal location, 1723bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek const ProgramPointTag *tag, 1724bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek QualType LoadTy) { 1725bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek assert(NodeEx); 1726bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek assert(BoundEx); 17271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // Evaluate the location (checks for bad dereferences). 1728b4b817d704287836b52b34369009e682f208aa2bTed Kremenek ExplodedNodeSet Tmp; 1729bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek evalLocation(Tmp, NodeEx, BoundEx, Pred, state, location, tag, true); 1730b4b817d704287836b52b34369009e682f208aa2bTed Kremenek if (Tmp.empty()) 17311b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek return; 1732b9bbd592c7ea72ada8d982e40a729beb9b53371eTed Kremenek 173366c486f275531df6362b3511fc3af6563561801bTed Kremenek StmtNodeBuilder Bldr(Tmp, Dst, *currBldrCtx); 173473c498a08f4968b6987d1453c7b77929dcc6d5f7Argyrios Kyrtzidis if (location.isUndef()) 173573c498a08f4968b6987d1453c7b77929dcc6d5f7Argyrios Kyrtzidis return; 1736b9bbd592c7ea72ada8d982e40a729beb9b53371eTed Kremenek 17371b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek // Proceed with the load. 1738b4b817d704287836b52b34369009e682f208aa2bTed Kremenek for (ExplodedNodeSet::iterator NI=Tmp.begin(), NE=Tmp.end(); NI!=NE; ++NI) { 1739db5e8cd095d1ffdd18f5620ad2348b5f386bebe3Anna Zaks state = (*NI)->getState(); 17405eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek const LocationContext *LCtx = (*NI)->getLocationContext(); 174196ebad66c451d79c9f57b1edb31efaeeb23b9a01Ted Kremenek 17427affe151f5689b2d3547b8947c4099532c78a021Jordan Rose SVal V = UnknownVal(); 17437affe151f5689b2d3547b8947c4099532c78a021Jordan Rose if (location.isValid()) { 174496ebad66c451d79c9f57b1edb31efaeeb23b9a01Ted Kremenek if (LoadTy.isNull()) 1745bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek LoadTy = BoundEx->getType(); 17467affe151f5689b2d3547b8947c4099532c78a021Jordan Rose V = state->getSVal(cast<Loc>(location), LoadTy); 1747b4b817d704287836b52b34369009e682f208aa2bTed Kremenek } 17487affe151f5689b2d3547b8947c4099532c78a021Jordan Rose 17497affe151f5689b2d3547b8947c4099532c78a021Jordan Rose Bldr.generateNode(NodeEx, *NI, state->BindExpr(BoundEx, LCtx, V), tag, 17507affe151f5689b2d3547b8947c4099532c78a021Jordan Rose ProgramPoint::PostLoadKind); 1751d5b499d43c3526fae7f9ebb6e2d50e79d3496cedZhongxing Xu } 17521b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek} 17531b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek 1754bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenekvoid ExprEngine::evalLocation(ExplodedNodeSet &Dst, 1755bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek const Stmt *NodeEx, 1756bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek const Stmt *BoundEx, 1757bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek ExplodedNode *Pred, 1758bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek ProgramStateRef state, 1759bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek SVal location, 1760bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek const ProgramPointTag *tag, 1761bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek bool isLoad) { 176266c486f275531df6362b3511fc3af6563561801bTed Kremenek StmtNodeBuilder BldrTop(Pred, Dst, *currBldrCtx); 176300b1ad2d56f3e39f95c3f61bf511a531ab6a4fa5Zhongxing Xu // Early checks for performance reason. 1764769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis if (location.isUnknown()) { 1765b4b817d704287836b52b34369009e682f208aa2bTed Kremenek return; 1766b4b817d704287836b52b34369009e682f208aa2bTed Kremenek } 1767b9bbd592c7ea72ada8d982e40a729beb9b53371eTed Kremenek 17689c0d6891b3ec4b0d20b8a295946c0dc5426d147cArgyrios Kyrtzidis ExplodedNodeSet Src; 1769ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks BldrTop.takeNodes(Pred); 177066c486f275531df6362b3511fc3af6563561801bTed Kremenek StmtNodeBuilder Bldr(Pred, Src, *currBldrCtx); 1771ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks if (Pred->getState() != state) { 1772eb48bd1dd4168ab206a330bf523659170291a6a0Argyrios Kyrtzidis // Associate this new state with an ExplodedNode. 1773eb48bd1dd4168ab206a330bf523659170291a6a0Argyrios Kyrtzidis // FIXME: If I pass null tag, the graph is incorrect, e.g for 1774eb48bd1dd4168ab206a330bf523659170291a6a0Argyrios Kyrtzidis // int *p; 1775eb48bd1dd4168ab206a330bf523659170291a6a0Argyrios Kyrtzidis // p = 0; 1776eb48bd1dd4168ab206a330bf523659170291a6a0Argyrios Kyrtzidis // *p = 0xDEADBEEF; 1777eb48bd1dd4168ab206a330bf523659170291a6a0Argyrios Kyrtzidis // "p = 0" is not noted as "Null pointer value stored to 'p'" but 1778eb48bd1dd4168ab206a330bf523659170291a6a0Argyrios Kyrtzidis // instead "int *p" is noted as 1779eb48bd1dd4168ab206a330bf523659170291a6a0Argyrios Kyrtzidis // "Variable 'p' initialized to a null pointer value" 1780ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek 1781fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose static SimpleProgramPointTag tag("ExprEngine: Location"); 1782fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose Bldr.generateNode(NodeEx, Pred, state, &tag); 17830296c22557b3735e2ffeff690eb46fb0e9152bccTed Kremenek } 1784ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks ExplodedNodeSet Tmp; 1785bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek getCheckerManager().runCheckersForLocation(Tmp, Src, location, isLoad, 1786bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek NodeEx, BoundEx, *this); 1787ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks BldrTop.addNodes(Tmp); 1788ec96a2d52d16e150baaf629cd35e3fabff5d8915Ted Kremenek} 1789ec96a2d52d16e150baaf629cd35e3fabff5d8915Ted Kremenek 17906c7511db998817e64f2e124013e7d7c9a430c580Ted Kremenekstd::pair<const ProgramPointTag *, const ProgramPointTag*> 17910caa2d47b84337e942b3f6652adfafe4ae506cfeTed KremenekExprEngine::geteagerlyAssumeBinOpBifurcationTags() { 17926c7511db998817e64f2e124013e7d7c9a430c580Ted Kremenek static SimpleProgramPointTag 17930caa2d47b84337e942b3f6652adfafe4ae506cfeTed Kremenek eagerlyAssumeBinOpBifurcationTrue("ExprEngine : Eagerly Assume True"), 17940caa2d47b84337e942b3f6652adfafe4ae506cfeTed Kremenek eagerlyAssumeBinOpBifurcationFalse("ExprEngine : Eagerly Assume False"); 17950caa2d47b84337e942b3f6652adfafe4ae506cfeTed Kremenek return std::make_pair(&eagerlyAssumeBinOpBifurcationTrue, 17960caa2d47b84337e942b3f6652adfafe4ae506cfeTed Kremenek &eagerlyAssumeBinOpBifurcationFalse); 17976c7511db998817e64f2e124013e7d7c9a430c580Ted Kremenek} 17986c7511db998817e64f2e124013e7d7c9a430c580Ted Kremenek 17990caa2d47b84337e942b3f6652adfafe4ae506cfeTed Kremenekvoid ExprEngine::evalEagerlyAssumeBinOpBifurcation(ExplodedNodeSet &Dst, 18000caa2d47b84337e942b3f6652adfafe4ae506cfeTed Kremenek ExplodedNodeSet &Src, 18010caa2d47b84337e942b3f6652adfafe4ae506cfeTed Kremenek const Expr *Ex) { 180266c486f275531df6362b3511fc3af6563561801bTed Kremenek StmtNodeBuilder Bldr(Src, Dst, *currBldrCtx); 180386b39f20d5091ca3fdcbeb4a22766aaffdf6ac35Ted Kremenek 1804031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu for (ExplodedNodeSet::iterator I=Src.begin(), E=Src.end(); I!=E; ++I) { 1805031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu ExplodedNode *Pred = *I; 1806b293902c5cfa18365ffb0e00763849c9808a2ad1Ted Kremenek // Test if the previous node was as the same expression. This can happen 1807b293902c5cfa18365ffb0e00763849c9808a2ad1Ted Kremenek // when the expression fails to evaluate to anything meaningful and 1808b293902c5cfa18365ffb0e00763849c9808a2ad1Ted Kremenek // (as an optimization) we don't generate a node. 18091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump ProgramPoint P = Pred->getLocation(); 1810b293902c5cfa18365ffb0e00763849c9808a2ad1Ted Kremenek if (!isa<PostStmt>(P) || cast<PostStmt>(P).getStmt() != Ex) { 1811b293902c5cfa18365ffb0e00763849c9808a2ad1Ted Kremenek continue; 18121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 1813b293902c5cfa18365ffb0e00763849c9808a2ad1Ted Kremenek 18148bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek ProgramStateRef state = Pred->getState(); 18155eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek SVal V = state->getSVal(Ex, Pred->getLocationContext()); 18165344baa704f42b22d9df25c24ffbbf6b4716603bAnna Zaks nonloc::SymbolVal *SEV = dyn_cast<nonloc::SymbolVal>(&V); 18175344baa704f42b22d9df25c24ffbbf6b4716603bAnna Zaks if (SEV && SEV->isExpression()) { 18186c7511db998817e64f2e124013e7d7c9a430c580Ted Kremenek const std::pair<const ProgramPointTag *, const ProgramPointTag*> &tags = 18190caa2d47b84337e942b3f6652adfafe4ae506cfeTed Kremenek geteagerlyAssumeBinOpBifurcationTags(); 18206c7511db998817e64f2e124013e7d7c9a430c580Ted Kremenek 18216960d08b4ddf389d7c81504df7f16dc645120482Jordan Rose ProgramStateRef StateTrue, StateFalse; 18226960d08b4ddf389d7c81504df7f16dc645120482Jordan Rose tie(StateTrue, StateFalse) = state->assume(*SEV); 18236960d08b4ddf389d7c81504df7f16dc645120482Jordan Rose 182448af2a9c1ed3259512f2d1431720add1fbe8fb5fTed Kremenek // First assume that the condition is true. 18256960d08b4ddf389d7c81504df7f16dc645120482Jordan Rose if (StateTrue) { 182686b39f20d5091ca3fdcbeb4a22766aaffdf6ac35Ted Kremenek SVal Val = svalBuilder.makeIntVal(1U, Ex->getType()); 18275eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek StateTrue = StateTrue->BindExpr(Ex, Pred->getLocationContext(), Val); 1828fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose Bldr.generateNode(Ex, Pred, StateTrue, tags.first); 182948af2a9c1ed3259512f2d1431720add1fbe8fb5fTed Kremenek } 18301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 183148af2a9c1ed3259512f2d1431720add1fbe8fb5fTed Kremenek // Next, assume that the condition is false. 18326960d08b4ddf389d7c81504df7f16dc645120482Jordan Rose if (StateFalse) { 183386b39f20d5091ca3fdcbeb4a22766aaffdf6ac35Ted Kremenek SVal Val = svalBuilder.makeIntVal(0U, Ex->getType()); 18345eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek StateFalse = StateFalse->BindExpr(Ex, Pred->getLocationContext(), Val); 1835fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose Bldr.generateNode(Ex, Pred, StateFalse, tags.second); 183648af2a9c1ed3259512f2d1431720add1fbe8fb5fTed Kremenek } 183748af2a9c1ed3259512f2d1431720add1fbe8fb5fTed Kremenek } 183848af2a9c1ed3259512f2d1431720add1fbe8fb5fTed Kremenek } 183948af2a9c1ed3259512f2d1431720add1fbe8fb5fTed Kremenek} 184048af2a9c1ed3259512f2d1431720add1fbe8fb5fTed Kremenek 1841df5faf5e7ae6823d0af0b801c4ac26d47f2cee97Chad Rosiervoid ExprEngine::VisitGCCAsmStmt(const GCCAsmStmt *A, ExplodedNode *Pred, 1842df5faf5e7ae6823d0af0b801c4ac26d47f2cee97Chad Rosier ExplodedNodeSet &Dst) { 184366c486f275531df6362b3511fc3af6563561801bTed Kremenek StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx); 1844a81d3d434e6581ff354eaf5b2a3c25c75771a792Erik Verbruggen // We have processed both the inputs and the outputs. All of the outputs 1845a81d3d434e6581ff354eaf5b2a3c25c75771a792Erik Verbruggen // should evaluate to Locs. Nuke all of their values. 18461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1847a81d3d434e6581ff354eaf5b2a3c25c75771a792Erik Verbruggen // FIXME: Some day in the future it would be nice to allow a "plug-in" 1848a81d3d434e6581ff354eaf5b2a3c25c75771a792Erik Verbruggen // which interprets the inline asm and stores proper results in the 1849a81d3d434e6581ff354eaf5b2a3c25c75771a792Erik Verbruggen // outputs. 18501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1851a81d3d434e6581ff354eaf5b2a3c25c75771a792Erik Verbruggen ProgramStateRef state = Pred->getState(); 18521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1853df5faf5e7ae6823d0af0b801c4ac26d47f2cee97Chad Rosier for (GCCAsmStmt::const_outputs_iterator OI = A->begin_outputs(), 1854a81d3d434e6581ff354eaf5b2a3c25c75771a792Erik Verbruggen OE = A->end_outputs(); OI != OE; ++OI) { 1855a81d3d434e6581ff354eaf5b2a3c25c75771a792Erik Verbruggen SVal X = state->getSVal(*OI, Pred->getLocationContext()); 1856a81d3d434e6581ff354eaf5b2a3c25c75771a792Erik Verbruggen assert (!isa<NonLoc>(X)); // Should be an Lval, or unknown, undef. 18571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1858a81d3d434e6581ff354eaf5b2a3c25c75771a792Erik Verbruggen if (isa<Loc>(X)) 1859a81d3d434e6581ff354eaf5b2a3c25c75771a792Erik Verbruggen state = state->bindLoc(cast<Loc>(X), UnknownVal()); 1860ef44bfb9d0f15ba0391f8346c9f01355fb450a09Ted Kremenek } 18611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1862a81d3d434e6581ff354eaf5b2a3c25c75771a792Erik Verbruggen Bldr.generateNode(A, Pred, state); 1863ef44bfb9d0f15ba0391f8346c9f01355fb450a09Ted Kremenek} 1864ef44bfb9d0f15ba0391f8346c9f01355fb450a09Ted Kremenek 18658cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosiervoid ExprEngine::VisitMSAsmStmt(const MSAsmStmt *A, ExplodedNode *Pred, 18668cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier ExplodedNodeSet &Dst) { 186766c486f275531df6362b3511fc3af6563561801bTed Kremenek StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx); 18688cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier Bldr.generateNode(A, Pred, Pred->getState()); 18698cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier} 18708cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier 1871094bef56a7900f13bb777f9a352704104b1458e7Ted Kremenek//===----------------------------------------------------------------------===// 1872e01c98767dfd7153c3c84637c36659e3bbe16ff7Ted Kremenek// Visualization. 1873ee98546b0d5f3439c4a590b0d7d1545af794a0ecTed Kremenek//===----------------------------------------------------------------------===// 1874ee98546b0d5f3439c4a590b0d7d1545af794a0ecTed Kremenek 1875aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek#ifndef NDEBUG 1876d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisstatic ExprEngine* GraphPrintCheckerState; 1877e97ca065c91ff9ca2a2a42eb443eaa553c40441cTed Kremenekstatic SourceManager* GraphPrintSourceManager; 18783b4f6702860208692f6ef28401e68de4e3ff9af9Ted Kremenek 1879aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremeneknamespace llvm { 1880aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenektemplate<> 188147491f8b7adf9d42a404d44c073e8a5308fa6cfcDouglas Gregorstruct DOTGraphTraits<ExplodedNode*> : 1882aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek public DefaultDOTGraphTraits { 1883006b0eb3e11162d8c06372db813ac9f71a7a16e8Tobias Grosser 1884006b0eb3e11162d8c06372db813ac9f71a7a16e8Tobias Grosser DOTGraphTraits (bool isSimple=false) : DefaultDOTGraphTraits(isSimple) {} 1885006b0eb3e11162d8c06372db813ac9f71a7a16e8Tobias Grosser 1886d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis // FIXME: Since we do not cache error nodes in ExprEngine now, this does not 1887ec9227fea66c3439991fc84b0d33b0a8b4b8875eZhongxing Xu // work. 18889c378f705405d37f49795d5e915989de774fe11fTed Kremenek static std::string getNodeAttributes(const ExplodedNode *N, void*) { 18891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 189010f51e8785e43d5a22acc2d2a638307c582949c2Ted Kremenek#if 0 189110f51e8785e43d5a22acc2d2a638307c582949c2Ted Kremenek // FIXME: Replace with a general scheme to tell if the node is 189210f51e8785e43d5a22acc2d2a638307c582949c2Ted Kremenek // an error node. 1893a3fadfcce5911742801a302cac82d4fe54d5c682Ted Kremenek if (GraphPrintCheckerState->isImplicitNullDeref(N) || 18949dca062461a6244cf0f733346657fa3eee853f9bTed Kremenek GraphPrintCheckerState->isExplicitNullDeref(N) || 18954a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek GraphPrintCheckerState->isUndefDeref(N) || 18964a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek GraphPrintCheckerState->isUndefStore(N) || 18974a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek GraphPrintCheckerState->isUndefControlFlow(N) || 18985e03fcb5420c33207433dd6f800588e256dd9bdbTed Kremenek GraphPrintCheckerState->isUndefResult(N) || 18992ded35a576e3899553ea0ccfcbf5cbdb3d8cf664Ted Kremenek GraphPrintCheckerState->isBadCall(N) || 19002ded35a576e3899553ea0ccfcbf5cbdb3d8cf664Ted Kremenek GraphPrintCheckerState->isUndefArg(N)) 1901a3fadfcce5911742801a302cac82d4fe54d5c682Ted Kremenek return "color=\"red\",style=\"filled\""; 19021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 19038cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek if (GraphPrintCheckerState->isNoReturnCall(N)) 19048cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek return "color=\"blue\",style=\"filled\""; 19052055effed54d614b51e3501a174c9b1fe92e4de4Zhongxing Xu#endif 1906a3fadfcce5911742801a302cac82d4fe54d5c682Ted Kremenek return ""; 1907a3fadfcce5911742801a302cac82d4fe54d5c682Ted Kremenek } 19081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 190928038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose static void printLocation(llvm::raw_ostream &Out, SourceLocation SLoc) { 191028038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose if (SLoc.isFileID()) { 191128038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose Out << "\\lline=" 191228038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose << GraphPrintSourceManager->getExpansionLineNumber(SLoc) 191328038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose << " col=" 191428038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose << GraphPrintSourceManager->getExpansionColumnNumber(SLoc) 191528038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose << "\\l"; 191628038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose } 191728038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose } 191828038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose 19199c378f705405d37f49795d5e915989de774fe11fTed Kremenek static std::string getNodeLabel(const ExplodedNode *N, void*){ 19201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 192153ba0b636194dbeaa65a6f85316c9397a0c5298bTed Kremenek std::string sbuf; 192253ba0b636194dbeaa65a6f85316c9397a0c5298bTed Kremenek llvm::raw_string_ostream Out(sbuf); 1923803c9edd06e8f936821525d36b1d8cc131e37d44Ted Kremenek 1924803c9edd06e8f936821525d36b1d8cc131e37d44Ted Kremenek // Program Location. 1925aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek ProgramPoint Loc = N->getLocation(); 19261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1927aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek switch (Loc.getKind()) { 19280b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks case ProgramPoint::BlockEntranceKind: { 19291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Out << "Block Entrance: B" 1930aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek << cast<BlockEntrance>(Loc).getBlock()->getBlockID(); 19310b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks if (const NamedDecl *ND = 19320b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks dyn_cast<NamedDecl>(Loc.getLocationContext()->getDecl())) { 19330b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks Out << " ("; 19340b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks ND->printName(Out); 19350b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks Out << ")"; 19360b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks } 1937aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek break; 19380b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks } 19391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1940aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek case ProgramPoint::BlockExitKind: 1941aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek assert (false); 1942aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek break; 19431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1944102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor case ProgramPoint::CallEnterKind: 1945102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor Out << "CallEnter"; 1946102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor break; 1947102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor 19480b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks case ProgramPoint::CallExitBeginKind: 19490b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks Out << "CallExitBegin"; 19500b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks break; 19510b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks 19520b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks case ProgramPoint::CallExitEndKind: 19530b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks Out << "CallExitEnd"; 19540b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks break; 19550b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks 19560b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks case ProgramPoint::PostStmtPurgeDeadSymbolsKind: 19570b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks Out << "PostStmtPurgeDeadSymbols"; 19580b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks break; 19590b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks 19600b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks case ProgramPoint::PreStmtPurgeDeadSymbolsKind: 19610b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks Out << "PreStmtPurgeDeadSymbols"; 1962102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor break; 1963102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor 19645903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks case ProgramPoint::EpsilonKind: 19655903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks Out << "Epsilon Point"; 19665903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks break; 19675903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks 196828038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose case ProgramPoint::PreImplicitCallKind: { 196928038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose ImplicitCallPoint *PC = cast<ImplicitCallPoint>(&Loc); 197028038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose Out << "PreCall: "; 197128038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose 197228038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose // FIXME: Get proper printing options. 197328038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose PC->getDecl()->print(Out, LangOptions()); 197428038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose printLocation(Out, PC->getLocation()); 197528038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose break; 197628038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose } 197728038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose 197828038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose case ProgramPoint::PostImplicitCallKind: { 197928038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose ImplicitCallPoint *PC = cast<ImplicitCallPoint>(&Loc); 198028038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose Out << "PostCall: "; 198128038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose 198228038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose // FIXME: Get proper printing options. 198328038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose PC->getDecl()->print(Out, LangOptions()); 198428038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose printLocation(Out, PC->getLocation()); 198528038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose break; 198628038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose } 198728038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose 1988aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek default: { 19895f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek if (StmtPoint *L = dyn_cast<StmtPoint>(&Loc)) { 19909c378f705405d37f49795d5e915989de774fe11fTed Kremenek const Stmt *S = L->getStmt(); 19918c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek 199231ba6135375433b617a8587ea6cc836a014ebd86Roman Divacky Out << S->getStmtClassName() << ' ' << (const void*) S << ' '; 1993e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner LangOptions LO; // FIXME. 1994e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner S->printPretty(Out, 0, PrintingPolicy(LO)); 199528038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose printLocation(Out, S->getLocStart()); 19961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 19975f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek if (isa<PreStmt>(Loc)) 19981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Out << "\\lPreStmt\\l;"; 19995f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek else if (isa<PostLoad>(Loc)) 20007090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek Out << "\\lPostLoad\\l;"; 20017090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek else if (isa<PostStore>(Loc)) 20027090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek Out << "\\lPostStore\\l"; 20037090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek else if (isa<PostLValue>(Loc)) 20047090d5465de7ca620da16211cf886edf1edc1f1fTed Kremenek Out << "\\lPostLValue\\l"; 20051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 200610f51e8785e43d5a22acc2d2a638307c582949c2Ted Kremenek#if 0 200710f51e8785e43d5a22acc2d2a638307c582949c2Ted Kremenek // FIXME: Replace with a general scheme to determine 200810f51e8785e43d5a22acc2d2a638307c582949c2Ted Kremenek // the name of the check. 20098c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek if (GraphPrintCheckerState->isImplicitNullDeref(N)) 20108c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek Out << "\\|Implicit-Null Dereference.\\l"; 20118c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek else if (GraphPrintCheckerState->isExplicitNullDeref(N)) 20128c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek Out << "\\|Explicit-Null Dereference.\\l"; 20138c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek else if (GraphPrintCheckerState->isUndefDeref(N)) 20148c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek Out << "\\|Dereference of undefialied value.\\l"; 20158c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek else if (GraphPrintCheckerState->isUndefStore(N)) 20168c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek Out << "\\|Store to Undefined Loc."; 20178c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek else if (GraphPrintCheckerState->isUndefResult(N)) 20188c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek Out << "\\|Result of operation is undefined."; 20198c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek else if (GraphPrintCheckerState->isNoReturnCall(N)) 20208c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek Out << "\\|Call to function marked \"noreturn\"."; 20218c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek else if (GraphPrintCheckerState->isBadCall(N)) 20228c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek Out << "\\|Call to NULL/Undefined."; 20238c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek else if (GraphPrintCheckerState->isUndefArg(N)) 20248c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek Out << "\\|Argument in call is undefined"; 202510f51e8785e43d5a22acc2d2a638307c582949c2Ted Kremenek#endif 20261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 20278c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek break; 20288c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek } 20298c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek 20309c378f705405d37f49795d5e915989de774fe11fTed Kremenek const BlockEdge &E = cast<BlockEdge>(Loc); 2031aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek Out << "Edge: (B" << E.getSrc()->getBlockID() << ", B" 2032aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek << E.getDst()->getBlockID() << ')'; 20331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 20349c378f705405d37f49795d5e915989de774fe11fTed Kremenek if (const Stmt *T = E.getSrc()->getTerminator()) { 20351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2036e97ca065c91ff9ca2a2a42eb443eaa553c40441cTed Kremenek SourceLocation SLoc = T->getLocStart(); 20371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2038b38911f16b4943548db6a3695fc6ae23070b25d2Ted Kremenek Out << "\\|Terminator: "; 2039e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner LangOptions LO; // FIXME. 2040e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner E.getSrc()->printTerminator(Out, LO); 20411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 20429b5551d7f0209cec8b9c555cf70e893940674e5cTed Kremenek if (SLoc.isFileID()) { 20439b5551d7f0209cec8b9c555cf70e893940674e5cTed Kremenek Out << "\\lline=" 2044642116259e8df6286063a17361c20e95b5017a0aChandler Carruth << GraphPrintSourceManager->getExpansionLineNumber(SLoc) 20457da5aea7669e6db3e593162b8a123aef06a04d07Chris Lattner << " col=" 2046a77c031cb66f75d22672070052cc6e0205289ff8Chandler Carruth << GraphPrintSourceManager->getExpansionColumnNumber(SLoc); 20479b5551d7f0209cec8b9c555cf70e893940674e5cTed Kremenek } 20481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2049daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek if (isa<SwitchStmt>(T)) { 20509c378f705405d37f49795d5e915989de774fe11fTed Kremenek const Stmt *Label = E.getDst()->getLabel(); 20511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 20521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (Label) { 20539c378f705405d37f49795d5e915989de774fe11fTed Kremenek if (const CaseStmt *C = dyn_cast<CaseStmt>(Label)) { 2054daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek Out << "\\lcase "; 2055e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner LangOptions LO; // FIXME. 2056e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner C->getLHS()->printPretty(Out, 0, PrintingPolicy(LO)); 20571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 20589c378f705405d37f49795d5e915989de774fe11fTed Kremenek if (const Stmt *RHS = C->getRHS()) { 2059daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek Out << " .. "; 2060e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner RHS->printPretty(Out, 0, PrintingPolicy(LO)); 2061daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek } 20621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2063daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek Out << ":"; 2064daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek } 2065daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek else { 2066daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek assert (isa<DefaultStmt>(Label)); 2067daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek Out << "\\ldefault:"; 2068daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek } 2069daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek } 20701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump else 2071daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek Out << "\\l(implicit) default:"; 2072daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek } 2073daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek else if (isa<IndirectGotoStmt>(T)) { 2074b38911f16b4943548db6a3695fc6ae23070b25d2Ted Kremenek // FIXME 2075b38911f16b4943548db6a3695fc6ae23070b25d2Ted Kremenek } 2076b38911f16b4943548db6a3695fc6ae23070b25d2Ted Kremenek else { 2077b38911f16b4943548db6a3695fc6ae23070b25d2Ted Kremenek Out << "\\lCondition: "; 2078b38911f16b4943548db6a3695fc6ae23070b25d2Ted Kremenek if (*E.getSrc()->succ_begin() == E.getDst()) 2079b38911f16b4943548db6a3695fc6ae23070b25d2Ted Kremenek Out << "true"; 2080b38911f16b4943548db6a3695fc6ae23070b25d2Ted Kremenek else 20811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Out << "false"; 2082b38911f16b4943548db6a3695fc6ae23070b25d2Ted Kremenek } 20831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2084b38911f16b4943548db6a3695fc6ae23070b25d2Ted Kremenek Out << "\\l"; 2085b38911f16b4943548db6a3695fc6ae23070b25d2Ted Kremenek } 20861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 208710f51e8785e43d5a22acc2d2a638307c582949c2Ted Kremenek#if 0 208810f51e8785e43d5a22acc2d2a638307c582949c2Ted Kremenek // FIXME: Replace with a general scheme to determine 208910f51e8785e43d5a22acc2d2a638307c582949c2Ted Kremenek // the name of the check. 20904a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek if (GraphPrintCheckerState->isUndefControlFlow(N)) { 20914a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek Out << "\\|Control-flow based on\\lUndefined value.\\l"; 20923b4f6702860208692f6ef28401e68de4e3ff9af9Ted Kremenek } 209310f51e8785e43d5a22acc2d2a638307c582949c2Ted Kremenek#endif 2094aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek } 2095aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek } 20961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 20978bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek ProgramStateRef state = N->getState(); 209831ba6135375433b617a8587ea6cc836a014ebd86Roman Divacky Out << "\\|StateID: " << (const void*) state.getPtr() 209931ba6135375433b617a8587ea6cc836a014ebd86Roman Divacky << " NodeID: " << (const void*) N << "\\|"; 21005eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek state->printDOT(Out); 2101ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek 2102ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek Out << "\\l"; 2103ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek 2104ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek if (const ProgramPointTag *tag = Loc.getTag()) { 2105ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek Out << "\\|Tag: " << tag->getTagDescription(); 2106ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek Out << "\\l"; 2107ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek } 2108aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek return Out.str(); 2109aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek } 2110aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek}; 21111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump} // end llvm namespace 2112aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek#endif 2113aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek 2114ffe0f43806d4823271c2406c1fccc2373115c36aTed Kremenek#ifndef NDEBUG 21157ec07fd91f6eae8bd619ebb8512805222ca41c92Ted Kremenektemplate <typename ITERATOR> 21169c378f705405d37f49795d5e915989de774fe11fTed KremenekExplodedNode *GetGraphNode(ITERATOR I) { return *I; } 21177ec07fd91f6eae8bd619ebb8512805222ca41c92Ted Kremenek 2118031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xutemplate <> ExplodedNode* 2119031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing XuGetGraphNode<llvm::DenseMap<ExplodedNode*, Expr*>::iterator> 2120031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu (llvm::DenseMap<ExplodedNode*, Expr*>::iterator I) { 21217ec07fd91f6eae8bd619ebb8512805222ca41c92Ted Kremenek return I->first; 21227ec07fd91f6eae8bd619ebb8512805222ca41c92Ted Kremenek} 2123ffe0f43806d4823271c2406c1fccc2373115c36aTed Kremenek#endif 2124ffe0f43806d4823271c2406c1fccc2373115c36aTed Kremenek 2125d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisvoid ExprEngine::ViewGraph(bool trim) { 21261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump#ifndef NDEBUG 2127ffe0f43806d4823271c2406c1fccc2373115c36aTed Kremenek if (trim) { 2128031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu std::vector<ExplodedNode*> Src; 2129940abcc574580e454689be801f38a3d4d41ab01fTed Kremenek 2130940abcc574580e454689be801f38a3d4d41ab01fTed Kremenek // Flush any outstanding reports to make sure we cover all the nodes. 2131940abcc574580e454689be801f38a3d4d41ab01fTed Kremenek // This does not cause them to get displayed. 2132940abcc574580e454689be801f38a3d4d41ab01fTed Kremenek for (BugReporter::iterator I=BR.begin(), E=BR.end(); I!=E; ++I) 2133940abcc574580e454689be801f38a3d4d41ab01fTed Kremenek const_cast<BugType*>(*I)->FlushReports(BR); 2134940abcc574580e454689be801f38a3d4d41ab01fTed Kremenek 2135940abcc574580e454689be801f38a3d4d41ab01fTed Kremenek // Iterate through the reports and get their nodes. 2136404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis for (BugReporter::EQClasses_iterator 2137404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis EI = BR.EQClasses_begin(), EE = BR.EQClasses_end(); EI != EE; ++EI) { 21384a5f724538cbc275370c9504e8169ce92503256cBenjamin Kramer ExplodedNode *N = const_cast<ExplodedNode*>(EI->begin()->getErrorNode()); 2139404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis if (N) Src.push_back(N); 2140940abcc574580e454689be801f38a3d4d41ab01fTed Kremenek } 21411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 21427ec07fd91f6eae8bd619ebb8512805222ca41c92Ted Kremenek ViewGraph(&Src[0], &Src[0]+Src.size()); 2143ffe0f43806d4823271c2406c1fccc2373115c36aTed Kremenek } 2144493d7a26d5ea319770ba904b43f2740d43b820cbTed Kremenek else { 2145493d7a26d5ea319770ba904b43f2740d43b820cbTed Kremenek GraphPrintCheckerState = this; 2146493d7a26d5ea319770ba904b43f2740d43b820cbTed Kremenek GraphPrintSourceManager = &getContext().getSourceManager(); 2147ae6814efb6c41bd0c0f6413d25097105284d5be7Ted Kremenek 2148d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis llvm::ViewGraph(*G.roots_begin(), "ExprEngine"); 21491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2150493d7a26d5ea319770ba904b43f2740d43b820cbTed Kremenek GraphPrintCheckerState = NULL; 2151493d7a26d5ea319770ba904b43f2740d43b820cbTed Kremenek GraphPrintSourceManager = NULL; 2152493d7a26d5ea319770ba904b43f2740d43b820cbTed Kremenek } 2153493d7a26d5ea319770ba904b43f2740d43b820cbTed Kremenek#endif 2154493d7a26d5ea319770ba904b43f2740d43b820cbTed Kremenek} 2155493d7a26d5ea319770ba904b43f2740d43b820cbTed Kremenek 2156d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisvoid ExprEngine::ViewGraph(ExplodedNode** Beg, ExplodedNode** End) { 2157493d7a26d5ea319770ba904b43f2740d43b820cbTed Kremenek#ifndef NDEBUG 2158493d7a26d5ea319770ba904b43f2740d43b820cbTed Kremenek GraphPrintCheckerState = this; 2159493d7a26d5ea319770ba904b43f2740d43b820cbTed Kremenek GraphPrintSourceManager = &getContext().getSourceManager(); 21601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2161031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu std::auto_ptr<ExplodedGraph> TrimmedG(G.Trim(Beg, End).first); 2162493d7a26d5ea319770ba904b43f2740d43b820cbTed Kremenek 2163cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek if (!TrimmedG.get()) 21646cb7c1a43b0c8f739d1f54b7fdae5ede86033496Benjamin Kramer llvm::errs() << "warning: Trimmed ExplodedGraph is empty.\n"; 2165cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek else 2166d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis llvm::ViewGraph(*TrimmedG->roots_begin(), "TrimmedExprEngine"); 21671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 21683b4f6702860208692f6ef28401e68de4e3ff9af9Ted Kremenek GraphPrintCheckerState = NULL; 2169e97ca065c91ff9ca2a2a42eb443eaa553c40441cTed Kremenek GraphPrintSourceManager = NULL; 2170e01c98767dfd7153c3c84637c36659e3bbe16ff7Ted Kremenek#endif 2171ee98546b0d5f3439c4a590b0d7d1545af794a0ecTed Kremenek} 2172