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 169b663716449b618ba0390b1dbebc54fa8e971124Ted Kremenek#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h" 17ac7cc2d37e82181e73fcc265c1d0a619d18b7605Jordan Rose#include "PrettyStackTraceLocationContext.h" 18199c3d6cd16aebbb9c7f0d42af9d922c9628bf70Ken Dyck#include "clang/AST/CharUnits.h" 1916f0049415ec596504891259e2a83e19871c0d52Chris Lattner#include "clang/AST/ParentMap.h" 20337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek#include "clang/AST/StmtCXX.h" 2155fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/AST/StmtObjC.h" 221b63e4f732dbc73d90abf886b4d21f8e3a165f6dChris Lattner#include "clang/Basic/Builtins.h" 230bed8a12f2878d3cd94fb8bdba55b593d92dd11aTed Kremenek#include "clang/Basic/PrettyStackTrace.h" 2455fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Basic/SourceManager.h" 2555fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" 2655fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/StaticAnalyzer/Core/CheckerManager.h" 2755fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h" 2855fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" 29a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar#include "clang/StaticAnalyzer/Core/PathSensitive/LoopWidening.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 426bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#define DEBUG_TYPE "ExprEngine" 436bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 44c2994283aa7538b7420c8e398cde7afa328d7042Anna ZaksSTATISTIC(NumRemoveDeadBindings, 45c2994283aa7538b7420c8e398cde7afa328d7042Anna Zaks "The # of times RemoveDeadBindings is called"); 46749bbe6f5f23676244f12a0d41511c8e73516febAnna ZaksSTATISTIC(NumMaxBlockCountReached, 47749bbe6f5f23676244f12a0d41511c8e73516febAnna Zaks "The # of aborted paths due to reaching the maximum block count in " 48749bbe6f5f23676244f12a0d41511c8e73516febAnna Zaks "a top level function"); 49749bbe6f5f23676244f12a0d41511c8e73516febAnna ZaksSTATISTIC(NumMaxBlockCountReachedInInlined, 50749bbe6f5f23676244f12a0d41511c8e73516febAnna Zaks "The # of aborted paths due to reaching the maximum block count in " 51749bbe6f5f23676244f12a0d41511c8e73516febAnna Zaks "an inlined function"); 525903a373db3d27794c90b25687e0dd6adb0e497dAnna ZaksSTATISTIC(NumTimesRetriedWithoutInlining, 535903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks "The # of times we re-evaluated a call without inlining"); 545903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks 55176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinestypedef std::pair<const CXXBindTemporaryExpr *, const StackFrameContext *> 56176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CXXBindTemporaryContext; 57176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 58176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// Keeps track of whether CXXBindTemporaryExpr nodes have been evaluated. 59176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// The StackFrameContext assures that nested calls due to inlined recursive 60176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// functions do not interfere. 61176edba5311f6eff0cad2631449885ddf4fbc9eaStephen HinesREGISTER_TRAIT_WITH_PROGRAMSTATE(InitializedTemporariesSet, 62176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::ImmutableSet<CXXBindTemporaryContext>) 63176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 64e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek//===----------------------------------------------------------------------===// 65bdb435ddaafd5069becd543d638112f68825b89dTed Kremenek// Engine construction and deletion. 66bdb435ddaafd5069becd543d638112f68825b89dTed Kremenek//===----------------------------------------------------------------------===// 67bdb435ddaafd5069becd543d638112f68825b89dTed Kremenek 68651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstatic const char* TagProviderName = "ExprEngine"; 69651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 703fd5f370a28552976c52e76c3035d79012d78ddaAnna ZaksExprEngine::ExprEngine(AnalysisManager &mgr, bool gcEnabled, 71fbcb3f11fc90e9f00e6074e9b118b8dc11ca604cAnna Zaks SetOfConstDecls *VisitedCalleesIn, 7275f31c4862643ab09479c979fabf754e7ffe1460Anna Zaks FunctionSummariesTy *FS, 7375f31c4862643ab09479c979fabf754e7ffe1460Anna Zaks InliningModes HowToInlineIn) 7425e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu : AMgr(mgr), 751d26f48dc2eea1c07431ca1519d7034a21b9bcffTed Kremenek AnalysisDeclContexts(mgr.getAnalysisDeclContextManager()), 76fbcb3f11fc90e9f00e6074e9b118b8dc11ca604cAnna Zaks Engine(*this, FS), 77d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis G(Engine.getGraph()), 78c77a55126fcad66fb086f8e100a494caa2496a2dZhongxing Xu StateMgr(getContext(), mgr.getStoreManagerCreator(), 7932a58084a4c53e6938dd81bfce224db25a5976d1Ted Kremenek mgr.getConstraintManagerCreator(), G.getAllocator(), 80ca5d78d0bc3010164f2f9682967d64d7e305a167Jordan Rose this), 8150a6d0ce344c02782e0207574005c3b2aaa5077cTed Kremenek SymMgr(StateMgr.getSymbolManager()), 82c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek svalBuilder(StateMgr.getSValBuilder()), 836bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines currStmtIdx(0), currBldrCtx(nullptr), 844ef19205b6912316296db74a9073ad6fa60e4ccaTed Kremenek ObjCNoRet(mgr.getASTContext()), 85fbcb3f11fc90e9f00e6074e9b118b8dc11ca604cAnna Zaks ObjCGCEnabled(gcEnabled), BR(mgr, *this), 8675f31c4862643ab09479c979fabf754e7ffe1460Anna Zaks VisitedCallees(VisitedCalleesIn), 8775f31c4862643ab09479c979fabf754e7ffe1460Anna Zaks HowToInline(HowToInlineIn) 88255d4d4226b24036ceb11228fbb74286e58620f7Ted Kremenek{ 894d9e497a2b1eab3b1214848216050c64fc3acfd6Jordan Rose unsigned TrimInterval = mgr.options.getGraphTrimInterval(); 904d9e497a2b1eab3b1214848216050c64fc3acfd6Jordan Rose if (TrimInterval != 0) { 914d9e497a2b1eab3b1214848216050c64fc3acfd6Jordan Rose // Enable eager node reclaimation when constructing the ExplodedGraph. 924d9e497a2b1eab3b1214848216050c64fc3acfd6Jordan Rose G.enableNodeReclamation(TrimInterval); 934d9e497a2b1eab3b1214848216050c64fc3acfd6Jordan Rose } 94c80135ba857da48173578b9c528fce6777e18168Ted Kremenek} 9550a6d0ce344c02782e0207574005c3b2aaa5077cTed Kremenek 96d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios KyrtzidisExprEngine::~ExprEngine() { 97cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek BR.FlushReports(); 9850a6d0ce344c02782e0207574005c3b2aaa5077cTed Kremenek} 9950a6d0ce344c02782e0207574005c3b2aaa5077cTed Kremenek 100e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek//===----------------------------------------------------------------------===// 101e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek// Utility methods. 102e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek//===----------------------------------------------------------------------===// 103e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek 1048bef8238181a30e52dea380789a7e2d760eac532Ted KremenekProgramStateRef ExprEngine::getInitialState(const LocationContext *InitLoc) { 1058bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek ProgramStateRef state = StateMgr.getInitialState(InitLoc); 106a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek const Decl *D = InitLoc->getDecl(); 1071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 108cfcd7fd0de701c5ce05e96de1ed2d0bf8c7035d9Ted Kremenek // Preconditions. 10952e5602056e4cade24cbcca57767e94e1d430b03Ted Kremenek // FIXME: It would be nice if we had a more general mechanism to add 11052e5602056e4cade24cbcca57767e94e1d430b03Ted Kremenek // such preconditions. Some day. 1115974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek do { 112a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek 1135974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 1145974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek // Precondition: the first argument of 'main' is an integer guaranteed 1155974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek // to be > 0. 1165974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek const IdentifierInfo *II = FD->getIdentifier(); 1175974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek if (!II || !(II->getName() == "main" && FD->getNumParams() > 0)) 1185974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek break; 1195974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek 1205974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek const ParmVarDecl *PD = FD->getParamDecl(0); 1215974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek QualType T = PD->getType(); 122a5796f87229b4aeebca71fa6ee1790ae7a5a0382Jordan Rose const BuiltinType *BT = dyn_cast<BuiltinType>(T); 123a5796f87229b4aeebca71fa6ee1790ae7a5a0382Jordan Rose if (!BT || !BT->isInteger()) 1245974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek break; 125b9bbd592c7ea72ada8d982e40a729beb9b53371eTed Kremenek 1265974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek const MemRegion *R = state->getRegion(PD, InitLoc); 1275974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek if (!R) 1285974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek break; 129b9bbd592c7ea72ada8d982e40a729beb9b53371eTed Kremenek 1301397663af9dbcc24dbf0e11de43931b3dc08fdbbTed Kremenek SVal V = state->getSVal(loc::MemRegionVal(R)); 1319c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek SVal Constraint_untested = evalBinOp(state, BO_GT, V, 132c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek svalBuilder.makeZeroVal(T), 133651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines svalBuilder.getConditionType()); 1345974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek 135dc84cd5efdd3430efb22546b4ac656aa0540b210David Blaikie Optional<DefinedOrUnknownSVal> Constraint = 136dc84cd5efdd3430efb22546b4ac656aa0540b210David Blaikie Constraint_untested.getAs<DefinedOrUnknownSVal>(); 137b9bbd592c7ea72ada8d982e40a729beb9b53371eTed Kremenek 1385974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek if (!Constraint) 1395974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek break; 140b9bbd592c7ea72ada8d982e40a729beb9b53371eTed Kremenek 1418bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek if (ProgramStateRef newState = state->assume(*Constraint, true)) 1425974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek state = newState; 14352e5602056e4cade24cbcca57767e94e1d430b03Ted Kremenek } 144a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek break; 145a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek } 146a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek while (0); 147a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek 148a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) { 149a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek // Precondition: 'self' is always non-null upon entry to an Objective-C 150a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek // method. 151a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek const ImplicitParamDecl *SelfD = MD->getSelfDecl(); 152a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek const MemRegion *R = state->getRegion(SelfD, InitLoc); 153a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek SVal V = state->getSVal(loc::MemRegionVal(R)); 154a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek 155dc84cd5efdd3430efb22546b4ac656aa0540b210David Blaikie if (Optional<Loc> LV = V.getAs<Loc>()) { 156a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek // Assume that the pointer value in 'self' is non-null. 157a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek state = state->assume(*LV, true); 158a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek assert(state && "'self' cannot be null"); 159a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek } 160a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek } 1615974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek 162a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) { 163a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek if (!MD->isStatic()) { 164a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek // Precondition: 'this' is always non-null upon entry to the 165a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek // top-level function. This is our starting assumption for 166a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek // analyzing an "open" program. 167a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek const StackFrameContext *SFC = InitLoc->getCurrentStackFrame(); 1686bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (SFC->getParent() == nullptr) { 16910f77ad7fc5e5cf3f37a9b14ff5843468b8b84d2Ted Kremenek loc::MemRegionVal L = svalBuilder.getCXXThis(MD, SFC); 170a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek SVal V = state->getSVal(L); 171dc84cd5efdd3430efb22546b4ac656aa0540b210David Blaikie if (Optional<Loc> LV = V.getAs<Loc>()) { 172a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek state = state->assume(*LV, true); 173a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek assert(state && "'this' cannot be null"); 174a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek } 1755974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek } 176cfcd7fd0de701c5ce05e96de1ed2d0bf8c7035d9Ted Kremenek } 177a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek } 178a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 17952e5602056e4cade24cbcca57767e94e1d430b03Ted Kremenek return state; 180e070a1df66aab6d4168fb28f7559fdf996df3567Ted Kremenek} 181e070a1df66aab6d4168fb28f7559fdf996df3567Ted Kremenek 1825e5440ba9c135f523f72e7e7c5da59d390d697c5Jordan RoseProgramStateRef 1835e5440ba9c135f523f72e7e7c5da59d390d697c5Jordan RoseExprEngine::createTemporaryRegionIfNeeded(ProgramStateRef State, 1845e5440ba9c135f523f72e7e7c5da59d390d697c5Jordan Rose const LocationContext *LC, 1855e5440ba9c135f523f72e7e7c5da59d390d697c5Jordan Rose const Expr *Ex, 1865e5440ba9c135f523f72e7e7c5da59d390d697c5Jordan Rose const Expr *Result) { 18787193dac8f2c6c8f7ee1aa9eeb64622ec75c881bJordan Rose SVal V = State->getSVal(Ex, LC); 18808291a937a149dbd036fd6ac8ab061eb8034343dJordan Rose if (!Result) { 18908291a937a149dbd036fd6ac8ab061eb8034343dJordan Rose // If we don't have an explicit result expression, we're in "if needed" 19008291a937a149dbd036fd6ac8ab061eb8034343dJordan Rose // mode. Only create a region if the current value is a NonLoc. 19108291a937a149dbd036fd6ac8ab061eb8034343dJordan Rose if (!V.getAs<NonLoc>()) 19208291a937a149dbd036fd6ac8ab061eb8034343dJordan Rose return State; 19308291a937a149dbd036fd6ac8ab061eb8034343dJordan Rose Result = Ex; 19408291a937a149dbd036fd6ac8ab061eb8034343dJordan Rose } else { 19508291a937a149dbd036fd6ac8ab061eb8034343dJordan Rose // We need to create a region no matter what. For sanity, make sure we don't 19608291a937a149dbd036fd6ac8ab061eb8034343dJordan Rose // try to stuff a Loc into a non-pointer temporary region. 19728117be48de465bc2862a8f4aaab09338be5090bJordan Rose assert(!V.getAs<Loc>() || Loc::isLocType(Result->getType()) || 19828117be48de465bc2862a8f4aaab09338be5090bJordan Rose Result->getType()->isMemberPointerType()); 19908291a937a149dbd036fd6ac8ab061eb8034343dJordan Rose } 2005e5440ba9c135f523f72e7e7c5da59d390d697c5Jordan Rose 2015e5440ba9c135f523f72e7e7c5da59d390d697c5Jordan Rose ProgramStateManager &StateMgr = State->getStateManager(); 2025e5440ba9c135f523f72e7e7c5da59d390d697c5Jordan Rose MemRegionManager &MRMgr = StateMgr.getRegionManager(); 2035e5440ba9c135f523f72e7e7c5da59d390d697c5Jordan Rose StoreManager &StoreMgr = StateMgr.getStoreManager(); 2045e5440ba9c135f523f72e7e7c5da59d390d697c5Jordan Rose 2055e5440ba9c135f523f72e7e7c5da59d390d697c5Jordan Rose // We need to be careful about treating a derived type's value as 20608291a937a149dbd036fd6ac8ab061eb8034343dJordan Rose // bindings for a base type. Unless we're creating a temporary pointer region, 20708291a937a149dbd036fd6ac8ab061eb8034343dJordan Rose // start by stripping and recording base casts. 2085e5440ba9c135f523f72e7e7c5da59d390d697c5Jordan Rose SmallVector<const CastExpr *, 4> Casts; 2095e5440ba9c135f523f72e7e7c5da59d390d697c5Jordan Rose const Expr *Inner = Ex->IgnoreParens(); 21008291a937a149dbd036fd6ac8ab061eb8034343dJordan Rose if (!Loc::isLocType(Result->getType())) { 211eafb5c694cc5d165149fcb9453bc9355fb0d44a5Jordan Rose while (const CastExpr *CE = dyn_cast<CastExpr>(Inner)) { 212eafb5c694cc5d165149fcb9453bc9355fb0d44a5Jordan Rose if (CE->getCastKind() == CK_DerivedToBase || 213eafb5c694cc5d165149fcb9453bc9355fb0d44a5Jordan Rose CE->getCastKind() == CK_UncheckedDerivedToBase) 214eafb5c694cc5d165149fcb9453bc9355fb0d44a5Jordan Rose Casts.push_back(CE); 215eafb5c694cc5d165149fcb9453bc9355fb0d44a5Jordan Rose else if (CE->getCastKind() != CK_NoOp) 216eafb5c694cc5d165149fcb9453bc9355fb0d44a5Jordan Rose break; 2175e5440ba9c135f523f72e7e7c5da59d390d697c5Jordan Rose 218eafb5c694cc5d165149fcb9453bc9355fb0d44a5Jordan Rose Inner = CE->getSubExpr()->IgnoreParens(); 219eafb5c694cc5d165149fcb9453bc9355fb0d44a5Jordan Rose } 2205e5440ba9c135f523f72e7e7c5da59d390d697c5Jordan Rose } 221f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose 2225e5440ba9c135f523f72e7e7c5da59d390d697c5Jordan Rose // Create a temporary object region for the inner expression (which may have 22308291a937a149dbd036fd6ac8ab061eb8034343dJordan Rose // a more derived type) and bind the value into it. 2246bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const TypedValueRegion *TR = nullptr; 22576b5dd48c9dbf2ed3e5830060ea55b81b7d1cca0Pavel Labath if (const MaterializeTemporaryExpr *MT = 22676b5dd48c9dbf2ed3e5830060ea55b81b7d1cca0Pavel Labath dyn_cast<MaterializeTemporaryExpr>(Result)) { 22776b5dd48c9dbf2ed3e5830060ea55b81b7d1cca0Pavel Labath StorageDuration SD = MT->getStorageDuration(); 22876b5dd48c9dbf2ed3e5830060ea55b81b7d1cca0Pavel Labath // If this object is bound to a reference with static storage duration, we 22976b5dd48c9dbf2ed3e5830060ea55b81b7d1cca0Pavel Labath // put it in a different region to prevent "address leakage" warnings. 23076b5dd48c9dbf2ed3e5830060ea55b81b7d1cca0Pavel Labath if (SD == SD_Static || SD == SD_Thread) 23176b5dd48c9dbf2ed3e5830060ea55b81b7d1cca0Pavel Labath TR = MRMgr.getCXXStaticTempObjectRegion(Inner); 23276b5dd48c9dbf2ed3e5830060ea55b81b7d1cca0Pavel Labath } 23376b5dd48c9dbf2ed3e5830060ea55b81b7d1cca0Pavel Labath if (!TR) 23476b5dd48c9dbf2ed3e5830060ea55b81b7d1cca0Pavel Labath TR = MRMgr.getCXXTempObjectRegion(Inner, LC); 23576b5dd48c9dbf2ed3e5830060ea55b81b7d1cca0Pavel Labath 23608291a937a149dbd036fd6ac8ab061eb8034343dJordan Rose SVal Reg = loc::MemRegionVal(TR); 23708291a937a149dbd036fd6ac8ab061eb8034343dJordan Rose 23808291a937a149dbd036fd6ac8ab061eb8034343dJordan Rose if (V.isUnknown()) 23908291a937a149dbd036fd6ac8ab061eb8034343dJordan Rose V = getSValBuilder().conjureSymbolVal(Result, LC, TR->getValueType(), 24008291a937a149dbd036fd6ac8ab061eb8034343dJordan Rose currBldrCtx->blockCount()); 2415e5440ba9c135f523f72e7e7c5da59d390d697c5Jordan Rose State = State->bindLoc(Reg, V); 2429f1d541ef1aca8f953e5bb4e7177969f0a2062d5Jordan Rose 2435e5440ba9c135f523f72e7e7c5da59d390d697c5Jordan Rose // Re-apply the casts (from innermost to outermost) for type sanity. 2445e5440ba9c135f523f72e7e7c5da59d390d697c5Jordan Rose for (SmallVectorImpl<const CastExpr *>::reverse_iterator I = Casts.rbegin(), 2455e5440ba9c135f523f72e7e7c5da59d390d697c5Jordan Rose E = Casts.rend(); 2465e5440ba9c135f523f72e7e7c5da59d390d697c5Jordan Rose I != E; ++I) { 2475e5440ba9c135f523f72e7e7c5da59d390d697c5Jordan Rose Reg = StoreMgr.evalDerivedToBase(Reg, *I); 248f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose } 249f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose 25008291a937a149dbd036fd6ac8ab061eb8034343dJordan Rose State = State->BindExpr(Result, LC, Reg); 251f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose return State; 252f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose} 253f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose 254e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek//===----------------------------------------------------------------------===// 255e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek// Top-level transfer function logic (Dispatcher). 256e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek//===----------------------------------------------------------------------===// 257e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek 2589c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek/// evalAssume - Called by ConstraintManager. Used to call checker-specific 25932a58084a4c53e6938dd81bfce224db25a5976d1Ted Kremenek/// logic for handling assumptions on symbolic values. 2608bef8238181a30e52dea380789a7e2d760eac532Ted KremenekProgramStateRef ExprEngine::processAssume(ProgramStateRef state, 261fe27971d54d26997149d6b84057f04ff398d1d5dJordy Rose SVal cond, bool assumption) { 262fe27971d54d26997149d6b84057f04ff398d1d5dJordy Rose return getCheckerManager().runCheckersForEvalAssume(state, cond, assumption); 26332a58084a4c53e6938dd81bfce224db25a5976d1Ted Kremenek} 26432a58084a4c53e6938dd81bfce224db25a5976d1Ted Kremenek 2658bef8238181a30e52dea380789a7e2d760eac532Ted Kremenekbool ExprEngine::wantsRegionChangeUpdate(ProgramStateRef state) { 266183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis return getCheckerManager().wantsRegionChangeUpdate(state); 267c2b7dfaad674587cfd220ff447b3710d252130c3Jordy Rose} 268c2b7dfaad674587cfd220ff447b3710d252130c3Jordy Rose 269a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga NainarProgramStateRef 2708bef8238181a30e52dea380789a7e2d760eac532Ted KremenekExprEngine::processRegionChanges(ProgramStateRef state, 271bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks const InvalidatedSymbols *invalidated, 272537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose ArrayRef<const MemRegion *> Explicits, 27366c40400e7d6272b0cd675ada18dd62c1f0362c7Anna Zaks ArrayRef<const MemRegion *> Regions, 274740d490593e0de8732a697c9f77b90ddd463863bJordan Rose const CallEvent *Call) { 27535bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek return getCheckerManager().runCheckersForRegionChanges(state, invalidated, 27666c40400e7d6272b0cd675ada18dd62c1f0362c7Anna Zaks Explicits, Regions, Call); 277c2b7dfaad674587cfd220ff447b3710d252130c3Jordy Rose} 278c2b7dfaad674587cfd220ff447b3710d252130c3Jordy Rose 2798bef8238181a30e52dea380789a7e2d760eac532Ted Kremenekvoid ExprEngine::printState(raw_ostream &Out, ProgramStateRef State, 280dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose const char *NL, const char *Sep) { 281dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose getCheckerManager().runCheckersForPrintState(Out, State, NL, Sep); 282dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose} 283dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose 284e36de1fe51c39d9161915dd3dbef880954af6476Ted Kremenekvoid ExprEngine::processEndWorklist(bool hasWorkRemaining) { 28530726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis getCheckerManager().runCheckersForEndAnalysis(G, BR, *this); 286ccc263b44c62ce3a02f797a3ddb3d6017cf0e5e4Ted Kremenek} 287ccc263b44c62ce3a02f797a3ddb3d6017cf0e5e4Ted Kremenek 288ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaksvoid ExprEngine::processCFGElement(const CFGElement E, ExplodedNode *Pred, 289ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks unsigned StmtIdx, NodeBuilderContext *Ctx) { 290ac7cc2d37e82181e73fcc265c1d0a619d18b7605Jordan Rose PrettyStackTraceLocationContext CrashInfo(Pred->getLocationContext()); 29166c486f275531df6362b3511fc3af6563561801bTed Kremenek currStmtIdx = StmtIdx; 29266c486f275531df6362b3511fc3af6563561801bTed Kremenek currBldrCtx = Ctx; 293ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks 2949c6cd67ea416bace666d614c84d5531124287653Zhongxing Xu switch (E.getKind()) { 2953c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek case CFGElement::Statement: 296fdf6a279c9a75c778eba382d9a156697092982a1David Blaikie ProcessStmt(const_cast<Stmt*>(E.castAs<CFGStmt>().getStmt()), Pred); 2973c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek return; 2983c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek case CFGElement::Initializer: 299fdf6a279c9a75c778eba382d9a156697092982a1David Blaikie ProcessInitializer(E.castAs<CFGInitializer>().getInitializer(), Pred); 3003c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek return; 301651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines case CFGElement::NewAllocator: 302651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ProcessNewAllocator(E.castAs<CFGNewAllocator>().getAllocatorExpr(), 303651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Pred); 304651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return; 3053c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek case CFGElement::AutomaticObjectDtor: 30636d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose case CFGElement::DeleteDtor: 3073c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek case CFGElement::BaseDtor: 3083c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek case CFGElement::MemberDtor: 3093c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek case CFGElement::TemporaryDtor: 310fdf6a279c9a75c778eba382d9a156697092982a1David Blaikie ProcessImplicitDtor(E.castAs<CFGImplicitDtor>(), Pred); 3113c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek return; 3129c6cd67ea416bace666d614c84d5531124287653Zhongxing Xu } 3139c6cd67ea416bace666d614c84d5531124287653Zhongxing Xu} 3149c6cd67ea416bace666d614c84d5531124287653Zhongxing Xu 315ce117a7d289f57f792e5cc3294280cfe070433deTed Kremenekstatic bool shouldRemoveDeadBindings(AnalysisManager &AMgr, 316ce117a7d289f57f792e5cc3294280cfe070433deTed Kremenek const CFGStmt S, 317ce117a7d289f57f792e5cc3294280cfe070433deTed Kremenek const ExplodedNode *Pred, 318ce117a7d289f57f792e5cc3294280cfe070433deTed Kremenek const LocationContext *LC) { 319a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 320ce117a7d289f57f792e5cc3294280cfe070433deTed Kremenek // Are we never purging state values? 321255d4d4226b24036ceb11228fbb74286e58620f7Ted Kremenek if (AMgr.options.AnalysisPurgeOpt == PurgeNone) 322ce117a7d289f57f792e5cc3294280cfe070433deTed Kremenek return false; 323ce117a7d289f57f792e5cc3294280cfe070433deTed Kremenek 324ce117a7d289f57f792e5cc3294280cfe070433deTed Kremenek // Is this the beginning of a basic block? 3257a95de68c093991047ed8d339479ccad51b88663David Blaikie if (Pred->getLocation().getAs<BlockEntrance>()) 326ce117a7d289f57f792e5cc3294280cfe070433deTed Kremenek return true; 327ce117a7d289f57f792e5cc3294280cfe070433deTed Kremenek 328ce117a7d289f57f792e5cc3294280cfe070433deTed Kremenek // Is this on a non-expression? 329ce117a7d289f57f792e5cc3294280cfe070433deTed Kremenek if (!isa<Expr>(S.getStmt())) 330ce117a7d289f57f792e5cc3294280cfe070433deTed Kremenek return true; 331a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 332ff80afcfb2b00ccffcb6cb10528bec565fc59eddAnna Zaks // Run before processing a call. 3336062334cc388bce69fb3978c4ecb26c6485a5c2bJordan Rose if (CallEvent::isCallStmt(S.getStmt())) 334ff80afcfb2b00ccffcb6cb10528bec565fc59eddAnna Zaks return true; 335ff80afcfb2b00ccffcb6cb10528bec565fc59eddAnna Zaks 336ce117a7d289f57f792e5cc3294280cfe070433deTed Kremenek // Is this an expression that is consumed by another expression? If so, 337ce117a7d289f57f792e5cc3294280cfe070433deTed Kremenek // postpone cleaning out the state. 338ce117a7d289f57f792e5cc3294280cfe070433deTed Kremenek ParentMap &PM = LC->getAnalysisDeclContext()->getParentMap(); 339ce117a7d289f57f792e5cc3294280cfe070433deTed Kremenek return !PM.isConsumedExpr(cast<Expr>(S.getStmt())); 340ce117a7d289f57f792e5cc3294280cfe070433deTed Kremenek} 341ce117a7d289f57f792e5cc3294280cfe070433deTed Kremenek 3420b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaksvoid ExprEngine::removeDead(ExplodedNode *Pred, ExplodedNodeSet &Out, 3430b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks const Stmt *ReferenceStmt, 34484c484545c5906ba55143e212b4a5275ab55889fJordan Rose const LocationContext *LC, 3450b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks const Stmt *DiagnosticStmt, 3460b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks ProgramPoint::Kind K) { 3470b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks assert((K == ProgramPoint::PreStmtPurgeDeadSymbolsKind || 3486bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ReferenceStmt == nullptr || isa<ReturnStmt>(ReferenceStmt)) 3498501b7a1c4c4a9ba0ea6cb8e500e601ef3759debAnna Zaks && "PostStmt is not generally supported by the SymbolReaper yet"); 35084c484545c5906ba55143e212b4a5275ab55889fJordan Rose assert(LC && "Must pass the current (or expiring) LocationContext"); 35184c484545c5906ba55143e212b4a5275ab55889fJordan Rose 35284c484545c5906ba55143e212b4a5275ab55889fJordan Rose if (!DiagnosticStmt) { 35384c484545c5906ba55143e212b4a5275ab55889fJordan Rose DiagnosticStmt = ReferenceStmt; 35484c484545c5906ba55143e212b4a5275ab55889fJordan Rose assert(DiagnosticStmt && "Required for clearing a LocationContext"); 35584c484545c5906ba55143e212b4a5275ab55889fJordan Rose } 35684c484545c5906ba55143e212b4a5275ab55889fJordan Rose 3570b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks NumRemoveDeadBindings++; 3589428723d6730f4fd257e15b78d24991ae95bbd84Jordan Rose ProgramStateRef CleanedState = Pred->getState(); 35984c484545c5906ba55143e212b4a5275ab55889fJordan Rose 36084c484545c5906ba55143e212b4a5275ab55889fJordan Rose // LC is the location context being destroyed, but SymbolReaper wants a 36184c484545c5906ba55143e212b4a5275ab55889fJordan Rose // location context that is still live. (If this is the top-level stack 36284c484545c5906ba55143e212b4a5275ab55889fJordan Rose // frame, this will be null.) 36384c484545c5906ba55143e212b4a5275ab55889fJordan Rose if (!ReferenceStmt) { 36484c484545c5906ba55143e212b4a5275ab55889fJordan Rose assert(K == ProgramPoint::PostStmtPurgeDeadSymbolsKind && 36584c484545c5906ba55143e212b4a5275ab55889fJordan Rose "Use PostStmtPurgeDeadSymbolsKind for clearing a LocationContext"); 36684c484545c5906ba55143e212b4a5275ab55889fJordan Rose LC = LC->getParent(); 36784c484545c5906ba55143e212b4a5275ab55889fJordan Rose } 36884c484545c5906ba55143e212b4a5275ab55889fJordan Rose 3696bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const StackFrameContext *SFC = LC ? LC->getCurrentStackFrame() : nullptr; 37084c484545c5906ba55143e212b4a5275ab55889fJordan Rose SymbolReaper SymReaper(SFC, ReferenceStmt, SymMgr, getStoreManager()); 3710b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks 3720b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks getCheckerManager().runCheckersForLiveSymbols(CleanedState, SymReaper); 3730b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks 3740b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks // Create a state in which dead bindings are removed from the environment 3750b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks // and the store. TODO: The function should just return new env and store, 3760b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks // not a new state. 3770b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks CleanedState = StateMgr.removeDeadBindings(CleanedState, SFC, SymReaper); 378241677a13cc46647a8f5098b3e3239bd9480dca2Ted Kremenek 37977d7ef8d8a80ccb2ab3d25c80810571e3ab14ee4Ted Kremenek // Process any special transfer function for dead symbols. 380f185cc1ac77a84139c603eee3473b88dcb839c68Anna Zaks // A tag to track convenience transitions, which can be removed at cleanup. 381651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines static SimpleProgramPointTag cleanupTag(TagProviderName, "Clean Node"); 3826bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks if (!SymReaper.hasDeadSymbols()) { 3836bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks // Generate a CleanedNode that has the environment and store cleaned 3846bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks // up. Since no symbols are dead, we can optimize and not clean out 3856bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks // the constraint manager. 38666c486f275531df6362b3511fc3af6563561801bTed Kremenek StmtNodeBuilder Bldr(Pred, Out, *currBldrCtx); 387fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose Bldr.generateNode(DiagnosticStmt, Pred, CleanedState, &cleanupTag, K); 3881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3896bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks } else { 3906bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks // Call checkers with the non-cleaned state so that they could query the 3916bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks // values of the soon to be dead symbols. 392fe27971d54d26997149d6b84057f04ff398d1d5dJordy Rose ExplodedNodeSet CheckedSet; 3930b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks getCheckerManager().runCheckersForDeadSymbols(CheckedSet, Pred, SymReaper, 3940b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks DiagnosticStmt, *this, K); 395183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis 396fe27971d54d26997149d6b84057f04ff398d1d5dJordy Rose // For each node in CheckedSet, generate CleanedNodes that have the 397fe27971d54d26997149d6b84057f04ff398d1d5dJordy Rose // environment, the store, and the constraints cleaned up but have the 398fe27971d54d26997149d6b84057f04ff398d1d5dJordy Rose // user-supplied states as the predecessors. 39966c486f275531df6362b3511fc3af6563561801bTed Kremenek StmtNodeBuilder Bldr(CheckedSet, Out, *currBldrCtx); 400fe27971d54d26997149d6b84057f04ff398d1d5dJordy Rose for (ExplodedNodeSet::const_iterator 401fe27971d54d26997149d6b84057f04ff398d1d5dJordy Rose I = CheckedSet.begin(), E = CheckedSet.end(); I != E; ++I) { 4028bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek ProgramStateRef CheckerState = (*I)->getState(); 4036bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks 4046bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks // The constraint manager has not been cleaned up yet, so clean up now. 4056bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks CheckerState = getConstraintManager().removeDeadBindings(CheckerState, 4066bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks SymReaper); 4076bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks 4080b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks assert(StateMgr.haveEqualEnvironments(CheckerState, Pred->getState()) && 4096bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks "Checkers are not allowed to modify the Environment as a part of " 4106bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks "checkDeadSymbols processing."); 4110b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks assert(StateMgr.haveEqualStores(CheckerState, Pred->getState()) && 4126bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks "Checkers are not allowed to modify the Store as a part of " 4136bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks "checkDeadSymbols processing."); 4146bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks 4156bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks // Create a state based on CleanedState with CheckerState GDM and 4166bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks // generate a transition to that state. 4178bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek ProgramStateRef CleanedCheckerSt = 4186bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks StateMgr.getPersistentStateWithGDM(CleanedState, CheckerState); 419fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose Bldr.generateNode(DiagnosticStmt, *I, CleanedCheckerSt, &cleanupTag, K); 4206bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks } 42177d7ef8d8a80ccb2ab3d25c80810571e3ab14ee4Ted Kremenek } 4220b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks} 4230b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks 4240b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaksvoid ExprEngine::ProcessStmt(const CFGStmt S, 4250b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks ExplodedNode *Pred) { 4260b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks // Reclaim any unnecessary nodes in the ExplodedGraph. 4270b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks G.reclaimRecentlyAllocatedNodes(); 4280b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks 4299428723d6730f4fd257e15b78d24991ae95bbd84Jordan Rose const Stmt *currStmt = S.getStmt(); 4300b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(), 43166c486f275531df6362b3511fc3af6563561801bTed Kremenek currStmt->getLocStart(), 4320b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks "Error evaluating statement"); 4331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4340b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks // Remove dead bindings and symbols. 4350b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks ExplodedNodeSet CleanedStates; 4369428723d6730f4fd257e15b78d24991ae95bbd84Jordan Rose if (shouldRemoveDeadBindings(AMgr, S, Pred, Pred->getLocationContext())){ 4379428723d6730f4fd257e15b78d24991ae95bbd84Jordan Rose removeDead(Pred, CleanedStates, currStmt, Pred->getLocationContext()); 4380b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks } else 4399428723d6730f4fd257e15b78d24991ae95bbd84Jordan Rose CleanedStates.Add(Pred); 4400b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks 4410b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks // Visit the statement. 442dd7ddf2b2296f95e7591ca3f9791f0eb9a15ee42Anna Zaks ExplodedNodeSet Dst; 4430b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks for (ExplodedNodeSet::iterator I = CleanedStates.begin(), 4440b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks E = CleanedStates.end(); I != E; ++I) { 445dd7ddf2b2296f95e7591ca3f9791f0eb9a15ee42Anna Zaks ExplodedNodeSet DstI; 4461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // Visit the statement. 44766c486f275531df6362b3511fc3af6563561801bTed Kremenek Visit(currStmt, *I, DstI); 448dd7ddf2b2296f95e7591ca3f9791f0eb9a15ee42Anna Zaks Dst.insert(DstI); 449ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks } 450ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks 451dd7ddf2b2296f95e7591ca3f9791f0eb9a15ee42Anna Zaks // Enqueue the new nodes onto the work list. 45266c486f275531df6362b3511fc3af6563561801bTed Kremenek Engine.enqueue(Dst, currBldrCtx->getBlock(), currStmtIdx); 453e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek} 454e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek 455d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisvoid ExprEngine::ProcessInitializer(const CFGInitializer Init, 456056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks ExplodedNode *Pred) { 457cbb67480094b3bcb5b715acd827cbad55e2a204cSean Hunt const CXXCtorInitializer *BMI = Init.getInitializer(); 458563ea2335d7d0df44bbfe8941f64523e8af1fc14Jordan Rose 459563ea2335d7d0df44bbfe8941f64523e8af1fc14Jordan Rose PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(), 460563ea2335d7d0df44bbfe8941f64523e8af1fc14Jordan Rose BMI->getSourceLocation(), 461563ea2335d7d0df44bbfe8941f64523e8af1fc14Jordan Rose "Error evaluating initializer"); 462563ea2335d7d0df44bbfe8941f64523e8af1fc14Jordan Rose 4639428723d6730f4fd257e15b78d24991ae95bbd84Jordan Rose // We don't clean up dead bindings here. 464056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks const StackFrameContext *stackFrame = 465056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks cast<StackFrameContext>(Pred->getLocationContext()); 466056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks const CXXConstructorDecl *decl = 467056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks cast<CXXConstructorDecl>(stackFrame->getDecl()); 4683682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose 4693682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose ProgramStateRef State = Pred->getState(); 4703a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose SVal thisVal = State->getSVal(svalBuilder.getCXXThis(decl, stackFrame)); 4719dc84c9455df2a77195147d0210c915dc1775a88Zhongxing Xu 4723682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose ExplodedNodeSet Tmp(Pred); 473610f79cbab4d752349b5c81a94682a6a82b102e7Anna Zaks SVal FieldLoc; 4743682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose 4753a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose // Evaluate the initializer, if necessary 47600eb3f9c5b33e3d99aee1f8b75dd9c9678fdd66bFrancois Pichet if (BMI->isAnyMemberInitializer()) { 4773a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose // Constructors build the object directly in the field, 4783a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose // but non-objects must be copied in from the initializer. 479a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar if (auto *CtorExpr = findDirectConstructorForCurrentCFGElement()) { 480a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar assert(BMI->getInit()->IgnoreImplicit() == CtorExpr); 481a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar (void)CtorExpr; 482a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar // The field was directly constructed, so there is no need to bind. 483a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar } else { 484a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar const Expr *Init = BMI->getInit()->IgnoreImplicit(); 485ecee1651c100342366a9417c85c6e50399039930Jordan Rose const ValueDecl *Field; 486ecee1651c100342366a9417c85c6e50399039930Jordan Rose if (BMI->isIndirectMemberInitializer()) { 487ecee1651c100342366a9417c85c6e50399039930Jordan Rose Field = BMI->getIndirectMember(); 4883a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose FieldLoc = State->getLValue(BMI->getIndirectMember(), thisVal); 489ecee1651c100342366a9417c85c6e50399039930Jordan Rose } else { 490ecee1651c100342366a9417c85c6e50399039930Jordan Rose Field = BMI->getMember(); 4913a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose FieldLoc = State->getLValue(BMI->getMember(), thisVal); 492ecee1651c100342366a9417c85c6e50399039930Jordan Rose } 4933a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose 494ecee1651c100342366a9417c85c6e50399039930Jordan Rose SVal InitVal; 495ecee1651c100342366a9417c85c6e50399039930Jordan Rose if (BMI->getNumArrayIndices() > 0) { 496ecee1651c100342366a9417c85c6e50399039930Jordan Rose // Handle arrays of trivial type. We can represent this with a 497ecee1651c100342366a9417c85c6e50399039930Jordan Rose // primitive load/copy from the base array region. 498ecee1651c100342366a9417c85c6e50399039930Jordan Rose const ArraySubscriptExpr *ASE; 499ecee1651c100342366a9417c85c6e50399039930Jordan Rose while ((ASE = dyn_cast<ArraySubscriptExpr>(Init))) 500ecee1651c100342366a9417c85c6e50399039930Jordan Rose Init = ASE->getBase()->IgnoreImplicit(); 501ecee1651c100342366a9417c85c6e50399039930Jordan Rose 502ecee1651c100342366a9417c85c6e50399039930Jordan Rose SVal LValue = State->getSVal(Init, stackFrame); 503ecee1651c100342366a9417c85c6e50399039930Jordan Rose if (Optional<Loc> LValueLoc = LValue.getAs<Loc>()) 504ecee1651c100342366a9417c85c6e50399039930Jordan Rose InitVal = State->getSVal(*LValueLoc); 505ecee1651c100342366a9417c85c6e50399039930Jordan Rose 506ecee1651c100342366a9417c85c6e50399039930Jordan Rose // If we fail to get the value for some reason, use a symbolic value. 507ecee1651c100342366a9417c85c6e50399039930Jordan Rose if (InitVal.isUnknownOrUndef()) { 508ecee1651c100342366a9417c85c6e50399039930Jordan Rose SValBuilder &SVB = getSValBuilder(); 509ecee1651c100342366a9417c85c6e50399039930Jordan Rose InitVal = SVB.conjureSymbolVal(BMI->getInit(), stackFrame, 510ecee1651c100342366a9417c85c6e50399039930Jordan Rose Field->getType(), 511ecee1651c100342366a9417c85c6e50399039930Jordan Rose currBldrCtx->blockCount()); 512ecee1651c100342366a9417c85c6e50399039930Jordan Rose } 513ecee1651c100342366a9417c85c6e50399039930Jordan Rose } else { 514ecee1651c100342366a9417c85c6e50399039930Jordan Rose InitVal = State->getSVal(BMI->getInit(), stackFrame); 515ecee1651c100342366a9417c85c6e50399039930Jordan Rose } 5163682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose 517ecee1651c100342366a9417c85c6e50399039930Jordan Rose assert(Tmp.size() == 1 && "have not generated any new nodes yet"); 518ecee1651c100342366a9417c85c6e50399039930Jordan Rose assert(*Tmp.begin() == Pred && "have not generated any new nodes yet"); 5193682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose Tmp.clear(); 520a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 521610f79cbab4d752349b5c81a94682a6a82b102e7Anna Zaks PostInitializer PP(BMI, FieldLoc.getAsRegion(), stackFrame); 5223682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose evalBind(Tmp, Init, Pred, FieldLoc, InitVal, /*isInit=*/true, &PP); 5233a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose } 524056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks } else { 525563ea2335d7d0df44bbfe8941f64523e8af1fc14Jordan Rose assert(BMI->isBaseInitializer() || BMI->isDelegatingInitializer()); 526888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose // We already did all the work when visiting the CXXConstructExpr. 527056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks } 528dd7ddf2b2296f95e7591ca3f9791f0eb9a15ee42Anna Zaks 5293682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose // Construct PostInitializer nodes whether the state changed or not, 5303a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose // so that the diagnostics don't get confused. 531610f79cbab4d752349b5c81a94682a6a82b102e7Anna Zaks PostInitializer PP(BMI, FieldLoc.getAsRegion(), stackFrame); 5323682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose ExplodedNodeSet Dst; 5333682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose NodeBuilder Bldr(Tmp, Dst, *currBldrCtx); 5343682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose for (ExplodedNodeSet::iterator I = Tmp.begin(), E = Tmp.end(); I != E; ++I) { 5353682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose ExplodedNode *N = *I; 5363682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose Bldr.generateNode(PP, N->getState(), N); 5373682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose } 5383a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose 539dd7ddf2b2296f95e7591ca3f9791f0eb9a15ee42Anna Zaks // Enqueue the new nodes onto the work list. 54066c486f275531df6362b3511fc3af6563561801bTed Kremenek Engine.enqueue(Dst, currBldrCtx->getBlock(), currStmtIdx); 5419c6cd67ea416bace666d614c84d5531124287653Zhongxing Xu} 5429c6cd67ea416bace666d614c84d5531124287653Zhongxing Xu 543d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisvoid ExprEngine::ProcessImplicitDtor(const CFGImplicitDtor D, 544ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks ExplodedNode *Pred) { 545ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks ExplodedNodeSet Dst; 5463c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek switch (D.getKind()) { 5474ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu case CFGElement::AutomaticObjectDtor: 548fdf6a279c9a75c778eba382d9a156697092982a1David Blaikie ProcessAutomaticObjDtor(D.castAs<CFGAutomaticObjDtor>(), Pred, Dst); 5494ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu break; 5504ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu case CFGElement::BaseDtor: 551fdf6a279c9a75c778eba382d9a156697092982a1David Blaikie ProcessBaseDtor(D.castAs<CFGBaseDtor>(), Pred, Dst); 5524ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu break; 5534ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu case CFGElement::MemberDtor: 554fdf6a279c9a75c778eba382d9a156697092982a1David Blaikie ProcessMemberDtor(D.castAs<CFGMemberDtor>(), Pred, Dst); 5554ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu break; 5564ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu case CFGElement::TemporaryDtor: 557fdf6a279c9a75c778eba382d9a156697092982a1David Blaikie ProcessTemporaryDtor(D.castAs<CFGTemporaryDtor>(), Pred, Dst); 5584ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu break; 55936d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose case CFGElement::DeleteDtor: 56036d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose ProcessDeleteDtor(D.castAs<CFGDeleteDtor>(), Pred, Dst); 56136d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose break; 5624ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu default: 5634ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu llvm_unreachable("Unexpected dtor kind."); 5644ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu } 565ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks 566dd7ddf2b2296f95e7591ca3f9791f0eb9a15ee42Anna Zaks // Enqueue the new nodes onto the work list. 56766c486f275531df6362b3511fc3af6563561801bTed Kremenek Engine.enqueue(Dst, currBldrCtx->getBlock(), currStmtIdx); 5684ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu} 5694ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu 570651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid ExprEngine::ProcessNewAllocator(const CXXNewExpr *NE, 571651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ExplodedNode *Pred) { 572651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ExplodedNodeSet Dst; 573651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines AnalysisManager &AMgr = getAnalysisManager(); 574651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines AnalyzerOptions &Opts = AMgr.options; 575651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // TODO: We're not evaluating allocators for all cases just yet as 576651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // we're not handling the return value correctly, which causes false 577651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // positives when the alpha.cplusplus.NewDeleteLeaks check is on. 578651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (Opts.mayInlineCXXAllocator()) 579651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines VisitCXXNewAllocatorCall(NE, Pred, Dst); 580651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines else { 581651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines NodeBuilder Bldr(Pred, Dst, *currBldrCtx); 582651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const LocationContext *LCtx = Pred->getLocationContext(); 583651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines PostImplicitCall PP(NE->getOperatorNew(), NE->getLocStart(), LCtx); 584651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Bldr.generateNode(PP, Pred->getState(), Pred); 585651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 586651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Engine.enqueue(Dst, currBldrCtx->getBlock(), currStmtIdx); 587651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 588651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 589056c4b46335a3bd2612414735d5749ee159c0165Anna Zaksvoid ExprEngine::ProcessAutomaticObjDtor(const CFGAutomaticObjDtor Dtor, 590056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks ExplodedNode *Pred, 591056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks ExplodedNodeSet &Dst) { 592056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks const VarDecl *varDecl = Dtor.getVarDecl(); 5932210490e6d099b7a5b4f68f44a136e4dcf3cdea2Zhongxing Xu QualType varType = varDecl->getType(); 5942210490e6d099b7a5b4f68f44a136e4dcf3cdea2Zhongxing Xu 59508291a937a149dbd036fd6ac8ab061eb8034343dJordan Rose ProgramStateRef state = Pred->getState(); 59608291a937a149dbd036fd6ac8ab061eb8034343dJordan Rose SVal dest = state->getLValue(varDecl, Pred->getLocationContext()); 59708291a937a149dbd036fd6ac8ab061eb8034343dJordan Rose const MemRegion *Region = dest.castAs<loc::MemRegionVal>().getRegion(); 5982210490e6d099b7a5b4f68f44a136e4dcf3cdea2Zhongxing Xu 59908291a937a149dbd036fd6ac8ab061eb8034343dJordan Rose if (const ReferenceType *refType = varType->getAs<ReferenceType>()) { 60008291a937a149dbd036fd6ac8ab061eb8034343dJordan Rose varType = refType->getPointeeType(); 60108291a937a149dbd036fd6ac8ab061eb8034343dJordan Rose Region = state->getSVal(Region).getAsRegion(); 60208291a937a149dbd036fd6ac8ab061eb8034343dJordan Rose } 603b13453bd8a91f331d0910ca95ad52aa41b52f648Zhongxing Xu 60408291a937a149dbd036fd6ac8ab061eb8034343dJordan Rose VisitCXXDestructor(varType, Region, Dtor.getTriggerStmt(), /*IsBase=*/ false, 60508291a937a149dbd036fd6ac8ab061eb8034343dJordan Rose Pred, Dst); 6064ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu} 6074ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu 60836d558d85653315edb389677e995ec9ccdbfbf3dJordan Rosevoid ExprEngine::ProcessDeleteDtor(const CFGDeleteDtor Dtor, 60936d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose ExplodedNode *Pred, 61036d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose ExplodedNodeSet &Dst) { 61181557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose ProgramStateRef State = Pred->getState(); 61281557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose const LocationContext *LCtx = Pred->getLocationContext(); 61381557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose const CXXDeleteExpr *DE = Dtor.getDeleteExpr(); 61481557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose const Stmt *Arg = DE->getArgument(); 61581557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose SVal ArgVal = State->getSVal(Arg, LCtx); 61681557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose 61781557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose // If the argument to delete is known to be a null value, 61881557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose // don't run destructor. 61981557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose if (State->isNull(ArgVal).isConstrainedTrue()) { 62081557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose QualType DTy = DE->getDestroyedType(); 62181557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose QualType BTy = getContext().getBaseElementType(DTy); 62281557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose const CXXRecordDecl *RD = BTy->getAsCXXRecordDecl(); 62381557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose const CXXDestructorDecl *Dtor = RD->getDestructor(); 62481557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose 62581557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose PostImplicitCall PP(Dtor, DE->getLocStart(), LCtx); 62681557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose NodeBuilder Bldr(Pred, Dst, *currBldrCtx); 62781557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose Bldr.generateNode(PP, Pred->getState(), Pred); 62881557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose return; 62981557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose } 63081557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose 63181557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose VisitCXXDestructor(DE->getDestroyedType(), 63281557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose ArgVal.getAsRegion(), 63381557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose DE, /*IsBase=*/ false, 63481557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose Pred, Dst); 63536d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose} 63636d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose 637d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisvoid ExprEngine::ProcessBaseDtor(const CFGBaseDtor D, 638888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose ExplodedNode *Pred, ExplodedNodeSet &Dst) { 639888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose const LocationContext *LCtx = Pred->getLocationContext(); 640888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose 641888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose const CXXDestructorDecl *CurDtor = cast<CXXDestructorDecl>(LCtx->getDecl()); 642888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose Loc ThisPtr = getSValBuilder().getCXXThis(CurDtor, 643888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose LCtx->getCurrentStackFrame()); 644888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose SVal ThisVal = Pred->getState()->getSVal(ThisPtr); 645888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose 646888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose // Create the base object region. 6474411b423e91da0a2c879b70c0222aeba35f72044Jordan Rose const CXXBaseSpecifier *Base = D.getBaseSpecifier(); 6484411b423e91da0a2c879b70c0222aeba35f72044Jordan Rose QualType BaseTy = Base->getType(); 6494411b423e91da0a2c879b70c0222aeba35f72044Jordan Rose SVal BaseVal = getStoreManager().evalDerivedToBase(ThisVal, BaseTy, 6504411b423e91da0a2c879b70c0222aeba35f72044Jordan Rose Base->isVirtual()); 651888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose 6525251abea41b446c26e3239c8dd6c7edea6fc335dDavid Blaikie VisitCXXDestructor(BaseTy, BaseVal.castAs<loc::MemRegionVal>().getRegion(), 6535251abea41b446c26e3239c8dd6c7edea6fc335dDavid Blaikie CurDtor->getBody(), /*IsBase=*/ true, Pred, Dst); 654888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose} 6554ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu 656d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisvoid ExprEngine::ProcessMemberDtor(const CFGMemberDtor D, 6573a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose ExplodedNode *Pred, ExplodedNodeSet &Dst) { 6583a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose const FieldDecl *Member = D.getFieldDecl(); 6593a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose ProgramStateRef State = Pred->getState(); 6603a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose const LocationContext *LCtx = Pred->getLocationContext(); 6613a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose 6623a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose const CXXDestructorDecl *CurDtor = cast<CXXDestructorDecl>(LCtx->getDecl()); 6633a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose Loc ThisVal = getSValBuilder().getCXXThis(CurDtor, 6643a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose LCtx->getCurrentStackFrame()); 6655251abea41b446c26e3239c8dd6c7edea6fc335dDavid Blaikie SVal FieldVal = 6665251abea41b446c26e3239c8dd6c7edea6fc335dDavid Blaikie State->getLValue(Member, State->getSVal(ThisVal).castAs<Loc>()); 6673a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose 6683a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose VisitCXXDestructor(Member->getType(), 6695251abea41b446c26e3239c8dd6c7edea6fc335dDavid Blaikie FieldVal.castAs<loc::MemRegionVal>().getRegion(), 670200fa2e70d52ae6d620e81cd45536071fdde70c0Jordan Rose CurDtor->getBody(), /*IsBase=*/false, Pred, Dst); 6713a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose} 6724ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu 673d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisvoid ExprEngine::ProcessTemporaryDtor(const CFGTemporaryDtor D, 674056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks ExplodedNode *Pred, 67595ab9e306f4deefeabd89ea61987f4a8d67e0890Pavel Labath ExplodedNodeSet &Dst) { 676176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines ExplodedNodeSet CleanDtorState; 677176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines StmtNodeBuilder StmtBldr(Pred, CleanDtorState, *currBldrCtx); 678176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines ProgramStateRef State = Pred->getState(); 679176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (State->contains<InitializedTemporariesSet>( 680176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines std::make_pair(D.getBindTemporaryExpr(), Pred->getStackFrame()))) { 681176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // FIXME: Currently we insert temporary destructors for default parameters, 682176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // but we don't insert the constructors. 683176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines State = State->remove<InitializedTemporariesSet>( 684176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines std::make_pair(D.getBindTemporaryExpr(), Pred->getStackFrame())); 685176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 686176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines StmtBldr.generateNode(D.getBindTemporaryExpr(), Pred, State); 68795ab9e306f4deefeabd89ea61987f4a8d67e0890Pavel Labath 68895ab9e306f4deefeabd89ea61987f4a8d67e0890Pavel Labath QualType varType = D.getBindTemporaryExpr()->getSubExpr()->getType(); 689176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // FIXME: Currently CleanDtorState can be empty here due to temporaries being 690176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // bound to default parameters. 691176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines assert(CleanDtorState.size() <= 1); 692176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines ExplodedNode *CleanPred = 693176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CleanDtorState.empty() ? Pred : *CleanDtorState.begin(); 694176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // FIXME: Inlining of temporary destructors is not supported yet anyway, so 695176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // we just put a NULL region for now. This will need to be changed later. 6966bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines VisitCXXDestructor(varType, nullptr, D.getBindTemporaryExpr(), 697176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines /*IsBase=*/false, CleanPred, Dst); 698176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines} 699176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 700176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesvoid ExprEngine::processCleanupTemporaryBranch(const CXXBindTemporaryExpr *BTE, 701176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines NodeBuilderContext &BldCtx, 702176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines ExplodedNode *Pred, 703176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines ExplodedNodeSet &Dst, 704176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines const CFGBlock *DstT, 705176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines const CFGBlock *DstF) { 706176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines BranchNodeBuilder TempDtorBuilder(Pred, Dst, BldCtx, DstT, DstF); 707176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (Pred->getState()->contains<InitializedTemporariesSet>( 708176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines std::make_pair(BTE, Pred->getStackFrame()))) { 709176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines TempDtorBuilder.markInfeasible(false); 710176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines TempDtorBuilder.generateNode(Pred->getState(), true, Pred); 711176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } else { 712176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines TempDtorBuilder.markInfeasible(true); 713176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines TempDtorBuilder.generateNode(Pred->getState(), false, Pred); 714176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 715176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines} 716176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 717176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesvoid ExprEngine::VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *BTE, 718176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines ExplodedNodeSet &PreVisit, 719176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines ExplodedNodeSet &Dst) { 720176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (!getAnalysisManager().options.includeTemporaryDtorsInCFG()) { 721176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // In case we don't have temporary destructors in the CFG, do not mark 722176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // the initialization - we would otherwise never clean it up. 723176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines Dst = PreVisit; 724176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return; 725176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 726176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines StmtNodeBuilder StmtBldr(PreVisit, Dst, *currBldrCtx); 727176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines for (ExplodedNode *Node : PreVisit) { 728176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines ProgramStateRef State = Node->getState(); 729176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 730176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (!State->contains<InitializedTemporariesSet>( 731176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines std::make_pair(BTE, Node->getStackFrame()))) { 732176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // FIXME: Currently the state might already contain the marker due to 733176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // incorrect handling of temporaries bound to default parameters; for 734176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // those, we currently skip the CXXBindTemporaryExpr but rely on adding 735176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // temporary destructor nodes. 736176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines State = State->add<InitializedTemporariesSet>( 737176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines std::make_pair(BTE, Node->getStackFrame())); 738176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 739176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines StmtBldr.generateNode(BTE, Node, State); 740176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 74195ab9e306f4deefeabd89ea61987f4a8d67e0890Pavel Labath} 7429c6cd67ea416bace666d614c84d5531124287653Zhongxing Xu 74348b6247804eacc262cc5508e0fbb74ed819fbb6eJordan Rosevoid ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred, 7446889679d72859960e0fc8d1080487f63c4df1e0aAnna Zaks ExplodedNodeSet &DstTop) { 7450bed8a12f2878d3cd94fb8bdba55b593d92dd11aTed Kremenek PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(), 7460bed8a12f2878d3cd94fb8bdba55b593d92dd11aTed Kremenek S->getLocStart(), 7470bed8a12f2878d3cd94fb8bdba55b593d92dd11aTed Kremenek "Error evaluating statement"); 7486889679d72859960e0fc8d1080487f63c4df1e0aAnna Zaks ExplodedNodeSet Dst; 74966c486f275531df6362b3511fc3af6563561801bTed Kremenek StmtNodeBuilder Bldr(Pred, DstTop, *currBldrCtx); 7500bed8a12f2878d3cd94fb8bdba55b593d92dd11aTed Kremenek 751e9cd031c77a92015571425b6445e8867816997cdJordan Rose assert(!isa<Expr>(S) || S == cast<Expr>(S)->IgnoreParens()); 7521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 753e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek switch (S->getStmtClass()) { 754f85e193739c953358c865005855253af4f68a497John McCall // C++ and ARC stuff we don't support yet. 755f85e193739c953358c865005855253af4f68a497John McCall case Expr::ObjCIndirectCopyRestoreExprClass: 7561b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::CXXDependentScopeMemberExprClass: 7571b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::CXXTryStmtClass: 7581b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::CXXTypeidExprClass: 7599be88403e965cc49af76c9d33d818781d44b333eFrancois Pichet case Stmt::CXXUuidofExprClass: 760176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines case Stmt::CXXFoldExprClass: 76176da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall case Stmt::MSPropertyRefExprClass: 762a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar case Stmt::MSPropertySubscriptExprClass: 763c768a0c46e6c064c3281d663777ee95aea8652eeTed Kremenek case Stmt::CXXUnresolvedConstructExprClass: 7641b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::DependentScopeDeclRefExprClass: 76521ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley case Stmt::ArrayTypeTraitExprClass: 766552622067dc45013d240f73952fece703f5e63bdJohn Wiegley case Stmt::ExpressionTraitExprClass: 7671b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::UnresolvedLookupExprClass: 768c768a0c46e6c064c3281d663777ee95aea8652eeTed Kremenek case Stmt::UnresolvedMemberExprClass: 769176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines case Stmt::TypoExprClass: 7706b219d082434394c1ac401390ec1d1967727815aSebastian Redl case Stmt::CXXNoexceptExprClass: 771be230c36e32142cbdcdbe9c97511d097beeecbabDouglas Gregor case Stmt::PackExpansionExprClass: 772c7793c73ba8a343de3f2552d984851985a46f159Douglas Gregor case Stmt::SubstNonTypeTemplateParmPackExprClass: 7739a4db032ecd991626d236a502e770126db32bd31Richard Smith case Stmt::FunctionParmPackExprClass: 774a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar case Stmt::CoroutineBodyStmtClass: 775a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar case Stmt::CoawaitExprClass: 776a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar case Stmt::CoreturnStmtClass: 777a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar case Stmt::CoyieldExprClass: 77828bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley case Stmt::SEHTryStmtClass: 77928bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley case Stmt::SEHExceptStmtClass: 780c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case Stmt::SEHLeaveStmtClass: 781ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks case Stmt::SEHFinallyStmtClass: { 782fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose const ExplodedNode *node = Bldr.generateSink(S, Pred, Pred->getState()); 78366c486f275531df6362b3511fc3af6563561801bTed Kremenek Engine.addAbortedBlock(node, currBldrCtx->getBlock()); 784c768a0c46e6c064c3281d663777ee95aea8652eeTed Kremenek break; 785c768a0c46e6c064c3281d663777ee95aea8652eeTed Kremenek } 786a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 787f6a1648197562e0b133440d612d9af297d0a86ccJohn McCall case Stmt::ParenExprClass: 788f6a1648197562e0b133440d612d9af297d0a86ccJohn McCall llvm_unreachable("ParenExprs already handled."); 789f111d935722ed488144600cea5ed03a6b5069e8fPeter Collingbourne case Stmt::GenericSelectionExprClass: 790f111d935722ed488144600cea5ed03a6b5069e8fPeter Collingbourne llvm_unreachable("GenericSelectionExprs already handled."); 7911b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek // Cases that should never be evaluated simply because they shouldn't 7921b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek // appear in the CFG. 7931b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::BreakStmtClass: 7941b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::CaseStmtClass: 7951b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::CompoundStmtClass: 7961b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::ContinueStmtClass: 79746eaf7789a1059a7b42b7dbd183150c72df5738fTed Kremenek case Stmt::CXXForRangeStmtClass: 7981b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::DefaultStmtClass: 7991b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::DoStmtClass: 800d40066b0fb883839a9100e5455e33190b9b8abacTed Kremenek case Stmt::ForStmtClass: 8011b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::GotoStmtClass: 802d40066b0fb883839a9100e5455e33190b9b8abacTed Kremenek case Stmt::IfStmtClass: 8031b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::IndirectGotoStmtClass: 8041b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::LabelStmtClass: 8051b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::NoStmtClass: 8061b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::NullStmtClass: 807d40066b0fb883839a9100e5455e33190b9b8abacTed Kremenek case Stmt::SwitchStmtClass: 808d40066b0fb883839a9100e5455e33190b9b8abacTed Kremenek case Stmt::WhileStmtClass: 809ba0513de93d2fab6db5ab30b6927209fcc883078Douglas Gregor case Expr::MSDependentExistsStmtClass: 810051303ce09291dfbed537fa33b0d8a4d92c82b75Tareq A. Siraj case Stmt::CapturedStmtClass: 8114fa7eab771ab8212e1058bd1a91061ff120c8fbbAlexey Bataev case Stmt::OMPParallelDirectiveClass: 812651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines case Stmt::OMPSimdDirectiveClass: 813c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case Stmt::OMPForDirectiveClass: 814176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines case Stmt::OMPForSimdDirectiveClass: 815c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case Stmt::OMPSectionsDirectiveClass: 816c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case Stmt::OMPSectionDirectiveClass: 817c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case Stmt::OMPSingleDirectiveClass: 818176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines case Stmt::OMPMasterDirectiveClass: 819176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines case Stmt::OMPCriticalDirectiveClass: 820c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case Stmt::OMPParallelForDirectiveClass: 821176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines case Stmt::OMPParallelForSimdDirectiveClass: 822c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines case Stmt::OMPParallelSectionsDirectiveClass: 823176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines case Stmt::OMPTaskDirectiveClass: 824176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines case Stmt::OMPTaskyieldDirectiveClass: 825176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines case Stmt::OMPBarrierDirectiveClass: 826176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines case Stmt::OMPTaskwaitDirectiveClass: 827a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar case Stmt::OMPTaskgroupDirectiveClass: 828176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines case Stmt::OMPFlushDirectiveClass: 829176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines case Stmt::OMPOrderedDirectiveClass: 830176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines case Stmt::OMPAtomicDirectiveClass: 831176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines case Stmt::OMPTargetDirectiveClass: 832a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar case Stmt::OMPTargetDataDirectiveClass: 833176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines case Stmt::OMPTeamsDirectiveClass: 834a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar case Stmt::OMPCancellationPointDirectiveClass: 835a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar case Stmt::OMPCancelDirectiveClass: 836a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar case Stmt::OMPTaskLoopDirectiveClass: 837a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar case Stmt::OMPTaskLoopSimdDirectiveClass: 838a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar case Stmt::OMPDistributeDirectiveClass: 8391b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek llvm_unreachable("Stmt should not be in analyzer evaluation loop"); 8401b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek 8414ccc4cc5d4e7c5c436d5f45065d3639cfc7c6e48Jordan Rose case Stmt::ObjCSubscriptRefExprClass: 8424ccc4cc5d4e7c5c436d5f45065d3639cfc7c6e48Jordan Rose case Stmt::ObjCPropertyRefExprClass: 8434ccc4cc5d4e7c5c436d5f45065d3639cfc7c6e48Jordan Rose llvm_unreachable("These are handled by PseudoObjectExpr"); 8444ccc4cc5d4e7c5c436d5f45065d3639cfc7c6e48Jordan Rose 8458ad9cbc518a603176462f1fa1efe389023590082Ted Kremenek case Stmt::GNUNullExprClass: { 8468f08426e6f54ed20b959018f24dbea106a00b4adJordy Rose // GNU __null is a pointer-width integer, not an actual pointer. 8478bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek ProgramStateRef state = Pred->getState(); 8485eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek state = state->BindExpr(S, Pred->getLocationContext(), 8495eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek svalBuilder.makeIntValWithPtrWidth(0, false)); 850ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.generateNode(S, Pred, state); 8518ad9cbc518a603176462f1fa1efe389023590082Ted Kremenek break; 8528ad9cbc518a603176462f1fa1efe389023590082Ted Kremenek } 8538ad9cbc518a603176462f1fa1efe389023590082Ted Kremenek 8544beaa9f51b2da57c64740cef2bd1c2fdb0c325d5Ted Kremenek case Stmt::ObjCAtSynchronizedStmtClass: 855ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 8564beaa9f51b2da57c64740cef2bd1c2fdb0c325d5Ted Kremenek VisitObjCAtSynchronizedStmt(cast<ObjCAtSynchronizedStmt>(S), Pred, Dst); 857ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 8584beaa9f51b2da57c64740cef2bd1c2fdb0c325d5Ted Kremenek break; 8594beaa9f51b2da57c64740cef2bd1c2fdb0c325d5Ted Kremenek 860ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks case Stmt::ExprWithCleanupsClass: 861e711d7e7875920fee4180a26bfc67d67f0f71a2cErik Verbruggen // Handled due to fully linearised CFG. 862f85e193739c953358c865005855253af4f68a497John McCall break; 863f85e193739c953358c865005855253af4f68a497John McCall 864176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines case Stmt::CXXBindTemporaryExprClass: { 865176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines Bldr.takeNodes(Pred); 866176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines ExplodedNodeSet PreVisit; 867176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines getCheckerManager().runCheckersForPreStmt(PreVisit, Pred, S, *this); 868176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines ExplodedNodeSet Next; 869176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines VisitCXXBindTemporaryExpr(cast<CXXBindTemporaryExpr>(S), PreVisit, Next); 870176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines getCheckerManager().runCheckersForPostStmt(Dst, Next, S, *this); 871176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines Bldr.addNodes(Dst); 872176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines break; 873176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 874176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 8751b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek // Cases not handled yet; but will handle some day. 8761b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::DesignatedInitExprClass: 877b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar case Stmt::DesignatedInitUpdateExprClass: 8781b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::ExtVectorElementExprClass: 8791b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::ImaginaryLiteralClass: 8801b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::ObjCAtCatchStmtClass: 8811b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::ObjCAtFinallyStmtClass: 8821b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::ObjCAtTryStmtClass: 883f85e193739c953358c865005855253af4f68a497John McCall case Stmt::ObjCAutoreleasePoolStmtClass: 8841b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::ObjCEncodeExprClass: 8851b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::ObjCIsaExprClass: 8861b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::ObjCProtocolExprClass: 8871b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::ObjCSelectorExprClass: 8881b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::ParenListExprClass: 8891b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::ShuffleVectorExprClass: 890414a1bdbdaf250e0488589f12865c8961831b65dHal Finkel case Stmt::ConvertVectorExprClass: 8911b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek case Stmt::VAArgExprClass: 892e08ce650a2b02410eddd1f60a4aa6b3d4be71e73Peter Collingbourne case Stmt::CUDAKernelCallExprClass: 89356ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall case Stmt::OpaqueValueExprClass: 89461eee0ca33b29e102f11bab77c8b74cc00e2392bTanya Lattner case Stmt::AsTypeExprClass: 895276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman case Stmt::AtomicExprClass: 896337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek // Fall through. 8971b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek 8981b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek // Cases we intentionally don't evaluate, since they don't need 8991b49d762e9658b6b6d1b677dca005324a7b1126dTed Kremenek // to be explicitly evaluated. 900176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines case Stmt::PredefinedExprClass: 901bc9ad74a13e83303a3a5251f8bacbbca17341c17Zhongxing Xu case Stmt::AddrLabelExprClass: 902ed2e2de580f840385f25a188ed48d2a14948af76Pavel Labath case Stmt::AttributedStmtClass: 903bc9ad74a13e83303a3a5251f8bacbbca17341c17Zhongxing Xu case Stmt::IntegerLiteralClass: 904bc9ad74a13e83303a3a5251f8bacbbca17341c17Zhongxing Xu case Stmt::CharacterLiteralClass: 905c319c585c0d5899cba0dca2272e6e4909c8b9f16Ted Kremenek case Stmt::ImplicitValueInitExprClass: 906c319c585c0d5899cba0dca2272e6e4909c8b9f16Ted Kremenek case Stmt::CXXScalarValueInitExprClass: 907477323d58a0de352c6a61e08b5a83127c4adc904Zhongxing Xu case Stmt::CXXBoolLiteralExprClass: 9081a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek case Stmt::ObjCBoolLiteralExprClass: 909bc9ad74a13e83303a3a5251f8bacbbca17341c17Zhongxing Xu case Stmt::FloatingLiteralClass: 910b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar case Stmt::NoInitExprClass: 911f901a7de97f46ba2b1ff153f9fb83d00dc37cfcfDouglas Gregor case Stmt::SizeOfPackExprClass: 912e739a29c62c67eaec0af5c4d5c75f9e8f11228bdTed Kremenek case Stmt::StringLiteralClass: 913e739a29c62c67eaec0af5c4d5c75f9e8f11228bdTed Kremenek case Stmt::ObjCStringLiteralClass: 914fee16225a103ee1459af4f3ecb89fa2804e81ac3Jordan Rose case Stmt::CXXPseudoDestructorExprClass: 91569a0e5021c5c49a34aa25cd89b1e613a52097e65Jordan Rose case Stmt::SubstNonTypeTemplateParmExprClass: 916a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar case Stmt::CXXNullPtrLiteralExprClass: 917a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar case Stmt::OMPArraySectionExprClass: 918a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar case Stmt::TypeTraitExprClass: { 919bdd4c848349d4091d66b052efa453e6d69a77e36Ted Kremenek Bldr.takeNodes(Pred); 920bdd4c848349d4091d66b052efa453e6d69a77e36Ted Kremenek ExplodedNodeSet preVisit; 921bdd4c848349d4091d66b052efa453e6d69a77e36Ted Kremenek getCheckerManager().runCheckersForPreStmt(preVisit, Pred, S, *this); 922bdd4c848349d4091d66b052efa453e6d69a77e36Ted Kremenek getCheckerManager().runCheckersForPostStmt(Dst, preVisit, S, *this); 923bdd4c848349d4091d66b052efa453e6d69a77e36Ted Kremenek Bldr.addNodes(Dst); 924e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek break; 925bdd4c848349d4091d66b052efa453e6d69a77e36Ted Kremenek } 9261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 927bccda13aa3fc2a4c674a8c0a7003a7e6b1ff17b0Jordan Rose case Stmt::CXXDefaultArgExprClass: 928bccda13aa3fc2a4c674a8c0a7003a7e6b1ff17b0Jordan Rose case Stmt::CXXDefaultInitExprClass: { 92938f68ef19cb51d5876e9025b5fceb44b33ec9ed7Jordan Rose Bldr.takeNodes(Pred); 93038f68ef19cb51d5876e9025b5fceb44b33ec9ed7Jordan Rose ExplodedNodeSet PreVisit; 93138f68ef19cb51d5876e9025b5fceb44b33ec9ed7Jordan Rose getCheckerManager().runCheckersForPreStmt(PreVisit, Pred, S, *this); 93238f68ef19cb51d5876e9025b5fceb44b33ec9ed7Jordan Rose 93338f68ef19cb51d5876e9025b5fceb44b33ec9ed7Jordan Rose ExplodedNodeSet Tmp; 93438f68ef19cb51d5876e9025b5fceb44b33ec9ed7Jordan Rose StmtNodeBuilder Bldr2(PreVisit, Tmp, *currBldrCtx); 93538f68ef19cb51d5876e9025b5fceb44b33ec9ed7Jordan Rose 936bccda13aa3fc2a4c674a8c0a7003a7e6b1ff17b0Jordan Rose const Expr *ArgE; 937bccda13aa3fc2a4c674a8c0a7003a7e6b1ff17b0Jordan Rose if (const CXXDefaultArgExpr *DefE = dyn_cast<CXXDefaultArgExpr>(S)) 938bccda13aa3fc2a4c674a8c0a7003a7e6b1ff17b0Jordan Rose ArgE = DefE->getExpr(); 939bccda13aa3fc2a4c674a8c0a7003a7e6b1ff17b0Jordan Rose else if (const CXXDefaultInitExpr *DefE = dyn_cast<CXXDefaultInitExpr>(S)) 940bccda13aa3fc2a4c674a8c0a7003a7e6b1ff17b0Jordan Rose ArgE = DefE->getExpr(); 941bccda13aa3fc2a4c674a8c0a7003a7e6b1ff17b0Jordan Rose else 942bccda13aa3fc2a4c674a8c0a7003a7e6b1ff17b0Jordan Rose llvm_unreachable("unknown constant wrapper kind"); 94338f68ef19cb51d5876e9025b5fceb44b33ec9ed7Jordan Rose 9444b75085f5669efc6407c662b5686361624c3ff2fJordan Rose bool IsTemporary = false; 9454b75085f5669efc6407c662b5686361624c3ff2fJordan Rose if (const MaterializeTemporaryExpr *MTE = 9464b75085f5669efc6407c662b5686361624c3ff2fJordan Rose dyn_cast<MaterializeTemporaryExpr>(ArgE)) { 9474b75085f5669efc6407c662b5686361624c3ff2fJordan Rose ArgE = MTE->GetTemporaryExpr(); 9484b75085f5669efc6407c662b5686361624c3ff2fJordan Rose IsTemporary = true; 9494b75085f5669efc6407c662b5686361624c3ff2fJordan Rose } 9504b75085f5669efc6407c662b5686361624c3ff2fJordan Rose 951e2b1246a24e8babf2f58c93713fba16b8edb8e2dJordan Rose Optional<SVal> ConstantVal = svalBuilder.getConstantVal(ArgE); 952e2b1246a24e8babf2f58c93713fba16b8edb8e2dJordan Rose if (!ConstantVal) 953e2b1246a24e8babf2f58c93713fba16b8edb8e2dJordan Rose ConstantVal = UnknownVal(); 95438f68ef19cb51d5876e9025b5fceb44b33ec9ed7Jordan Rose 955bccda13aa3fc2a4c674a8c0a7003a7e6b1ff17b0Jordan Rose const LocationContext *LCtx = Pred->getLocationContext(); 95638f68ef19cb51d5876e9025b5fceb44b33ec9ed7Jordan Rose for (ExplodedNodeSet::iterator I = PreVisit.begin(), E = PreVisit.end(); 95738f68ef19cb51d5876e9025b5fceb44b33ec9ed7Jordan Rose I != E; ++I) { 95838f68ef19cb51d5876e9025b5fceb44b33ec9ed7Jordan Rose ProgramStateRef State = (*I)->getState(); 959bccda13aa3fc2a4c674a8c0a7003a7e6b1ff17b0Jordan Rose State = State->BindExpr(S, LCtx, *ConstantVal); 9604b75085f5669efc6407c662b5686361624c3ff2fJordan Rose if (IsTemporary) 961bccda13aa3fc2a4c674a8c0a7003a7e6b1ff17b0Jordan Rose State = createTemporaryRegionIfNeeded(State, LCtx, 962bccda13aa3fc2a4c674a8c0a7003a7e6b1ff17b0Jordan Rose cast<Expr>(S), 963bccda13aa3fc2a4c674a8c0a7003a7e6b1ff17b0Jordan Rose cast<Expr>(S)); 96438f68ef19cb51d5876e9025b5fceb44b33ec9ed7Jordan Rose Bldr2.generateNode(S, *I, State); 96538f68ef19cb51d5876e9025b5fceb44b33ec9ed7Jordan Rose } 96638f68ef19cb51d5876e9025b5fceb44b33ec9ed7Jordan Rose 96738f68ef19cb51d5876e9025b5fceb44b33ec9ed7Jordan Rose getCheckerManager().runCheckersForPostStmt(Dst, Tmp, S, *this); 96838f68ef19cb51d5876e9025b5fceb44b33ec9ed7Jordan Rose Bldr.addNodes(Dst); 96938f68ef19cb51d5876e9025b5fceb44b33ec9ed7Jordan Rose break; 97038f68ef19cb51d5876e9025b5fceb44b33ec9ed7Jordan Rose } 97138f68ef19cb51d5876e9025b5fceb44b33ec9ed7Jordan Rose 972be2e1b11e3350e3a6e632c71beaab83aae3824d2Jordan Rose // Cases we evaluate as opaque expressions, conjuring a symbol. 973be2e1b11e3350e3a6e632c71beaab83aae3824d2Jordan Rose case Stmt::CXXStdInitializerListExprClass: 9741a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek case Expr::ObjCArrayLiteralClass: 97570fdbc366da85880aae5baebd3351e993ca05603Jordy Rose case Expr::ObjCDictionaryLiteralClass: 97670fdbc366da85880aae5baebd3351e993ca05603Jordy Rose case Expr::ObjCBoxedExprClass: { 9771a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek Bldr.takeNodes(Pred); 9781a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek 9791a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek ExplodedNodeSet preVisit; 9801a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek getCheckerManager().runCheckersForPreStmt(preVisit, Pred, S, *this); 981a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 9821a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek ExplodedNodeSet Tmp; 98366c486f275531df6362b3511fc3af6563561801bTed Kremenek StmtNodeBuilder Bldr2(preVisit, Tmp, *currBldrCtx); 9841a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek 98570fdbc366da85880aae5baebd3351e993ca05603Jordy Rose const Expr *Ex = cast<Expr>(S); 98670fdbc366da85880aae5baebd3351e993ca05603Jordy Rose QualType resultType = Ex->getType(); 98770fdbc366da85880aae5baebd3351e993ca05603Jordy Rose 9881a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek for (ExplodedNodeSet::iterator it = preVisit.begin(), et = preVisit.end(); 989a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar it != et; ++it) { 9901a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek ExplodedNode *N = *it; 9911a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek const LocationContext *LCtx = N->getLocationContext(); 9926bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SVal result = svalBuilder.conjureSymbolVal(nullptr, Ex, LCtx, 9936bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines resultType, 99466c486f275531df6362b3511fc3af6563561801bTed Kremenek currBldrCtx->blockCount()); 9951a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek ProgramStateRef state = N->getState()->BindExpr(Ex, LCtx, result); 9961a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek Bldr2.generateNode(S, N, state); 9971a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek } 998a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 9991a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek getCheckerManager().runCheckersForPostStmt(Dst, Tmp, S, *this); 10001a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek Bldr.addNodes(Dst); 1001a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar break; 10021a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek } 10031a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek 1004540cbe2b60294fe7b926c26b4f1840f544fe3011Ted Kremenek case Stmt::ArraySubscriptExprClass: 1005ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 1006892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek VisitLvalArraySubscriptExpr(cast<ArraySubscriptExpr>(S), Pred, Dst); 1007ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 1008540cbe2b60294fe7b926c26b4f1840f544fe3011Ted Kremenek break; 10091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1010df5faf5e7ae6823d0af0b801c4ac26d47f2cee97Chad Rosier case Stmt::GCCAsmStmtClass: 1011ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 1012df5faf5e7ae6823d0af0b801c4ac26d47f2cee97Chad Rosier VisitGCCAsmStmt(cast<GCCAsmStmt>(S), Pred, Dst); 1013ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 1014e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek break; 1015b9bbd592c7ea72ada8d982e40a729beb9b53371eTed Kremenek 10168cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier case Stmt::MSAsmStmtClass: 10178cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier Bldr.takeNodes(Pred); 10188cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier VisitMSAsmStmt(cast<MSAsmStmt>(S), Pred, Dst); 10198cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier Bldr.addNodes(Dst); 10208cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier break; 10218cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier 1022c95ad9ff6e574aecdd759542d5578bc65d586d93Ted Kremenek case Stmt::BlockExprClass: 1023ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 1024c95ad9ff6e574aecdd759542d5578bc65d586d93Ted Kremenek VisitBlockExpr(cast<BlockExpr>(S), Pred, Dst); 1025ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 1026c95ad9ff6e574aecdd759542d5578bc65d586d93Ted Kremenek break; 1027c95ad9ff6e574aecdd759542d5578bc65d586d93Ted Kremenek 1028a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar case Stmt::LambdaExprClass: 1029a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar if (AMgr.options.shouldInlineLambdas()) { 1030a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar Bldr.takeNodes(Pred); 1031a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar VisitLambdaExpr(cast<LambdaExpr>(S), Pred, Dst); 1032a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar Bldr.addNodes(Dst); 1033a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar } else { 1034a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar const ExplodedNode *node = Bldr.generateSink(S, Pred, Pred->getState()); 1035a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar Engine.addAbortedBlock(node, currBldrCtx->getBlock()); 1036a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar } 1037a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar break; 1038a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 1039e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek case Stmt::BinaryOperatorClass: { 104003509aea098772644bf4662dc1c88634818ceeccZhongxing Xu const BinaryOperator* B = cast<BinaryOperator>(S); 1041e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek if (B->isLogicalOp()) { 1042ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 1043e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek VisitLogicalExpr(B, Pred, Dst); 1044ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 1045e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek break; 1046e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek } 10472de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall else if (B->getOpcode() == BO_Comma) { 10488bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek ProgramStateRef state = Pred->getState(); 1049ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.generateNode(B, Pred, 10505eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek state->BindExpr(B, Pred->getLocationContext(), 10515eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek state->getSVal(B->getRHS(), 10525eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek Pred->getLocationContext()))); 1053e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek break; 1054e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek } 105506fb99fb403bff1651429923f666a2ebe2b1522fTed Kremenek 1056ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 1057a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 10580caa2d47b84337e942b3f6652adfafe4ae506cfeTed Kremenek if (AMgr.options.eagerlyAssumeBinOpBifurcation && 1059bb141217871e93767aa3f2de1b9946fa6d37066aZhongxing Xu (B->isRelationalOp() || B->isEqualityOp())) { 1060031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu ExplodedNodeSet Tmp; 1061892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Tmp); 10620caa2d47b84337e942b3f6652adfafe4ae506cfeTed Kremenek evalEagerlyAssumeBinOpBifurcation(Dst, Tmp, cast<Expr>(S)); 106348af2a9c1ed3259512f2d1431720add1fbe8fb5fTed Kremenek } 106448af2a9c1ed3259512f2d1431720add1fbe8fb5fTed Kremenek else 1065892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Dst); 106648af2a9c1ed3259512f2d1431720add1fbe8fb5fTed Kremenek 1067ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 1068e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek break; 1069e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek } 107006fb99fb403bff1651429923f666a2ebe2b1522fTed Kremenek 1071f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose case Stmt::CXXOperatorCallExprClass: { 1072f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose const CXXOperatorCallExpr *OCE = cast<CXXOperatorCallExpr>(S); 1073f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose 1074f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose // For instance method operators, make sure the 'this' argument has a 1075f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose // valid region. 1076f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose const Decl *Callee = OCE->getCalleeDecl(); 1077f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose if (const CXXMethodDecl *MD = dyn_cast_or_null<CXXMethodDecl>(Callee)) { 1078f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose if (MD->isInstance()) { 1079f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose ProgramStateRef State = Pred->getState(); 1080f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose const LocationContext *LCtx = Pred->getLocationContext(); 1081f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose ProgramStateRef NewState = 1082f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose createTemporaryRegionIfNeeded(State, LCtx, OCE->getArg(0)); 1083476f41c4750421a7ead5014e75a0e790ff682754Jordan Rose if (NewState != State) { 10846bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Pred = Bldr.generateNode(OCE, Pred, NewState, /*Tag=*/nullptr, 1085f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose ProgramPoint::PreStmtKind); 1086476f41c4750421a7ead5014e75a0e790ff682754Jordan Rose // Did we cache out? 1087476f41c4750421a7ead5014e75a0e790ff682754Jordan Rose if (!Pred) 1088476f41c4750421a7ead5014e75a0e790ff682754Jordan Rose break; 1089476f41c4750421a7ead5014e75a0e790ff682754Jordan Rose } 1090f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose } 1091f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose } 1092f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose // FALLTHROUGH 1093f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose } 1094b277159055933e610bbc80262b600d3ad7e0595cTed Kremenek case Stmt::CallExprClass: 10959fcce65e7e1307b5b8da9be13e4092d6bb94dc1dRichard Smith case Stmt::CXXMemberCallExprClass: 10969fcce65e7e1307b5b8da9be13e4092d6bb94dc1dRichard Smith case Stmt::UserDefinedLiteralClass: { 1097ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 1098b277159055933e610bbc80262b600d3ad7e0595cTed Kremenek VisitCallExpr(cast<CallExpr>(S), Pred, Dst); 1099ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 110006fb99fb403bff1651429923f666a2ebe2b1522fTed Kremenek break; 1101e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek } 1102a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 1103337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek case Stmt::CXXCatchStmtClass: { 1104337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek Bldr.takeNodes(Pred); 1105337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek VisitCXXCatchStmt(cast<CXXCatchStmt>(S), Pred, Dst); 1106337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek Bldr.addNodes(Dst); 1107337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek break; 1108337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek } 110906fb99fb403bff1651429923f666a2ebe2b1522fTed Kremenek 1110744f1cd66bb6747ea71fbf1172698e7bf35ec88dTed Kremenek case Stmt::CXXTemporaryObjectExprClass: 1111a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar case Stmt::CXXConstructExprClass: { 1112ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 1113888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose VisitCXXConstructExpr(cast<CXXConstructExpr>(S), Pred, Dst); 1114ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 11157ce351db56fbce162a3b650518ce05b5c61ebf36Zhongxing Xu break; 11167ce351db56fbce162a3b650518ce05b5c61ebf36Zhongxing Xu } 11177ce351db56fbce162a3b650518ce05b5c61ebf36Zhongxing Xu 1118d74324371465a152387ac45e737ab7d23e543552Anton Yartsev case Stmt::CXXNewExprClass: { 1119d74324371465a152387ac45e737ab7d23e543552Anton Yartsev Bldr.takeNodes(Pred); 1120d74324371465a152387ac45e737ab7d23e543552Anton Yartsev ExplodedNodeSet PostVisit; 1121d74324371465a152387ac45e737ab7d23e543552Anton Yartsev VisitCXXNewExpr(cast<CXXNewExpr>(S), Pred, PostVisit); 1122d74324371465a152387ac45e737ab7d23e543552Anton Yartsev getCheckerManager().runCheckersForPostStmt(Dst, PostVisit, S, *this); 1123d74324371465a152387ac45e737ab7d23e543552Anton Yartsev Bldr.addNodes(Dst); 1124d74324371465a152387ac45e737ab7d23e543552Anton Yartsev break; 1125d74324371465a152387ac45e737ab7d23e543552Anton Yartsev } 1126d74324371465a152387ac45e737ab7d23e543552Anton Yartsev 1127d74324371465a152387ac45e737ab7d23e543552Anton Yartsev case Stmt::CXXDeleteExprClass: { 1128d74324371465a152387ac45e737ab7d23e543552Anton Yartsev Bldr.takeNodes(Pred); 1129d74324371465a152387ac45e737ab7d23e543552Anton Yartsev ExplodedNodeSet PreVisit; 1130d74324371465a152387ac45e737ab7d23e543552Anton Yartsev const CXXDeleteExpr *CDE = cast<CXXDeleteExpr>(S); 1131d74324371465a152387ac45e737ab7d23e543552Anton Yartsev getCheckerManager().runCheckersForPreStmt(PreVisit, Pred, S, *this); 1132d74324371465a152387ac45e737ab7d23e543552Anton Yartsev 1133a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar for (ExplodedNodeSet::iterator i = PreVisit.begin(), 1134d74324371465a152387ac45e737ab7d23e543552Anton Yartsev e = PreVisit.end(); i != e ; ++i) 1135d74324371465a152387ac45e737ab7d23e543552Anton Yartsev VisitCXXDeleteExpr(CDE, *i, Dst); 1136d74324371465a152387ac45e737ab7d23e543552Anton Yartsev 1137d74324371465a152387ac45e737ab7d23e543552Anton Yartsev Bldr.addNodes(Dst); 1138d74324371465a152387ac45e737ab7d23e543552Anton Yartsev break; 1139d74324371465a152387ac45e737ab7d23e543552Anton Yartsev } 1140e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek // FIXME: ChooseExpr is really a constant. We need to fix 1141e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek // the CFG do not model them as explicit control-flow. 11421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1143e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek case Stmt::ChooseExprClass: { // __builtin_choose_expr 1144ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 11459c378f705405d37f49795d5e915989de774fe11fTed Kremenek const ChooseExpr *C = cast<ChooseExpr>(S); 1146e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek VisitGuardedExpr(C, C->getLHS(), C->getRHS(), Pred, Dst); 1147ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 1148e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek break; 1149e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek } 11501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1151e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek case Stmt::CompoundAssignOperatorClass: 1152ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 1153892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Dst); 1154ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 1155e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek break; 1156f22679e3e5d5f5754931952e58112b4c863a4137Zhongxing Xu 1157f22679e3e5d5f5754931952e58112b4c863a4137Zhongxing Xu case Stmt::CompoundLiteralExprClass: 1158ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 1159892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek VisitCompoundLiteralExpr(cast<CompoundLiteralExpr>(S), Pred, Dst); 1160ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 1161f22679e3e5d5f5754931952e58112b4c863a4137Zhongxing Xu break; 11621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 116356ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall case Stmt::BinaryConditionalOperatorClass: 1164e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek case Stmt::ConditionalOperatorClass: { // '?' operator 1165ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 116656ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall const AbstractConditionalOperator *C 116756ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall = cast<AbstractConditionalOperator>(S); 116856ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall VisitGuardedExpr(C, C->getTrueExpr(), C->getFalseExpr(), Pred, Dst); 1169ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 1170e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek break; 1171e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek } 11721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1173bb141217871e93767aa3f2de1b9946fa6d37066aZhongxing Xu case Stmt::CXXThisExprClass: 1174ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 1175bb141217871e93767aa3f2de1b9946fa6d37066aZhongxing Xu VisitCXXThisExpr(cast<CXXThisExpr>(S), Pred, Dst); 1176ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 1177bb141217871e93767aa3f2de1b9946fa6d37066aZhongxing Xu break; 1178bb141217871e93767aa3f2de1b9946fa6d37066aZhongxing Xu 1179892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek case Stmt::DeclRefExprClass: { 1180ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 1181892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek const DeclRefExpr *DE = cast<DeclRefExpr>(S); 1182892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek VisitCommonDeclRefExpr(DE, DE->getDecl(), Pred, Dst); 1183ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 1184e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek break; 1185892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek } 11861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1187e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek case Stmt::DeclStmtClass: 1188ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 1189e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek VisitDeclStmt(cast<DeclStmt>(S), Pred, Dst); 1190ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 1191e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek break; 11921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 11930835a3cdeefe714b4959d31127ea155e56393125Argyrios Kyrtzidis case Stmt::ImplicitCastExprClass: 11940d9d736c49b51691ced96759ec99399824e2a602Zhongxing Xu case Stmt::CStyleCastExprClass: 11950d9d736c49b51691ced96759ec99399824e2a602Zhongxing Xu case Stmt::CXXStaticCastExprClass: 11960d9d736c49b51691ced96759ec99399824e2a602Zhongxing Xu case Stmt::CXXDynamicCastExprClass: 11970d9d736c49b51691ced96759ec99399824e2a602Zhongxing Xu case Stmt::CXXReinterpretCastExprClass: 11980d9d736c49b51691ced96759ec99399824e2a602Zhongxing Xu case Stmt::CXXConstCastExprClass: 1199a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar case Stmt::CXXFunctionalCastExprClass: 1200f85e193739c953358c865005855253af4f68a497John McCall case Stmt::ObjCBridgedCastExprClass: { 1201ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 12029c378f705405d37f49795d5e915989de774fe11fTed Kremenek const CastExpr *C = cast<CastExpr>(S); 1203f85e193739c953358c865005855253af4f68a497John McCall // Handle the previsit checks. 1204f85e193739c953358c865005855253af4f68a497John McCall ExplodedNodeSet dstPrevisit; 1205f85e193739c953358c865005855253af4f68a497John McCall getCheckerManager().runCheckersForPreStmt(dstPrevisit, Pred, C, *this); 1206a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 1207f85e193739c953358c865005855253af4f68a497John McCall // Handle the expression itself. 1208f85e193739c953358c865005855253af4f68a497John McCall ExplodedNodeSet dstExpr; 1209f85e193739c953358c865005855253af4f68a497John McCall for (ExplodedNodeSet::iterator i = dstPrevisit.begin(), 1210a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar e = dstPrevisit.end(); i != e ; ++i) { 1211f85e193739c953358c865005855253af4f68a497John McCall VisitCast(C, C->getSubExpr(), *i, dstExpr); 1212f85e193739c953358c865005855253af4f68a497John McCall } 1213f85e193739c953358c865005855253af4f68a497John McCall 1214f85e193739c953358c865005855253af4f68a497John McCall // Handle the postvisit checks. 1215f85e193739c953358c865005855253af4f68a497John McCall getCheckerManager().runCheckersForPostStmt(Dst, dstExpr, C, *this); 1216ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 1217e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek break; 1218e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek } 1219b9bbd592c7ea72ada8d982e40a729beb9b53371eTed Kremenek 122003e80030515c800d1ab44125b9052dfffd1bd04cDouglas Gregor case Expr::MaterializeTemporaryExprClass: { 1221ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 1222c210cb7a358d14cdd93b58562f33ff5ed2d895c1Jordan Rose const MaterializeTemporaryExpr *MTE = cast<MaterializeTemporaryExpr>(S); 1223c210cb7a358d14cdd93b58562f33ff5ed2d895c1Jordan Rose CreateCXXTemporaryObject(MTE, Pred, Dst); 1224ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 122503e80030515c800d1ab44125b9052dfffd1bd04cDouglas Gregor break; 122603e80030515c800d1ab44125b9052dfffd1bd04cDouglas Gregor } 1227a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 1228c4f8706b6539e06a5de153bd72850bb2e0a71456Zhongxing Xu case Stmt::InitListExprClass: 1229ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 1230c4f8706b6539e06a5de153bd72850bb2e0a71456Zhongxing Xu VisitInitListExpr(cast<InitListExpr>(S), Pred, Dst); 1231ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 1232c4f8706b6539e06a5de153bd72850bb2e0a71456Zhongxing Xu break; 12331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 123497ed4f68f5dba3e21e7a490ef0f9ffd3bfead7f8Ted Kremenek case Stmt::MemberExprClass: 1235ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 1236892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek VisitMemberExpr(cast<MemberExpr>(S), Pred, Dst); 1237ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 1238469ecbded3616416ef938ed94a67f86149faf226Ted Kremenek break; 1239ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks 124097ed4f68f5dba3e21e7a490ef0f9ffd3bfead7f8Ted Kremenek case Stmt::ObjCIvarRefExprClass: 1241ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 1242892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek VisitLvalObjCIvarRefExpr(cast<ObjCIvarRefExpr>(S), Pred, Dst); 1243ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 124497ed4f68f5dba3e21e7a490ef0f9ffd3bfead7f8Ted Kremenek break; 1245af3374187c47acea45706eab6744be6b1c66a856Ted Kremenek 1246af3374187c47acea45706eab6744be6b1c66a856Ted Kremenek case Stmt::ObjCForCollectionStmtClass: 1247ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 1248af3374187c47acea45706eab6744be6b1c66a856Ted Kremenek VisitObjCForCollectionStmt(cast<ObjCForCollectionStmt>(S), Pred, Dst); 1249ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 1250af3374187c47acea45706eab6744be6b1c66a856Ted Kremenek break; 12511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1252d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose case Stmt::ObjCMessageExprClass: 1253ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 1254d563d3fb73879df7147b8a5302c3bf0e1402ba18Jordan Rose VisitObjCMessage(cast<ObjCMessageExpr>(S), Pred, Dst); 1255ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 1256e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek break; 12571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1258c32a453e40b2c8878fed10512fb2f570b7aba576Jordan Rose case Stmt::ObjCAtThrowStmtClass: 1259c32a453e40b2c8878fed10512fb2f570b7aba576Jordan Rose case Stmt::CXXThrowExprClass: 1260bbfd07a0c94f659beaf74316029ef73769cefb81Ted Kremenek // FIXME: This is not complete. We basically treat @throw as 1261bbfd07a0c94f659beaf74316029ef73769cefb81Ted Kremenek // an abort. 1262fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose Bldr.generateSink(S, Pred, Pred->getState()); 1263bbfd07a0c94f659beaf74316029ef73769cefb81Ted Kremenek break; 12641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 12651b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek case Stmt::ReturnStmtClass: 1266ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 12671b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek VisitReturnStmt(cast<ReturnStmt>(S), Pred, Dst); 1268ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 12691b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek break; 12701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 12718ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor case Stmt::OffsetOfExprClass: 1272ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 12738ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor VisitOffsetOfExpr(cast<OffsetOfExpr>(S), Pred, Dst); 1274ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 12758ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor break; 12768ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor 1277f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne case Stmt::UnaryExprOrTypeTraitExprClass: 1278ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 1279f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne VisitUnaryExprOrTypeTraitExpr(cast<UnaryExprOrTypeTraitExpr>(S), 1280f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne Pred, Dst); 1281ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 1282e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek break; 12831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1284e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek case Stmt::StmtExprClass: { 12859c378f705405d37f49795d5e915989de774fe11fTed Kremenek const StmtExpr *SE = cast<StmtExpr>(S); 1286a3d1eb85853eae7b719f679b40923826b5e4b7dfTed Kremenek 1287a3d1eb85853eae7b719f679b40923826b5e4b7dfTed Kremenek if (SE->getSubStmt()->body_empty()) { 1288a3d1eb85853eae7b719f679b40923826b5e4b7dfTed Kremenek // Empty statement expression. 1289a3d1eb85853eae7b719f679b40923826b5e4b7dfTed Kremenek assert(SE->getType() == getContext().VoidTy 1290a3d1eb85853eae7b719f679b40923826b5e4b7dfTed Kremenek && "Empty statement expression must have void type."); 1291a3d1eb85853eae7b719f679b40923826b5e4b7dfTed Kremenek break; 1292a3d1eb85853eae7b719f679b40923826b5e4b7dfTed Kremenek } 12931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 12949c378f705405d37f49795d5e915989de774fe11fTed Kremenek if (Expr *LastExpr = dyn_cast<Expr>(*SE->getSubStmt()->body_rbegin())) { 12958bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek ProgramStateRef state = Pred->getState(); 1296ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.generateNode(SE, Pred, 12975eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek state->BindExpr(SE, Pred->getLocationContext(), 12985eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek state->getSVal(LastExpr, 12995eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek Pred->getLocationContext()))); 1300a3d1eb85853eae7b719f679b40923826b5e4b7dfTed Kremenek } 1301e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek break; 1302e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek } 13036987c7b74146b9658b1925c5981f8b0cd0672b55Zhongxing Xu 130472374594c5d9ade02451bc85cf9dfa5b0ea106e7Ted Kremenek case Stmt::UnaryOperatorClass: { 1305ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.takeNodes(Pred); 130603509aea098772644bf4662dc1c88634818ceeccZhongxing Xu const UnaryOperator *U = cast<UnaryOperator>(S); 13070caa2d47b84337e942b3f6652adfafe4ae506cfeTed Kremenek if (AMgr.options.eagerlyAssumeBinOpBifurcation && (U->getOpcode() == UO_LNot)) { 1308031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu ExplodedNodeSet Tmp; 1309892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek VisitUnaryOperator(U, Pred, Tmp); 13100caa2d47b84337e942b3f6652adfafe4ae506cfeTed Kremenek evalEagerlyAssumeBinOpBifurcation(Dst, Tmp, U); 131172374594c5d9ade02451bc85cf9dfa5b0ea106e7Ted Kremenek } 131272374594c5d9ade02451bc85cf9dfa5b0ea106e7Ted Kremenek else 1313892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek VisitUnaryOperator(U, Pred, Dst); 1314ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks Bldr.addNodes(Dst); 13151b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek break; 131672374594c5d9ade02451bc85cf9dfa5b0ea106e7Ted Kremenek } 13174b9c2d235fb9449e249d74f48ecfec601650de93John McCall 13184b9c2d235fb9449e249d74f48ecfec601650de93John McCall case Stmt::PseudoObjectExprClass: { 13194b9c2d235fb9449e249d74f48ecfec601650de93John McCall Bldr.takeNodes(Pred); 13208bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek ProgramStateRef state = Pred->getState(); 13214b9c2d235fb9449e249d74f48ecfec601650de93John McCall const PseudoObjectExpr *PE = cast<PseudoObjectExpr>(S); 1322a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar if (const Expr *Result = PE->getResultExpr()) { 13235eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek SVal V = state->getSVal(Result, Pred->getLocationContext()); 13245eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek Bldr.generateNode(S, Pred, 13255eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek state->BindExpr(S, Pred->getLocationContext(), V)); 13264b9c2d235fb9449e249d74f48ecfec601650de93John McCall } 13274b9c2d235fb9449e249d74f48ecfec601650de93John McCall else 13285eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek Bldr.generateNode(S, Pred, 13295eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek state->BindExpr(S, Pred->getLocationContext(), 13305eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek UnknownVal())); 13314b9c2d235fb9449e249d74f48ecfec601650de93John McCall 13324b9c2d235fb9449e249d74f48ecfec601650de93John McCall Bldr.addNodes(Dst); 13334b9c2d235fb9449e249d74f48ecfec601650de93John McCall break; 13344b9c2d235fb9449e249d74f48ecfec601650de93John McCall } 13351b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek } 13361b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek} 13371b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek 13385903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaksbool ExprEngine::replayWithoutInlining(ExplodedNode *N, 13395903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks const LocationContext *CalleeLC) { 13405903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks const StackFrameContext *CalleeSF = CalleeLC->getCurrentStackFrame(); 13415903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks const StackFrameContext *CallerSF = CalleeSF->getParent()->getCurrentStackFrame(); 13425903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks assert(CalleeSF && CallerSF); 13436bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ExplodedNode *BeforeProcessingCall = nullptr; 134428038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose const Stmt *CE = CalleeSF->getCallSite(); 13455903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks 13465903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks // Find the first node before we started processing the call expression. 13475903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks while (N) { 13485903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks ProgramPoint L = N->getLocation(); 13495903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks BeforeProcessingCall = N; 13506bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines N = N->pred_empty() ? nullptr : *(N->pred_begin()); 13515903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks 13525903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks // Skip the nodes corresponding to the inlined code. 13535903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks if (L.getLocationContext()->getCurrentStackFrame() != CallerSF) 13545903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks continue; 13555903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks // We reached the caller. Find the node right before we started 135628038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose // processing the call. 13570b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks if (L.isPurgeKind()) 13585903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks continue; 13597a95de68c093991047ed8d339479ccad51b88663David Blaikie if (L.getAs<PreImplicitCall>()) 136028038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose continue; 13617a95de68c093991047ed8d339479ccad51b88663David Blaikie if (L.getAs<CallEnter>()) 1362852aa0d2c5d2d1faf2d77b5aa3c0848068a342c5Jordan Rose continue; 13637a95de68c093991047ed8d339479ccad51b88663David Blaikie if (Optional<StmtPoint> SP = L.getAs<StmtPoint>()) 136428038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose if (SP->getStmt() == CE) 13655903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks continue; 13665903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks break; 13675903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks } 13685903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks 1369253955ca25c7e7049963b5db613c0cd15d66e4f8Anna Zaks if (!BeforeProcessingCall) 13705903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks return false; 13715903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks 13725903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks // TODO: Clean up the unneeded nodes. 13735903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks 13745903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks // Build an Epsilon node from which we will restart the analyzes. 137528038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose // Note that CE is permitted to be NULL! 13765903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks ProgramPoint NewNodeLoc = 13775903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks EpsilonPoint(BeforeProcessingCall->getLocationContext(), CE); 13785903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks // Add the special flag to GDM to signal retrying with no inlining. 13795903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks // Note, changing the state ensures that we are not going to cache out. 13805903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks ProgramStateRef NewNodeState = BeforeProcessingCall->getState(); 138116303fcc569ea149dc2de38ff9e367d2d4831ceeDavid Greene NewNodeState = 138216303fcc569ea149dc2de38ff9e367d2d4831ceeDavid Greene NewNodeState->set<ReplayWithoutInlining>(const_cast<Stmt *>(CE)); 13835903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks 13845903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks // Make the new node a successor of BeforeProcessingCall. 13855903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks bool IsNew = false; 13865903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks ExplodedNode *NewNode = G.getNode(NewNodeLoc, NewNodeState, false, &IsNew); 1387253955ca25c7e7049963b5db613c0cd15d66e4f8Anna Zaks // We cached out at this point. Caching out is common due to us backtracking 1388253955ca25c7e7049963b5db613c0cd15d66e4f8Anna Zaks // from the inlined function, which might spawn several paths. 1389253955ca25c7e7049963b5db613c0cd15d66e4f8Anna Zaks if (!IsNew) 1390253955ca25c7e7049963b5db613c0cd15d66e4f8Anna Zaks return true; 1391253955ca25c7e7049963b5db613c0cd15d66e4f8Anna Zaks 13925903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks NewNode->addPredecessor(BeforeProcessingCall, G); 13935903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks 13945903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks // Add the new node to the work list. 13955903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks Engine.enqueueStmtNode(NewNode, CalleeSF->getCallSiteBlock(), 13965903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks CalleeSF->getIndex()); 13975903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks NumTimesRetriedWithoutInlining++; 13985903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks return true; 13995903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks} 14005903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks 1401c03a39e16762627b421247b12a2658be630a3300Anna Zaks/// Block entrance. (Update counters). 1402253955ca25c7e7049963b5db613c0cd15d66e4f8Anna Zaksvoid ExprEngine::processCFGBlockEntrance(const BlockEdge &L, 1403a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar NodeBuilderWithSinks &nodeBuilder, 1404b355be838a22a511d078504b2277f70aea52ca85Anna Zaks ExplodedNode *Pred) { 1405ac7cc2d37e82181e73fcc265c1d0a619d18b7605Jordan Rose PrettyStackTraceLocationContext CrashInfo(Pred->getLocationContext()); 1406ac7cc2d37e82181e73fcc265c1d0a619d18b7605Jordan Rose 1407a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar // If this block is terminated by a loop and it has already been visited the 1408a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar // maximum number of times, widen the loop. 1409a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar unsigned int BlockCount = nodeBuilder.getContext().blockCount(); 1410a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar if (BlockCount == AMgr.options.maxBlockVisitOnPath - 1 && 1411a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar AMgr.options.shouldWidenLoops()) { 1412a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar const Stmt *Term = nodeBuilder.getContext().getBlock()->getTerminator(); 1413a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar if (!(Term && 1414a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar (isa<ForStmt>(Term) || isa<WhileStmt>(Term) || isa<DoStmt>(Term)))) 1415a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar return; 1416a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar // Widen. 1417a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar const LocationContext *LCtx = Pred->getLocationContext(); 1418a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar ProgramStateRef WidenedState = 1419a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar getWidenedLoopState(Pred->getState(), LCtx, BlockCount, Term); 1420a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar nodeBuilder.generateNode(WidenedState, Pred); 1421a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar return; 1422a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar } 1423a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 142427c54e57c4a012dcdf2b40cf985b70d0b9caa69eTed Kremenek // FIXME: Refactor this into a checker. 1425a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar if (BlockCount >= AMgr.options.maxBlockVisitOnPath) { 1426651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines static SimpleProgramPointTag tag(TagProviderName, "Block count exceeded"); 1427253955ca25c7e7049963b5db613c0cd15d66e4f8Anna Zaks const ExplodedNode *Sink = 1428b355be838a22a511d078504b2277f70aea52ca85Anna Zaks nodeBuilder.generateSink(Pred->getState(), Pred, &tag); 1429749bbe6f5f23676244f12a0d41511c8e73516febAnna Zaks 1430749bbe6f5f23676244f12a0d41511c8e73516febAnna Zaks // Check if we stopped at the top level function or not. 1431749bbe6f5f23676244f12a0d41511c8e73516febAnna Zaks // Root node should have the location context of the top most function. 1432b355be838a22a511d078504b2277f70aea52ca85Anna Zaks const LocationContext *CalleeLC = Pred->getLocation().getLocationContext(); 14333bbd8cd831788c506f2980293eb3c7e1b3ca2501Anna Zaks const LocationContext *CalleeSF = CalleeLC->getCurrentStackFrame(); 14345903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks const LocationContext *RootLC = 14355903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks (*G.roots_begin())->getLocation().getLocationContext(); 14363bbd8cd831788c506f2980293eb3c7e1b3ca2501Anna Zaks if (RootLC->getCurrentStackFrame() != CalleeSF) { 1437e62f048960645b79363408fdead53fec2a063c52Anna Zaks Engine.FunctionSummaries->markReachedMaxBlockCount(CalleeSF->getDecl()); 14383bbd8cd831788c506f2980293eb3c7e1b3ca2501Anna Zaks 14395903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks // Re-run the call evaluation without inlining it, by storing the 14405903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks // no-inlining policy in the state and enqueuing the new work item on 14415903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks // the list. Replay should almost never fail. Use the stats to catch it 14425903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks // if it does. 1443255d4d4226b24036ceb11228fbb74286e58620f7Ted Kremenek if ((!AMgr.options.NoRetryExhausted && 1444b355be838a22a511d078504b2277f70aea52ca85Anna Zaks replayWithoutInlining(Pred, CalleeLC))) 1445253955ca25c7e7049963b5db613c0cd15d66e4f8Anna Zaks return; 1446253955ca25c7e7049963b5db613c0cd15d66e4f8Anna Zaks NumMaxBlockCountReachedInInlined++; 14475903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks } else 1448749bbe6f5f23676244f12a0d41511c8e73516febAnna Zaks NumMaxBlockCountReached++; 1449253955ca25c7e7049963b5db613c0cd15d66e4f8Anna Zaks 1450253955ca25c7e7049963b5db613c0cd15d66e4f8Anna Zaks // Make sink nodes as exhausted(for stats) only if retry failed. 1451253955ca25c7e7049963b5db613c0cd15d66e4f8Anna Zaks Engine.blocksExhausted.push_back(std::make_pair(L, Sink)); 145227c54e57c4a012dcdf2b40cf985b70d0b9caa69eTed Kremenek } 1453e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek} 1454e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek 1455e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek//===----------------------------------------------------------------------===// 1456e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek// Branch processing. 1457e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek//===----------------------------------------------------------------------===// 1458e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek 14596ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek/// RecoverCastedSymbol - A helper function for ProcessBranch that is used 14606ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek/// to try to recover some path-sensitivity for casts of symbolic 14616ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek/// integers that promote their values (which are currently not tracked well). 14626ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek/// This function returns the SVal bound to Condition->IgnoreCasts if all the 14636ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek// cast(s) did was sign-extend the original value. 1464294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenekstatic SVal RecoverCastedSymbol(ProgramStateManager& StateMgr, 14658bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek ProgramStateRef state, 1466294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek const Stmt *Condition, 14675eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek const LocationContext *LCtx, 1468294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek ASTContext &Ctx) { 14696ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek 147003509aea098772644bf4662dc1c88634818ceeccZhongxing Xu const Expr *Ex = dyn_cast<Expr>(Condition); 14716ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek if (!Ex) 14726ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek return UnknownVal(); 14736ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek 14746ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek uint64_t bits = 0; 14756ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek bool bitsInit = false; 14761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 147703509aea098772644bf4662dc1c88634818ceeccZhongxing Xu while (const CastExpr *CE = dyn_cast<CastExpr>(Ex)) { 14786ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek QualType T = CE->getType(); 14796ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek 1480a5796f87229b4aeebca71fa6ee1790ae7a5a0382Jordan Rose if (!T->isIntegralOrEnumerationType()) 14816ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek return UnknownVal(); 14821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 14836ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek uint64_t newBits = Ctx.getTypeSize(T); 14846ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek if (!bitsInit || newBits < bits) { 14856ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek bitsInit = true; 14866ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek bits = newBits; 14876ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek } 14881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 14896ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek Ex = CE->getSubExpr(); 14906ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek } 14916ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek 14926ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek // We reached a non-cast. Is it a symbolic value? 14936ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek QualType T = Ex->getType(); 14946ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek 1495a5796f87229b4aeebca71fa6ee1790ae7a5a0382Jordan Rose if (!bitsInit || !T->isIntegralOrEnumerationType() || 1496a5796f87229b4aeebca71fa6ee1790ae7a5a0382Jordan Rose Ctx.getTypeSize(T) > bits) 14976ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek return UnknownVal(); 14981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 14995eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek return state->getSVal(Ex, LCtx); 15006ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek} 15016ae8a3600656c478d27f25639bed765f4fe71732Ted Kremenek 15026bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#ifndef NDEBUG 15036bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesstatic const Stmt *getRightmostLeaf(const Stmt *Condition) { 15046bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines while (Condition) { 15056bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const BinaryOperator *BO = dyn_cast<BinaryOperator>(Condition); 15066bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (!BO || !BO->isLogicalOp()) { 15076bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return Condition; 15086bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 15096bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Condition = BO->getRHS()->IgnoreParens(); 15106bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 15116bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 15126bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines} 15136bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#endif 15146bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 15156bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// Returns the condition the branch at the end of 'B' depends on and whose value 15166bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// has been evaluated within 'B'. 15176bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// In most cases, the terminator condition of 'B' will be evaluated fully in 15186bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// the last statement of 'B'; in those cases, the resolved condition is the 15196bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// given 'Condition'. 15206bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// If the condition of the branch is a logical binary operator tree, the CFG is 15216bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// optimized: in that case, we know that the expression formed by all but the 15226bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// rightmost leaf of the logical binary operator tree must be true, and thus 15236bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// the branch condition is at this point equivalent to the truth value of that 15246bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// rightmost leaf; the CFG block thus only evaluates this rightmost leaf 15256bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// expression in its final statement. As the full condition in that case was 15266bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// not evaluated, and is thus not in the SVal cache, we need to use that leaf 15276bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// expression to evaluate the truth value of the condition in the current state 15286bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// space. 15293f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenekstatic const Stmt *ResolveCondition(const Stmt *Condition, 15303f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek const CFGBlock *B) { 15313f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek if (const Expr *Ex = dyn_cast<Expr>(Condition)) 15323f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek Condition = Ex->IgnoreParens(); 15333f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 15343f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek const BinaryOperator *BO = dyn_cast<BinaryOperator>(Condition); 15353f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek if (!BO || !BO->isLogicalOp()) 15363f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek return Condition; 15373f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 1538176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines assert(!B->getTerminator().isTemporaryDtorsBranch() && 1539176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines "Temporary destructor branches handled by processBindTemporary."); 15406bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 15413f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // For logical operations, we still have the case where some branches 15423f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // use the traditional "merge" approach and others sink the branch 15433f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // directly into the basic blocks representing the logical operation. 15443f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // We need to distinguish between those two cases here. 15453f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 15463f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // The invariants are still shifting, but it is possible that the 15473f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // last element in a CFGBlock is not a CFGStmt. Look for the last 15483f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // CFGStmt as the value of the condition. 15493f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek CFGBlock::const_reverse_iterator I = B->rbegin(), E = B->rend(); 15503f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek for (; I != E; ++I) { 15513f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek CFGElement Elem = *I; 1552b07805485c603be3d8011f72611465324c9e664bDavid Blaikie Optional<CFGStmt> CS = Elem.getAs<CFGStmt>(); 15533f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek if (!CS) 15543f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek continue; 15556bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const Stmt *LastStmt = CS->getStmt(); 15566bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines assert(LastStmt == Condition || LastStmt == getRightmostLeaf(Condition)); 15576bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return LastStmt; 15583f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek } 15593f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek llvm_unreachable("could not resolve condition"); 15603f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek} 15613f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 15629c378f705405d37f49795d5e915989de774fe11fTed Kremenekvoid ExprEngine::processBranch(const Stmt *Condition, const Stmt *Term, 1563a19f4af7a94835ce4693bfe12d6270754e79eb56Anna Zaks NodeBuilderContext& BldCtx, 1564ad62deeb70e97da6bd514dd390ea1ce6af6ad81dAnna Zaks ExplodedNode *Pred, 15651aae01a8308d2f8e31adab3f4d7ac35543aac680Anna Zaks ExplodedNodeSet &Dst, 1566a19f4af7a94835ce4693bfe12d6270754e79eb56Anna Zaks const CFGBlock *DstT, 1567a19f4af7a94835ce4693bfe12d6270754e79eb56Anna Zaks const CFGBlock *DstF) { 1568176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines assert((!Condition || !isa<CXXBindTemporaryExpr>(Condition)) && 1569176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines "CXXBindTemporaryExprs are handled by processBindTemporary."); 157095ab9e306f4deefeabd89ea61987f4a8d67e0890Pavel Labath const LocationContext *LCtx = Pred->getLocationContext(); 157195ab9e306f4deefeabd89ea61987f4a8d67e0890Pavel Labath PrettyStackTraceLocationContext StackCrashInfo(LCtx); 157266c486f275531df6362b3511fc3af6563561801bTed Kremenek currBldrCtx = &BldCtx; 1573f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks 1574b2331834a0515c80862ee51325c758a053829f15Ted Kremenek // Check for NULL conditions; e.g. "for(;;)" 15751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (!Condition) { 15761aae01a8308d2f8e31adab3f4d7ac35543aac680Anna Zaks BranchNodeBuilder NullCondBldr(Pred, Dst, BldCtx, DstT, DstF); 1577a19f4af7a94835ce4693bfe12d6270754e79eb56Anna Zaks NullCondBldr.markInfeasible(false); 15784e82d3cf6fd4c907265e3fa3aac0a835c35dc759Anna Zaks NullCondBldr.generateNode(Pred->getState(), true, Pred); 1579b2331834a0515c80862ee51325c758a053829f15Ted Kremenek return; 1580b2331834a0515c80862ee51325c758a053829f15Ted Kremenek } 15811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 15823f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek if (const Expr *Ex = dyn_cast<Expr>(Condition)) 15833f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek Condition = Ex->IgnoreParens(); 158495ab9e306f4deefeabd89ea61987f4a8d67e0890Pavel Labath 1585dd9e9cec6f863afa15dd91b34fbf15c66c678c02Bill Wendling Condition = ResolveCondition(Condition, BldCtx.getBlock()); 158621028dd8850c64a414f7a82dfddcc291351203d6Ted Kremenek PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(), 158721028dd8850c64a414f7a82dfddcc291351203d6Ted Kremenek Condition->getLocStart(), 158821028dd8850c64a414f7a82dfddcc291351203d6Ted Kremenek "Error evaluating branch"); 15890fb0bc4067d6c9d7c0e655300ef309b05d3adfc9Ted Kremenek 1590f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks ExplodedNodeSet CheckersOutSet; 1591f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks getCheckerManager().runCheckersForBranchCondition(Condition, CheckersOutSet, 15924e82d3cf6fd4c907265e3fa3aac0a835c35dc759Anna Zaks Pred, *this); 15938ff5c41f2bde7ebbe568b4c15e59f14b8befae66Anna Zaks // We generated only sinks. 1594f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks if (CheckersOutSet.empty()) 15958ff5c41f2bde7ebbe568b4c15e59f14b8befae66Anna Zaks return; 15961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1597f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks BranchNodeBuilder builder(CheckersOutSet, Dst, BldCtx, DstT, DstF); 1598f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks for (NodeBuilder::iterator I = CheckersOutSet.begin(), 1599f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks E = CheckersOutSet.end(); E != I; ++I) { 1600cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks ExplodedNode *PredI = *I; 1601cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks 1602cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks if (PredI->isSink()) 1603cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks continue; 1604cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks 160512b3e3199c530b72f3cc44dd24a1e20ed6086292Anna Zaks ProgramStateRef PrevState = PredI->getState(); 160612b3e3199c530b72f3cc44dd24a1e20ed6086292Anna Zaks SVal X = PrevState->getSVal(Condition, PredI->getLocationContext()); 1607cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks 1608cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks if (X.isUnknownOrUndef()) { 1609cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks // Give it a chance to recover from unknown. 1610cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks if (const Expr *Ex = dyn_cast<Expr>(Condition)) { 1611a5796f87229b4aeebca71fa6ee1790ae7a5a0382Jordan Rose if (Ex->getType()->isIntegralOrEnumerationType()) { 1612cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks // Try to recover some path-sensitivity. Right now casts of symbolic 1613cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks // integers that promote their values are currently not tracked well. 1614cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks // If 'Condition' is such an expression, try and recover the 1615cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks // underlying value and use that instead. 1616cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks SVal recovered = RecoverCastedSymbol(getStateManager(), 1617cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks PrevState, Condition, 161812b3e3199c530b72f3cc44dd24a1e20ed6086292Anna Zaks PredI->getLocationContext(), 1619cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks getContext()); 1620cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks 1621cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks if (!recovered.isUnknown()) { 1622cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks X = recovered; 1623cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks } 16240835e4cccfef3ea5346962722b79484f6b3ca602Zhongxing Xu } 1625b38911f16b4943548db6a3695fc6ae23070b25d2Ted Kremenek } 16260835e4cccfef3ea5346962722b79484f6b3ca602Zhongxing Xu } 1627a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 16280835e4cccfef3ea5346962722b79484f6b3ca602Zhongxing Xu // If the condition is still unknown, give up. 162973c498a08f4968b6987d1453c7b77929dcc6d5f7Argyrios Kyrtzidis if (X.isUnknownOrUndef()) { 1630dd9e9cec6f863afa15dd91b34fbf15c66c678c02Bill Wendling builder.generateNode(PrevState, true, PredI); 1631dd9e9cec6f863afa15dd91b34fbf15c66c678c02Bill Wendling builder.generateNode(PrevState, false, PredI); 1632cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks continue; 16331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 16341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 16355251abea41b446c26e3239c8dd6c7edea6fc335dDavid Blaikie DefinedSVal V = X.castAs<DefinedSVal>(); 1636dd9e9cec6f863afa15dd91b34fbf15c66c678c02Bill Wendling 1637dd9e9cec6f863afa15dd91b34fbf15c66c678c02Bill Wendling ProgramStateRef StTrue, StFalse; 1638651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::tie(StTrue, StFalse) = PrevState->assume(V); 16396960d08b4ddf389d7c81504df7f16dc645120482Jordan Rose 1640cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks // Process the true branch. 1641cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks if (builder.isFeasible(true)) { 1642dd9e9cec6f863afa15dd91b34fbf15c66c678c02Bill Wendling if (StTrue) 16436960d08b4ddf389d7c81504df7f16dc645120482Jordan Rose builder.generateNode(StTrue, true, PredI); 1644dd9e9cec6f863afa15dd91b34fbf15c66c678c02Bill Wendling else 1645cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks builder.markInfeasible(true); 1646cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks } 16471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1648cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks // Process the false branch. 1649cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks if (builder.isFeasible(false)) { 1650dd9e9cec6f863afa15dd91b34fbf15c66c678c02Bill Wendling if (StFalse) 16516960d08b4ddf389d7c81504df7f16dc645120482Jordan Rose builder.generateNode(StFalse, false, PredI); 1652dd9e9cec6f863afa15dd91b34fbf15c66c678c02Bill Wendling else 1653cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks builder.markInfeasible(false); 1654cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks } 1655cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks } 16566bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines currBldrCtx = nullptr; 1657f233d48cfc513b045e2c2cfca5c175220fbd0a82Ted Kremenek} 1658f233d48cfc513b045e2c2cfca5c175220fbd0a82Ted Kremenek 16590f5c5c60e9806d13f0907cd99d7204ffab0e08f7Ted Kremenek/// The GDM component containing the set of global variables which have been 16600f5c5c60e9806d13f0907cd99d7204ffab0e08f7Ted Kremenek/// previously initialized with explicit initializers. 16610f5c5c60e9806d13f0907cd99d7204ffab0e08f7Ted KremenekREGISTER_TRAIT_WITH_PROGRAMSTATE(InitializedGlobalsSet, 16620f5c5c60e9806d13f0907cd99d7204ffab0e08f7Ted Kremenek llvm::ImmutableSet<const VarDecl *>) 16630f5c5c60e9806d13f0907cd99d7204ffab0e08f7Ted Kremenek 16640f5c5c60e9806d13f0907cd99d7204ffab0e08f7Ted Kremenekvoid ExprEngine::processStaticInitializer(const DeclStmt *DS, 16650f5c5c60e9806d13f0907cd99d7204ffab0e08f7Ted Kremenek NodeBuilderContext &BuilderCtx, 16660f5c5c60e9806d13f0907cd99d7204ffab0e08f7Ted Kremenek ExplodedNode *Pred, 16670f5c5c60e9806d13f0907cd99d7204ffab0e08f7Ted Kremenek clang::ento::ExplodedNodeSet &Dst, 16680f5c5c60e9806d13f0907cd99d7204ffab0e08f7Ted Kremenek const CFGBlock *DstT, 16690f5c5c60e9806d13f0907cd99d7204ffab0e08f7Ted Kremenek const CFGBlock *DstF) { 1670ac7cc2d37e82181e73fcc265c1d0a619d18b7605Jordan Rose PrettyStackTraceLocationContext CrashInfo(Pred->getLocationContext()); 16710f5c5c60e9806d13f0907cd99d7204ffab0e08f7Ted Kremenek currBldrCtx = &BuilderCtx; 16720f5c5c60e9806d13f0907cd99d7204ffab0e08f7Ted Kremenek 16730f5c5c60e9806d13f0907cd99d7204ffab0e08f7Ted Kremenek const VarDecl *VD = cast<VarDecl>(DS->getSingleDecl()); 16740f5c5c60e9806d13f0907cd99d7204ffab0e08f7Ted Kremenek ProgramStateRef state = Pred->getState(); 16750f5c5c60e9806d13f0907cd99d7204ffab0e08f7Ted Kremenek bool initHasRun = state->contains<InitializedGlobalsSet>(VD); 16760f5c5c60e9806d13f0907cd99d7204ffab0e08f7Ted Kremenek BranchNodeBuilder builder(Pred, Dst, BuilderCtx, DstT, DstF); 16770f5c5c60e9806d13f0907cd99d7204ffab0e08f7Ted Kremenek 16780f5c5c60e9806d13f0907cd99d7204ffab0e08f7Ted Kremenek if (!initHasRun) { 16790f5c5c60e9806d13f0907cd99d7204ffab0e08f7Ted Kremenek state = state->add<InitializedGlobalsSet>(VD); 16800f5c5c60e9806d13f0907cd99d7204ffab0e08f7Ted Kremenek } 16810f5c5c60e9806d13f0907cd99d7204ffab0e08f7Ted Kremenek 16820f5c5c60e9806d13f0907cd99d7204ffab0e08f7Ted Kremenek builder.generateNode(state, initHasRun, Pred); 16830f5c5c60e9806d13f0907cd99d7204ffab0e08f7Ted Kremenek builder.markInfeasible(!initHasRun); 16840f5c5c60e9806d13f0907cd99d7204ffab0e08f7Ted Kremenek 16856bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines currBldrCtx = nullptr; 16860f5c5c60e9806d13f0907cd99d7204ffab0e08f7Ted Kremenek} 16870f5c5c60e9806d13f0907cd99d7204ffab0e08f7Ted Kremenek 1688e36de1fe51c39d9161915dd3dbef880954af6476Ted Kremenek/// processIndirectGoto - Called by CoreEngine. Used to generate successor 1689754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek/// nodes by processing the 'effects' of a computed goto jump. 1690ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattnervoid ExprEngine::processIndirectGoto(IndirectGotoNodeBuilder &builder) { 1691754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek 16928bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek ProgramStateRef state = builder.getState(); 16935eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek SVal V = state->getSVal(builder.getTarget(), builder.getLocationContext()); 16941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1695754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek // Three possibilities: 1696754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek // 1697754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek // (1) We know the computed label. 16984a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek // (2) The label is NULL (or some other constant), or Undefined. 1699754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek // (3) We have no clue about the label. Dispatch to all targets. 1700754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek // 17011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1702d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis typedef IndirectGotoNodeBuilder::iterator iterator; 1703754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek 1704dc84cd5efdd3430efb22546b4ac656aa0540b210David Blaikie if (Optional<loc::GotoLabel> LV = V.getAs<loc::GotoLabel>()) { 17055251abea41b446c26e3239c8dd6c7edea6fc335dDavid Blaikie const LabelDecl *L = LV->getLabel(); 17061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1707ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattner for (iterator I = builder.begin(), E = builder.end(); I != E; ++I) { 170824f1a967741ff9f8025ee23be12ba6feacc31f77Ted Kremenek if (I.getLabel() == L) { 1709a8538d902fce9cfec20f39b34492268b51643819Ted Kremenek builder.generateNode(I, state); 1710754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek return; 1711754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek } 1712754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek } 17131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1714b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie llvm_unreachable("No block with label."); 1715754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek } 1716754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek 17175251abea41b446c26e3239c8dd6c7edea6fc335dDavid Blaikie if (V.getAs<loc::ConcreteInt>() || V.getAs<UndefinedVal>()) { 1718754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek // Dispatch to the first target and mark it as a sink. 17192055effed54d614b51e3501a174c9b1fe92e4de4Zhongxing Xu //ExplodedNode* N = builder.generateNode(builder.begin(), state, true); 17202055effed54d614b51e3501a174c9b1fe92e4de4Zhongxing Xu // FIXME: add checker visit. 17212055effed54d614b51e3501a174c9b1fe92e4de4Zhongxing Xu // UndefBranches.insert(N); 1722754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek return; 1723754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek } 17241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1725754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek // This is really a catch-all. We don't support symbolics yet. 1726b3cfd58c9b13325d994e5f9b5065e6a22d91911dTed Kremenek // FIXME: Implement dispatch for symbolic pointers. 17271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1728754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek for (iterator I=builder.begin(), E=builder.end(); I != E; ++I) 1729a8538d902fce9cfec20f39b34492268b51643819Ted Kremenek builder.generateNode(I, state); 1730754607e7cff2d902d9af8b771409449fb2f8d2bfTed Kremenek} 1731f233d48cfc513b045e2c2cfca5c175220fbd0a82Ted Kremenek 1732176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines#if 0 1733176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesstatic bool stackFrameDoesNotContainInitializedTemporaries(ExplodedNode &Pred) { 1734176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines const StackFrameContext* Frame = Pred.getStackFrame(); 1735176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines const llvm::ImmutableSet<CXXBindTemporaryContext> &Set = 1736176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines Pred.getState()->get<InitializedTemporariesSet>(); 1737176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return std::find_if(Set.begin(), Set.end(), 1738176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines [&](const CXXBindTemporaryContext &Ctx) { 1739176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (Ctx.second == Frame) { 1740176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines Ctx.first->dump(); 1741176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::errs() << "\n"; 1742176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 1743176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return Ctx.second == Frame; 1744176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines }) == Set.end(); 1745176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines} 1746176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines#endif 1747176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 1748d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis/// ProcessEndPath - Called by CoreEngine. Used to generate end-of-path 174973099bfea9f5d4ec05265170bbefec3d76fb6b5eTed Kremenek/// nodes when the control reaches the end of a function. 1750b355be838a22a511d078504b2277f70aea52ca85Anna Zaksvoid ExprEngine::processEndOfFunction(NodeBuilderContext& BC, 1751b355be838a22a511d078504b2277f70aea52ca85Anna Zaks ExplodedNode *Pred) { 1752176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // FIXME: Assert that stackFrameDoesNotContainInitializedTemporaries(*Pred)). 1753176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // We currently cannot enable this assert, as lifetime extended temporaries 1754176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // are not modelled correctly. 1755ac7cc2d37e82181e73fcc265c1d0a619d18b7605Jordan Rose PrettyStackTraceLocationContext CrashInfo(Pred->getLocationContext()); 1756b355be838a22a511d078504b2277f70aea52ca85Anna Zaks StateMgr.EndPath(Pred->getState()); 17578501b7a1c4c4a9ba0ea6cb8e500e601ef3759debAnna Zaks 1758af498a28797c075c48d7e943df5f5a8e78ed8eb0Anna Zaks ExplodedNodeSet Dst; 17598501b7a1c4c4a9ba0ea6cb8e500e601ef3759debAnna Zaks if (Pred->getLocationContext()->inTopFrame()) { 17608501b7a1c4c4a9ba0ea6cb8e500e601ef3759debAnna Zaks // Remove dead symbols. 17618501b7a1c4c4a9ba0ea6cb8e500e601ef3759debAnna Zaks ExplodedNodeSet AfterRemovedDead; 17628501b7a1c4c4a9ba0ea6cb8e500e601ef3759debAnna Zaks removeDeadOnEndOfFunction(BC, Pred, AfterRemovedDead); 17638501b7a1c4c4a9ba0ea6cb8e500e601ef3759debAnna Zaks 17648501b7a1c4c4a9ba0ea6cb8e500e601ef3759debAnna Zaks // Notify checkers. 17658501b7a1c4c4a9ba0ea6cb8e500e601ef3759debAnna Zaks for (ExplodedNodeSet::iterator I = AfterRemovedDead.begin(), 17668501b7a1c4c4a9ba0ea6cb8e500e601ef3759debAnna Zaks E = AfterRemovedDead.end(); I != E; ++I) { 1767344c77aac25e5d960aced3f45fbaa09853383f6dAnna Zaks getCheckerManager().runCheckersForEndFunction(BC, Dst, *I, *this); 17688501b7a1c4c4a9ba0ea6cb8e500e601ef3759debAnna Zaks } 17698501b7a1c4c4a9ba0ea6cb8e500e601ef3759debAnna Zaks } else { 1770344c77aac25e5d960aced3f45fbaa09853383f6dAnna Zaks getCheckerManager().runCheckersForEndFunction(BC, Dst, Pred, *this); 17718501b7a1c4c4a9ba0ea6cb8e500e601ef3759debAnna Zaks } 17728501b7a1c4c4a9ba0ea6cb8e500e601ef3759debAnna Zaks 17734d2ae4a70336dc2aa11389b34946be152bb454c9Anna Zaks Engine.enqueueEndOfFunction(Dst); 177473099bfea9f5d4ec05265170bbefec3d76fb6b5eTed Kremenek} 177573099bfea9f5d4ec05265170bbefec3d76fb6b5eTed Kremenek 1776d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis/// ProcessSwitch - Called by CoreEngine. Used to generate successor 1777daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek/// nodes by processing the 'effects' of a switch statement. 1778e36de1fe51c39d9161915dd3dbef880954af6476Ted Kremenekvoid ExprEngine::processSwitch(SwitchNodeBuilder& builder) { 1779d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis typedef SwitchNodeBuilder::iterator iterator; 17808bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek ProgramStateRef state = builder.getState(); 17819c378f705405d37f49795d5e915989de774fe11fTed Kremenek const Expr *CondE = builder.getCondition(); 17825eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek SVal CondV_untested = state->getSVal(CondE, builder.getLocationContext()); 1783daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek 17845b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek if (CondV_untested.isUndef()) { 17852055effed54d614b51e3501a174c9b1fe92e4de4Zhongxing Xu //ExplodedNode* N = builder.generateDefaultCaseNode(state, true); 1786b9bbd592c7ea72ada8d982e40a729beb9b53371eTed Kremenek // FIXME: add checker 17872055effed54d614b51e3501a174c9b1fe92e4de4Zhongxing Xu //UndefBranches.insert(N); 17882055effed54d614b51e3501a174c9b1fe92e4de4Zhongxing Xu 1789daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek return; 1790daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek } 17915251abea41b446c26e3239c8dd6c7edea6fc335dDavid Blaikie DefinedOrUnknownSVal CondV = CondV_untested.castAs<DefinedOrUnknownSVal>(); 1792692416c214a3b234236dedcf875735a9cc29e90bTed Kremenek 17938bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek ProgramStateRef DefaultSt = state; 1794a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 179534feff654c6304e0a59ceb1376989d28dbc956ffTed Kremenek iterator I = builder.begin(), EI = builder.end(); 179634feff654c6304e0a59ceb1376989d28dbc956ffTed Kremenek bool defaultIsFeasible = I == EI; 17971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 179834feff654c6304e0a59ceb1376989d28dbc956ffTed Kremenek for ( ; I != EI; ++I) { 1799e71f3d587844110d836c82250830b27b1651afdbTed Kremenek // Successor may be pruned out during CFG construction. 1800e71f3d587844110d836c82250830b27b1651afdbTed Kremenek if (!I.getBlock()) 1801e71f3d587844110d836c82250830b27b1651afdbTed Kremenek continue; 1802a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 18039c378f705405d37f49795d5e915989de774fe11fTed Kremenek const CaseStmt *Case = I.getCase(); 180472afb3739da0da02158242ae41a50cfe0bea78b4Ted Kremenek 180572afb3739da0da02158242ae41a50cfe0bea78b4Ted Kremenek // Evaluate the LHS of the case value. 180685df96c1f04867e26ba069aa0cc6a4cd6a01292eRichard Smith llvm::APSInt V1 = Case->getLHS()->EvaluateKnownConstInt(getContext()); 180785df96c1f04867e26ba069aa0cc6a4cd6a01292eRichard Smith assert(V1.getBitWidth() == getContext().getTypeSize(CondE->getType())); 18081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1809daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek // Get the RHS of the case, if it exists. 181085df96c1f04867e26ba069aa0cc6a4cd6a01292eRichard Smith llvm::APSInt V2; 181185df96c1f04867e26ba069aa0cc6a4cd6a01292eRichard Smith if (const Expr *E = Case->getRHS()) 181285df96c1f04867e26ba069aa0cc6a4cd6a01292eRichard Smith V2 = E->EvaluateKnownConstInt(getContext()); 181314a1140c9f4e20b12a54db8745b74699b9872cd2Ted Kremenek else 181414a1140c9f4e20b12a54db8745b74699b9872cd2Ted Kremenek V2 = V1; 18151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1816a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar ProgramStateRef StateCase; 1817a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar if (Optional<NonLoc> NL = CondV.getAs<NonLoc>()) 1818a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar std::tie(StateCase, DefaultSt) = 1819a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar DefaultSt->assumeWithinInclusiveRange(*NL, V1, V2); 1820a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar else // UnknownVal 1821a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar StateCase = DefaultSt; 1822a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 1823a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar if (StateCase) 1824a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar builder.generateCaseStmtNode(I, StateCase); 1825a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 1826a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar // Now "assume" that the case doesn't match. Add this state 1827a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar // to the default state (if it is feasible). 1828a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar if (DefaultSt) 1829a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar defaultIsFeasible = true; 1830a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar else { 1831a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar defaultIsFeasible = false; 1832a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar break; 1833a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar } 1834daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek } 18351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 18364d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek if (!defaultIsFeasible) 18374d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek return; 18384d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek 18394d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek // If we have switch(enum value), the default branch is not 18404d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek // feasible if all of the enum constants not covered by 'case:' statements 18414d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek // are not feasible values for the switch condition. 18424d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek // 18434d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek // Note that this isn't as accurate as it could be. Even if there isn't 18444d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek // a case for a particular enum value as long as that enum value isn't 18454d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek // feasible then it shouldn't be considered for making 'default:' reachable. 18464d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek const SwitchStmt *SS = builder.getSwitch(); 18474d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek const Expr *CondExpr = SS->getCond()->IgnoreParenImpCasts(); 18484d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek if (CondExpr->getType()->getAs<EnumType>()) { 18494d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek if (SS->isAllEnumCasesCovered()) 18504d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek return; 18514d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek } 18524d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek 18534d3175c1e5a44251ea97b0c81e80f060629d9c08Ted Kremenek builder.generateDefaultCaseNode(DefaultSt); 1854daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek} 1855daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek 1856e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek//===----------------------------------------------------------------------===// 1857ec96a2d52d16e150baaf629cd35e3fabff5d8915Ted Kremenek// Transfer functions: Loads and stores. 1858e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek//===----------------------------------------------------------------------===// 1859d27f8169f4b68337a489547a41ac45bf7a5d1ddfTed Kremenek 1860d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisvoid ExprEngine::VisitCommonDeclRefExpr(const Expr *Ex, const NamedDecl *D, 1861d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis ExplodedNode *Pred, 1862d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis ExplodedNodeSet &Dst) { 186366c486f275531df6362b3511fc3af6563561801bTed Kremenek StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx); 1864ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks 18658bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek ProgramStateRef state = Pred->getState(); 18665eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek const LocationContext *LCtx = Pred->getLocationContext(); 18676d69b5d82281992e981caa9bc038e3f6cac6594aZhongxing Xu 18689c378f705405d37f49795d5e915989de774fe11fTed Kremenek if (const VarDecl *VD = dyn_cast<VarDecl>(D)) { 18691acb394679b6e644044a0f6c358229759009b1a6Jordan Rose // C permits "extern void v", and if you cast the address to a valid type, 1870a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar // you can even do things with it. We simply pretend 18711acb394679b6e644044a0f6c358229759009b1a6Jordan Rose assert(Ex->isGLValue() || VD->getType()->isVoidType()); 1872a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar const LocationContext *LocCtxt = Pred->getLocationContext(); 1873a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar const Decl *D = LocCtxt->getDecl(); 1874a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar const auto *MD = D ? dyn_cast<CXXMethodDecl>(D) : nullptr; 1875a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar const auto *DeclRefEx = dyn_cast<DeclRefExpr>(Ex); 1876a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar SVal V; 1877a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar bool IsReference; 1878a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar if (AMgr.options.shouldInlineLambdas() && DeclRefEx && 1879a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar DeclRefEx->refersToEnclosingVariableOrCapture() && MD && 1880a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar MD->getParent()->isLambda()) { 1881a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar // Lookup the field of the lambda. 1882a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar const CXXRecordDecl *CXXRec = MD->getParent(); 1883a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar llvm::DenseMap<const VarDecl *, FieldDecl *> LambdaCaptureFields; 1884a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar FieldDecl *LambdaThisCaptureField; 1885a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar CXXRec->getCaptureFields(LambdaCaptureFields, LambdaThisCaptureField); 1886a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar const FieldDecl *FD = LambdaCaptureFields[VD]; 1887a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar if (!FD) { 1888a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar // When a constant is captured, sometimes no corresponding field is 1889a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar // created in the lambda object. 1890a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar assert(VD->getType().isConstQualified()); 1891a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar V = state->getLValue(VD, LocCtxt); 1892a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar IsReference = false; 1893a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar } else { 1894a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar Loc CXXThis = 1895a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar svalBuilder.getCXXThis(MD, LocCtxt->getCurrentStackFrame()); 1896a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar SVal CXXThisVal = state->getSVal(CXXThis); 1897a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar V = state->getLValue(FD, CXXThisVal); 1898a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar IsReference = FD->getType()->isReferenceType(); 1899a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar } 1900a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar } else { 1901a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar V = state->getLValue(VD, LocCtxt); 1902a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar IsReference = VD->getType()->isReferenceType(); 1903a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar } 1904a7581731b1453b51b26154d2409d42a5b6395079Zhongxing Xu 1905892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek // For references, the 'lvalue' is the pointer address stored in the 1906892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek // reference region. 1907a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar if (IsReference) { 1908892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek if (const MemRegion *R = V.getAsRegion()) 1909892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek V = state->getSVal(R); 1910892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek else 1911892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek V = UnknownVal(); 1912852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek } 19136d69b5d82281992e981caa9bc038e3f6cac6594aZhongxing Xu 19146bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Bldr.generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V), nullptr, 1915ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks ProgramPoint::PostLValueKind); 1916852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek return; 1917892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek } 19189c378f705405d37f49795d5e915989de774fe11fTed Kremenek if (const EnumConstantDecl *ED = dyn_cast<EnumConstantDecl>(D)) { 1919591b5f53c0e11d87401b4804bb1be1a53f95c619Anna Zaks assert(!Ex->isGLValue()); 1920c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek SVal V = svalBuilder.makeIntVal(ED->getInitVal()); 19215eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek Bldr.generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V)); 19226d69b5d82281992e981caa9bc038e3f6cac6594aZhongxing Xu return; 1923892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek } 19249c378f705405d37f49795d5e915989de774fe11fTed Kremenek if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 1925c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek SVal V = svalBuilder.getFunctionPointer(FD); 19266bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Bldr.generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V), nullptr, 1927ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks ProgramPoint::PostLValueKind); 19286d69b5d82281992e981caa9bc038e3f6cac6594aZhongxing Xu return; 19291b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek } 19305aac0b6ae95f137b1783f3e6227241fb457b8f8bTed Kremenek if (isa<FieldDecl>(D)) { 1931fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose // FIXME: Compute lvalue of field pointers-to-member. 19320156439a3d718ea0ef5922c38d189a60829c8a86Jordan Rose // Right now we just use a non-null void pointer, so that it gives proper 19330156439a3d718ea0ef5922c38d189a60829c8a86Jordan Rose // results in boolean contexts. 19340156439a3d718ea0ef5922c38d189a60829c8a86Jordan Rose SVal V = svalBuilder.conjureSymbolVal(Ex, LCtx, getContext().VoidPtrTy, 19350156439a3d718ea0ef5922c38d189a60829c8a86Jordan Rose currBldrCtx->blockCount()); 19365251abea41b446c26e3239c8dd6c7edea6fc335dDavid Blaikie state = state->assume(V.castAs<DefinedOrUnknownSVal>(), true); 19376bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Bldr.generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V), nullptr, 1938fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose ProgramPoint::PostLValueKind); 19395aac0b6ae95f137b1783f3e6227241fb457b8f8bTed Kremenek return; 19405aac0b6ae95f137b1783f3e6227241fb457b8f8bTed Kremenek } 19415aac0b6ae95f137b1783f3e6227241fb457b8f8bTed Kremenek 1942fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose llvm_unreachable("Support for this Decl not implemented."); 19433271f8d315712885ac87747369bb1d9f4b1ea81fTed Kremenek} 19443271f8d315712885ac87747369bb1d9f4b1ea81fTed Kremenek 1945540cbe2b60294fe7b926c26b4f1840f544fe3011Ted Kremenek/// VisitArraySubscriptExpr - Transfer function for array accesses 19469c378f705405d37f49795d5e915989de774fe11fTed Kremenekvoid ExprEngine::VisitLvalArraySubscriptExpr(const ArraySubscriptExpr *A, 19479c378f705405d37f49795d5e915989de774fe11fTed Kremenek ExplodedNode *Pred, 19489c378f705405d37f49795d5e915989de774fe11fTed Kremenek ExplodedNodeSet &Dst){ 19491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 19509c378f705405d37f49795d5e915989de774fe11fTed Kremenek const Expr *Base = A->getBase()->IgnoreParens(); 19519c378f705405d37f49795d5e915989de774fe11fTed Kremenek const Expr *Idx = A->getIdx()->IgnoreParens(); 19521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 19538f3407ef22bc7efe6ca4169381e09d0d657ec192Ted Kremenek ExplodedNodeSet checkerPreStmt; 19548f3407ef22bc7efe6ca4169381e09d0d657ec192Ted Kremenek getCheckerManager().runCheckersForPreStmt(checkerPreStmt, Pred, A, *this); 19558f3407ef22bc7efe6ca4169381e09d0d657ec192Ted Kremenek 195666c486f275531df6362b3511fc3af6563561801bTed Kremenek StmtNodeBuilder Bldr(checkerPreStmt, Dst, *currBldrCtx); 19570e2c34f92f00628d48968dfea096d36381f494cbStephen Hines assert(A->isGLValue() || 19580e2c34f92f00628d48968dfea096d36381f494cbStephen Hines (!AMgr.getLangOpts().CPlusPlus && 19590e2c34f92f00628d48968dfea096d36381f494cbStephen Hines A->getType().isCForbiddenLValueType())); 1960ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks 19618f3407ef22bc7efe6ca4169381e09d0d657ec192Ted Kremenek for (ExplodedNodeSet::iterator it = checkerPreStmt.begin(), 19628f3407ef22bc7efe6ca4169381e09d0d657ec192Ted Kremenek ei = checkerPreStmt.end(); it != ei; ++it) { 19635eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek const LocationContext *LCtx = (*it)->getLocationContext(); 19648bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek ProgramStateRef state = (*it)->getState(); 19655eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek SVal V = state->getLValue(A->getType(), 19665eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek state->getSVal(Idx, LCtx), 19675eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek state->getSVal(Base, LCtx)); 19686bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Bldr.generateNode(A, *it, state->BindExpr(A, LCtx, V), nullptr, 1969fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose ProgramPoint::PostLValueKind); 19701b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek } 1971540cbe2b60294fe7b926c26b4f1840f544fe3011Ted Kremenek} 1972540cbe2b60294fe7b926c26b4f1840f544fe3011Ted Kremenek 1973469ecbded3616416ef938ed94a67f86149faf226Ted Kremenek/// VisitMemberExpr - Transfer function for member expressions. 19749c378f705405d37f49795d5e915989de774fe11fTed Kremenekvoid ExprEngine::VisitMemberExpr(const MemberExpr *M, ExplodedNode *Pred, 1975651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ExplodedNodeSet &Dst) { 19761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1977651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // FIXME: Prechecks eventually go in ::Visit(). 1978651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ExplodedNodeSet CheckedSet; 1979651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines getCheckerManager().runCheckersForPreStmt(CheckedSet, Pred, M, *this); 1980651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1981651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ExplodedNodeSet EvalSet; 1982603513d2294c437b37bcf47f326b686e31bd9e84Jordan Rose ValueDecl *Member = M->getMemberDecl(); 198310f77ad7fc5e5cf3f37a9b14ff5843468b8b84d2Ted Kremenek 1984603513d2294c437b37bcf47f326b686e31bd9e84Jordan Rose // Handle static member variables and enum constants accessed via 1985603513d2294c437b37bcf47f326b686e31bd9e84Jordan Rose // member syntax. 1986603513d2294c437b37bcf47f326b686e31bd9e84Jordan Rose if (isa<VarDecl>(Member) || isa<EnumConstantDecl>(Member)) { 1987651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ExplodedNodeSet Dst; 1988651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (ExplodedNodeSet::iterator I = CheckedSet.begin(), E = CheckedSet.end(); 1989651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines I != E; ++I) { 1990651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines VisitCommonDeclRefExpr(M, Member, Pred, EvalSet); 1991651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 1992651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } else { 1993651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines StmtNodeBuilder Bldr(CheckedSet, EvalSet, *currBldrCtx); 1994651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ExplodedNodeSet Tmp; 1995f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose 1996651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (ExplodedNodeSet::iterator I = CheckedSet.begin(), E = CheckedSet.end(); 1997651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines I != E; ++I) { 1998651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ProgramStateRef state = (*I)->getState(); 1999651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const LocationContext *LCtx = (*I)->getLocationContext(); 2000651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Expr *BaseExpr = M->getBase(); 200110f77ad7fc5e5cf3f37a9b14ff5843468b8b84d2Ted Kremenek 2002651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // Handle C++ method calls. 2003651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(Member)) { 2004651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (MD->isInstance()) 2005651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines state = createTemporaryRegionIfNeeded(state, LCtx, BaseExpr); 200620aa40342bd74895128860c081aa84cd85bfa68dJordan Rose 2007651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines SVal MDVal = svalBuilder.getFunctionPointer(MD); 2008651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines state = state->BindExpr(M, LCtx, MDVal); 200920aa40342bd74895128860c081aa84cd85bfa68dJordan Rose 2010651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Bldr.generateNode(M, *I, state); 2011651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines continue; 201273b417f363a67439b30b3167ef8d9fb32e37191bAnna Zaks } 201373b417f363a67439b30b3167ef8d9fb32e37191bAnna Zaks 2014651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // Handle regular struct fields / member variables. 2015651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines state = createTemporaryRegionIfNeeded(state, LCtx, BaseExpr); 2016651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines SVal baseExprVal = state->getSVal(BaseExpr, LCtx); 2017651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 2018651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FieldDecl *field = cast<FieldDecl>(Member); 2019651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines SVal L = state->getLValue(field, baseExprVal); 2020651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 2021651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (M->isGLValue() || M->getType()->isArrayType()) { 2022651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // We special-case rvalues of array type because the analyzer cannot 2023651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // reason about them, since we expect all regions to be wrapped in Locs. 2024651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // We instead treat these as lvalues and assume that they will decay to 2025651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // pointers as soon as they are used. 2026651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (!M->isGLValue()) { 2027651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines assert(M->getType()->isArrayType()); 2028651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const ImplicitCastExpr *PE = 2029651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines dyn_cast<ImplicitCastExpr>((*I)->getParentMap().getParent(M)); 2030651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (!PE || PE->getCastKind() != CK_ArrayToPointerDecay) { 2031651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines llvm_unreachable("should always be wrapped in ArrayToPointerDecay"); 2032651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 2033651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 20346b4be2ef4ce49717ff972434975ce3c34c9a1c4cJordan Rose 2035651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (field->getType()->isReferenceType()) { 2036651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (const MemRegion *R = L.getAsRegion()) 2037651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines L = state->getSVal(R); 2038651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines else 2039651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines L = UnknownVal(); 2040651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 2041651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 20426bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Bldr.generateNode(M, *I, state->BindExpr(M, LCtx, L), nullptr, 2043651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ProgramPoint::PostLValueKind); 2044651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } else { 2045651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Bldr.takeNodes(*I); 2046651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines evalLoad(Tmp, M, M, *I, state, L); 2047651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Bldr.addNodes(Tmp); 2048651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 2049651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 2050ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks } 2051651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 2052651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines getCheckerManager().runCheckersForPostStmt(Dst, EvalSet, M, *this); 2053469ecbded3616416ef938ed94a67f86149faf226Ted Kremenek} 2054469ecbded3616416ef938ed94a67f86149faf226Ted Kremenek 2055bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaksnamespace { 2056a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainarclass CollectReachableSymbolsCallback final : public SymbolVisitor { 2057bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks InvalidatedSymbols Symbols; 2058a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 2059bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zakspublic: 2060bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks CollectReachableSymbolsCallback(ProgramStateRef State) {} 2061bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks const InvalidatedSymbols &getSymbols() const { return Symbols; } 2062bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks 2063651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool VisitSymbol(SymbolRef Sym) override { 2064bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks Symbols.insert(Sym); 2065bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks return true; 2066bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks } 2067bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks}; 2068bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks} // end anonymous namespace 2069bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks 20701655bcd052a67a3050fc55df8ecce57342352e68Anna Zaks// A value escapes in three possible cases: 20711655bcd052a67a3050fc55df8ecce57342352e68Anna Zaks// (1) We are binding to something that is not a memory region. 20721655bcd052a67a3050fc55df8ecce57342352e68Anna Zaks// (2) We are binding to a MemrRegion that does not have stack storage. 20731655bcd052a67a3050fc55df8ecce57342352e68Anna Zaks// (3) We are binding to a MemRegion with stack storage that the store 20741655bcd052a67a3050fc55df8ecce57342352e68Anna Zaks// does not understand. 2075bf53dfac8195835028bd6347433f7dbebcc29fc1Anna ZaksProgramStateRef ExprEngine::processPointerEscapedOnBind(ProgramStateRef State, 20761655bcd052a67a3050fc55df8ecce57342352e68Anna Zaks SVal Loc, SVal Val) { 2077bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks // Are we storing to something that causes the value to "escape"? 2078bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks bool escapes = true; 2079bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks 2080bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks // TODO: Move to StoreManager. 2081dc84cd5efdd3430efb22546b4ac656aa0540b210David Blaikie if (Optional<loc::MemRegionVal> regionLoc = Loc.getAs<loc::MemRegionVal>()) { 2082bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks escapes = !regionLoc->getRegion()->hasStackStorage(); 2083bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks 2084bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks if (!escapes) { 2085bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks // To test (3), generate a new state with the binding added. If it is 2086bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks // the same state, then it escapes (since the store cannot represent 2087bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks // the binding). 2088bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks // Do this only if we know that the store is not supposed to generate the 2089bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks // same state. 2090bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks SVal StoredVal = State->getSVal(regionLoc->getRegion()); 2091bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks if (StoredVal != Val) 2092bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks escapes = (State == (State->bindLoc(*regionLoc, Val))); 2093bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks } 2094bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks } 2095bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks 2096bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks // If our store can represent the binding and we aren't storing to something 2097bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks // that doesn't have local storage then just return and have the simulation 2098bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks // state continue as is. 2099bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks if (!escapes) 2100bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks return State; 2101bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks 2102bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks // Otherwise, find all symbols referenced by 'val' that we are tracking 2103bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks // and stop tracking them. 2104bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks CollectReachableSymbolsCallback Scanner = 2105bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks State->scanReachableSymbols<CollectReachableSymbolsCallback>(Val); 2106bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks const InvalidatedSymbols &EscapedSymbols = Scanner.getSymbols(); 2107bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks State = getCheckerManager().runCheckersForPointerEscape(State, 2108bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks EscapedSymbols, 21096bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines /*CallEvent*/ nullptr, 2110da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev PSK_EscapeOnBind, 21116bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines nullptr); 2112bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks 2113bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks return State; 2114bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks} 2115bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks 2116a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga NainarProgramStateRef 211741988f331a74a72cf243a2a68ffb56418e9a174eAnna ZaksExprEngine::notifyCheckersOfPointerEscape(ProgramStateRef State, 2118bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks const InvalidatedSymbols *Invalidated, 2119bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks ArrayRef<const MemRegion *> ExplicitRegions, 2120bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks ArrayRef<const MemRegion *> Regions, 212141988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks const CallEvent *Call, 2122da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev RegionAndSymbolInvalidationTraits &ITraits) { 2123a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 2124bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks if (!Invalidated || Invalidated->empty()) 2125bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks return State; 2126bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks 2127bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks if (!Call) 2128bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks return getCheckerManager().runCheckersForPointerEscape(State, 2129233e26acc0ff2a1098f4c813f69286fce840a422Anna Zaks *Invalidated, 21306bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines nullptr, 2131044fe23e79fff3841cc4c315f8c97e1cdccdd8ddAnton Yartsev PSK_EscapeOther, 2132da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev &ITraits); 213341988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks 2134a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar // If the symbols were invalidated by a call, we want to find out which ones 2135bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks // were invalidated directly due to being arguments to the call. 2136bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks InvalidatedSymbols SymbolsDirectlyInvalidated; 2137bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks for (ArrayRef<const MemRegion *>::iterator I = ExplicitRegions.begin(), 2138bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks E = ExplicitRegions.end(); I != E; ++I) { 2139bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks if (const SymbolicRegion *R = (*I)->StripCasts()->getAs<SymbolicRegion>()) 2140bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks SymbolsDirectlyInvalidated.insert(R->getSymbol()); 2141bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks } 2142bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks 2143bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks InvalidatedSymbols SymbolsIndirectlyInvalidated; 2144bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks for (InvalidatedSymbols::const_iterator I=Invalidated->begin(), 2145bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks E = Invalidated->end(); I!=E; ++I) { 2146bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks SymbolRef sym = *I; 2147bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks if (SymbolsDirectlyInvalidated.count(sym)) 2148bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks continue; 2149bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks SymbolsIndirectlyInvalidated.insert(sym); 2150bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks } 2151bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks 2152bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks if (!SymbolsDirectlyInvalidated.empty()) 2153bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks State = getCheckerManager().runCheckersForPointerEscape(State, 2154da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev SymbolsDirectlyInvalidated, Call, PSK_DirectEscapeOnCall, &ITraits); 2155bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks 2156bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks // Notify about the symbols that get indirectly invalidated by the call. 2157bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks if (!SymbolsIndirectlyInvalidated.empty()) 2158bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks State = getCheckerManager().runCheckersForPointerEscape(State, 2159da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev SymbolsIndirectlyInvalidated, Call, PSK_IndirectEscapeOnCall, &ITraits); 2160bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks 2161bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks return State; 2162bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks} 2163bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks 21649c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek/// evalBind - Handle the semantics of binding a value to a specific location. 21659c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek/// This method is used by evalStore and (soon) VisitDeclStmt, and others. 21669c378f705405d37f49795d5e915989de774fe11fTed Kremenekvoid ExprEngine::evalBind(ExplodedNodeSet &Dst, const Stmt *StoreE, 216793bd5ca766c4d7906878f4ffe76ce1b2080e540bJordy Rose ExplodedNode *Pred, 216832a549a64922af0903bdb777613ae7ae4490b70fTed Kremenek SVal location, SVal Val, 21693682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose bool atDeclInit, const ProgramPoint *PP) { 21703682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose 21713682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose const LocationContext *LC = Pred->getLocationContext(); 21723682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose PostStmt PS(StoreE, LC); 21733682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose if (!PP) 21743682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose PP = &PS; 2175b9bbd592c7ea72ada8d982e40a729beb9b53371eTed Kremenek 2176b107c4b7efb907d75620cd3c17f82fe27dc5b745Ted Kremenek // Do a previsit of the bind. 2177fe27971d54d26997149d6b84057f04ff398d1d5dJordy Rose ExplodedNodeSet CheckedSet; 2178fe27971d54d26997149d6b84057f04ff398d1d5dJordy Rose getCheckerManager().runCheckersForBind(CheckedSet, Pred, location, Val, 21793682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose StoreE, *this, *PP); 2180b9bbd592c7ea72ada8d982e40a729beb9b53371eTed Kremenek 2181bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks StmtNodeBuilder Bldr(CheckedSet, Dst, *currBldrCtx); 2182bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks 218332a549a64922af0903bdb777613ae7ae4490b70fTed Kremenek // If the location is not a 'Loc', it will already be handled by 218432a549a64922af0903bdb777613ae7ae4490b70fTed Kremenek // the checkers. There is nothing left to do. 21855251abea41b446c26e3239c8dd6c7edea6fc335dDavid Blaikie if (!location.getAs<Loc>()) { 21866bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const ProgramPoint L = PostStore(StoreE, LC, /*Loc*/nullptr, 21876bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines /*tag*/nullptr); 2188bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks ProgramStateRef state = Pred->getState(); 2189bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks state = processPointerEscapedOnBind(state, location, Val); 2190bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks Bldr.generateNode(L, state, Pred); 219132a549a64922af0903bdb777613ae7ae4490b70fTed Kremenek return; 219232a549a64922af0903bdb777613ae7ae4490b70fTed Kremenek } 21936b6152ba96c164a292cc0b8d8b1d4cecbec27a60Anna Zaks 2194b107c4b7efb907d75620cd3c17f82fe27dc5b745Ted Kremenek for (ExplodedNodeSet::iterator I = CheckedSet.begin(), E = CheckedSet.end(); 2195b107c4b7efb907d75620cd3c17f82fe27dc5b745Ted Kremenek I!=E; ++I) { 21963d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks ExplodedNode *PredI = *I; 21973d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks ProgramStateRef state = PredI->getState(); 2198a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 2199bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks state = processPointerEscapedOnBind(state, location, Val); 2200bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks 220132a549a64922af0903bdb777613ae7ae4490b70fTed Kremenek // When binding the value, pass on the hint that this is a initialization. 220232a549a64922af0903bdb777613ae7ae4490b70fTed Kremenek // For initializations, we do not need to inform clients of region 220332a549a64922af0903bdb777613ae7ae4490b70fTed Kremenek // changes. 22045251abea41b446c26e3239c8dd6c7edea6fc335dDavid Blaikie state = state->bindLoc(location.castAs<Loc>(), 220532a549a64922af0903bdb777613ae7ae4490b70fTed Kremenek Val, /* notifyChanges = */ !atDeclInit); 2206bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks 22076bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const MemRegion *LocReg = nullptr; 2208dc84cd5efdd3430efb22546b4ac656aa0540b210David Blaikie if (Optional<loc::MemRegionVal> LocRegVal = 22095251abea41b446c26e3239c8dd6c7edea6fc335dDavid Blaikie location.getAs<loc::MemRegionVal>()) { 22103d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks LocReg = LocRegVal->getRegion(); 221132a549a64922af0903bdb777613ae7ae4490b70fTed Kremenek } 22126bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 22136bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const ProgramPoint L = PostStore(StoreE, LC, LocReg, nullptr); 2214fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose Bldr.generateNode(L, state, PredI); 2215b107c4b7efb907d75620cd3c17f82fe27dc5b745Ted Kremenek } 2216a8538d902fce9cfec20f39b34492268b51643819Ted Kremenek} 2217a8538d902fce9cfec20f39b34492268b51643819Ted Kremenek 22189c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek/// evalStore - Handle the semantics of a store via an assignment. 2219a8538d902fce9cfec20f39b34492268b51643819Ted Kremenek/// @param Dst The node set to store generated state nodes 22202e6f5b823912ae76211427cb8684c9eaa6e53a1fJames Dennett/// @param AssignE The assignment expression if the store happens in an 2221e8a4d7d0064b357a30fe7ee4f2ddc02f9ffc0357Zhongxing Xu/// assignment. 22222e6f5b823912ae76211427cb8684c9eaa6e53a1fJames Dennett/// @param LocationE The location expression that is stored to. 2223a8538d902fce9cfec20f39b34492268b51643819Ted Kremenek/// @param state The current simulation state 2224a8538d902fce9cfec20f39b34492268b51643819Ted Kremenek/// @param location The location to store the value 2225a8538d902fce9cfec20f39b34492268b51643819Ted Kremenek/// @param Val The value to be stored 22269c378f705405d37f49795d5e915989de774fe11fTed Kremenekvoid ExprEngine::evalStore(ExplodedNodeSet &Dst, const Expr *AssignE, 22279c378f705405d37f49795d5e915989de774fe11fTed Kremenek const Expr *LocationE, 22289c378f705405d37f49795d5e915989de774fe11fTed Kremenek ExplodedNode *Pred, 22298bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek ProgramStateRef state, SVal location, SVal Val, 2230ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek const ProgramPointTag *tag) { 223114429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis // Proceed with the store. We use AssignE as the anchor for the PostStore 223214429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis // ProgramPoint if it is non-NULL, and LocationE otherwise. 223314429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis const Expr *StoreE = AssignE ? AssignE : LocationE; 223414429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis 22351b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek // Evaluate the location (checks for bad dereferences). 2236b4b817d704287836b52b34369009e682f208aa2bTed Kremenek ExplodedNodeSet Tmp; 2237bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek evalLocation(Tmp, AssignE, LocationE, Pred, state, location, tag, false); 22381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2239b4b817d704287836b52b34369009e682f208aa2bTed Kremenek if (Tmp.empty()) 22401b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek return; 2241b0533965f1b4db020692e3b23ca7b3bc15bf5897Ted Kremenek 224273c498a08f4968b6987d1453c7b77929dcc6d5f7Argyrios Kyrtzidis if (location.isUndef()) 224373c498a08f4968b6987d1453c7b77929dcc6d5f7Argyrios Kyrtzidis return; 2244a8538d902fce9cfec20f39b34492268b51643819Ted Kremenek 2245b4b817d704287836b52b34369009e682f208aa2bTed Kremenek for (ExplodedNodeSet::iterator NI=Tmp.begin(), NE=Tmp.end(); NI!=NE; ++NI) 22463d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks evalBind(Dst, StoreE, *NI, location, Val, false); 22471b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek} 22481b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek 2249bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenekvoid ExprEngine::evalLoad(ExplodedNodeSet &Dst, 2250bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek const Expr *NodeEx, 2251bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek const Expr *BoundEx, 2252bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek ExplodedNode *Pred, 2253bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek ProgramStateRef state, 2254bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek SVal location, 2255bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek const ProgramPointTag *tag, 2256bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek QualType LoadTy) 2257bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek{ 22585251abea41b446c26e3239c8dd6c7edea6fc335dDavid Blaikie assert(!location.getAs<NonLoc>() && "location cannot be a NonLoc."); 225914429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis 22605b8c69494881b7d35bc6244b4a19be0cc2eab368Jordan Rose // Are we loading from a region? This actually results in two loads; one 2261852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek // to fetch the address of the referenced value and one to fetch the 2262852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek // referenced value. 22639697934650354bed2e509d8e7e44f21a1fb00f76Ted Kremenek if (const TypedValueRegion *TR = 22649697934650354bed2e509d8e7e44f21a1fb00f76Ted Kremenek dyn_cast_or_null<TypedValueRegion>(location.getAsRegion())) { 2265b9bbd592c7ea72ada8d982e40a729beb9b53371eTed Kremenek 2266018220c343c103b7dfaa117a7a474c7a7fd6d068Zhongxing Xu QualType ValTy = TR->getValueType(); 2267852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek if (const ReferenceType *RT = ValTy->getAs<ReferenceType>()) { 2268ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek static SimpleProgramPointTag 2269651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines loadReferenceTag(TagProviderName, "Load Reference"); 2270852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek ExplodedNodeSet Tmp; 2271bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek evalLoadCommon(Tmp, NodeEx, BoundEx, Pred, state, 2272bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek location, &loadReferenceTag, 2273852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek getContext().getPointerType(RT->getPointeeType())); 2274852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek 2275852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek // Perform the load from the referenced value. 2276852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end() ; I!=E; ++I) { 2277db5e8cd095d1ffdd18f5620ad2348b5f386bebe3Anna Zaks state = (*I)->getState(); 2278bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek location = state->getSVal(BoundEx, (*I)->getLocationContext()); 2279bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek evalLoadCommon(Dst, NodeEx, BoundEx, *I, state, location, tag, LoadTy); 2280b9bbd592c7ea72ada8d982e40a729beb9b53371eTed Kremenek } 2281852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek return; 2282852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek } 2283852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek } 2284b9bbd592c7ea72ada8d982e40a729beb9b53371eTed Kremenek 2285bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek evalLoadCommon(Dst, NodeEx, BoundEx, Pred, state, location, tag, LoadTy); 2286852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek} 2287852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek 2288bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenekvoid ExprEngine::evalLoadCommon(ExplodedNodeSet &Dst, 2289bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek const Expr *NodeEx, 2290bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek const Expr *BoundEx, 2291bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek ExplodedNode *Pred, 2292bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek ProgramStateRef state, 2293bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek SVal location, 2294bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek const ProgramPointTag *tag, 2295bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek QualType LoadTy) { 2296bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek assert(NodeEx); 2297bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek assert(BoundEx); 22981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // Evaluate the location (checks for bad dereferences). 2299b4b817d704287836b52b34369009e682f208aa2bTed Kremenek ExplodedNodeSet Tmp; 2300bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek evalLocation(Tmp, NodeEx, BoundEx, Pred, state, location, tag, true); 2301b4b817d704287836b52b34369009e682f208aa2bTed Kremenek if (Tmp.empty()) 23021b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek return; 2303b9bbd592c7ea72ada8d982e40a729beb9b53371eTed Kremenek 230466c486f275531df6362b3511fc3af6563561801bTed Kremenek StmtNodeBuilder Bldr(Tmp, Dst, *currBldrCtx); 230573c498a08f4968b6987d1453c7b77929dcc6d5f7Argyrios Kyrtzidis if (location.isUndef()) 230673c498a08f4968b6987d1453c7b77929dcc6d5f7Argyrios Kyrtzidis return; 2307b9bbd592c7ea72ada8d982e40a729beb9b53371eTed Kremenek 23081b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek // Proceed with the load. 2309b4b817d704287836b52b34369009e682f208aa2bTed Kremenek for (ExplodedNodeSet::iterator NI=Tmp.begin(), NE=Tmp.end(); NI!=NE; ++NI) { 2310db5e8cd095d1ffdd18f5620ad2348b5f386bebe3Anna Zaks state = (*NI)->getState(); 23115eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek const LocationContext *LCtx = (*NI)->getLocationContext(); 231296ebad66c451d79c9f57b1edb31efaeeb23b9a01Ted Kremenek 23137affe151f5689b2d3547b8947c4099532c78a021Jordan Rose SVal V = UnknownVal(); 23147affe151f5689b2d3547b8947c4099532c78a021Jordan Rose if (location.isValid()) { 231596ebad66c451d79c9f57b1edb31efaeeb23b9a01Ted Kremenek if (LoadTy.isNull()) 2316bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek LoadTy = BoundEx->getType(); 23175251abea41b446c26e3239c8dd6c7edea6fc335dDavid Blaikie V = state->getSVal(location.castAs<Loc>(), LoadTy); 2318b4b817d704287836b52b34369009e682f208aa2bTed Kremenek } 23197affe151f5689b2d3547b8947c4099532c78a021Jordan Rose 23207affe151f5689b2d3547b8947c4099532c78a021Jordan Rose Bldr.generateNode(NodeEx, *NI, state->BindExpr(BoundEx, LCtx, V), tag, 23217affe151f5689b2d3547b8947c4099532c78a021Jordan Rose ProgramPoint::PostLoadKind); 2322d5b499d43c3526fae7f9ebb6e2d50e79d3496cedZhongxing Xu } 23231b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek} 23241b8bd4d71c2098126041b4de4267175a82f0103cTed Kremenek 2325bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenekvoid ExprEngine::evalLocation(ExplodedNodeSet &Dst, 2326bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek const Stmt *NodeEx, 2327bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek const Stmt *BoundEx, 2328bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek ExplodedNode *Pred, 2329bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek ProgramStateRef state, 2330bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek SVal location, 2331bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek const ProgramPointTag *tag, 2332bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek bool isLoad) { 233366c486f275531df6362b3511fc3af6563561801bTed Kremenek StmtNodeBuilder BldrTop(Pred, Dst, *currBldrCtx); 233400b1ad2d56f3e39f95c3f61bf511a531ab6a4fa5Zhongxing Xu // Early checks for performance reason. 2335769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis if (location.isUnknown()) { 2336b4b817d704287836b52b34369009e682f208aa2bTed Kremenek return; 2337b4b817d704287836b52b34369009e682f208aa2bTed Kremenek } 2338b9bbd592c7ea72ada8d982e40a729beb9b53371eTed Kremenek 23399c0d6891b3ec4b0d20b8a295946c0dc5426d147cArgyrios Kyrtzidis ExplodedNodeSet Src; 2340ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks BldrTop.takeNodes(Pred); 234166c486f275531df6362b3511fc3af6563561801bTed Kremenek StmtNodeBuilder Bldr(Pred, Src, *currBldrCtx); 2342ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks if (Pred->getState() != state) { 2343eb48bd1dd4168ab206a330bf523659170291a6a0Argyrios Kyrtzidis // Associate this new state with an ExplodedNode. 2344eb48bd1dd4168ab206a330bf523659170291a6a0Argyrios Kyrtzidis // FIXME: If I pass null tag, the graph is incorrect, e.g for 2345eb48bd1dd4168ab206a330bf523659170291a6a0Argyrios Kyrtzidis // int *p; 2346eb48bd1dd4168ab206a330bf523659170291a6a0Argyrios Kyrtzidis // p = 0; 2347eb48bd1dd4168ab206a330bf523659170291a6a0Argyrios Kyrtzidis // *p = 0xDEADBEEF; 2348eb48bd1dd4168ab206a330bf523659170291a6a0Argyrios Kyrtzidis // "p = 0" is not noted as "Null pointer value stored to 'p'" but 2349eb48bd1dd4168ab206a330bf523659170291a6a0Argyrios Kyrtzidis // instead "int *p" is noted as 2350eb48bd1dd4168ab206a330bf523659170291a6a0Argyrios Kyrtzidis // "Variable 'p' initialized to a null pointer value" 2351a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 2352651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines static SimpleProgramPointTag tag(TagProviderName, "Location"); 2353fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose Bldr.generateNode(NodeEx, Pred, state, &tag); 23540296c22557b3735e2ffeff690eb46fb0e9152bccTed Kremenek } 2355ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks ExplodedNodeSet Tmp; 2356bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek getCheckerManager().runCheckersForLocation(Tmp, Src, location, isLoad, 2357bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek NodeEx, BoundEx, *this); 2358ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks BldrTop.addNodes(Tmp); 2359ec96a2d52d16e150baaf629cd35e3fabff5d8915Ted Kremenek} 2360ec96a2d52d16e150baaf629cd35e3fabff5d8915Ted Kremenek 23616c7511db998817e64f2e124013e7d7c9a430c580Ted Kremenekstd::pair<const ProgramPointTag *, const ProgramPointTag*> 23620caa2d47b84337e942b3f6652adfafe4ae506cfeTed KremenekExprEngine::geteagerlyAssumeBinOpBifurcationTags() { 23636c7511db998817e64f2e124013e7d7c9a430c580Ted Kremenek static SimpleProgramPointTag 2364651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines eagerlyAssumeBinOpBifurcationTrue(TagProviderName, 2365651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "Eagerly Assume True"), 2366651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines eagerlyAssumeBinOpBifurcationFalse(TagProviderName, 2367651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "Eagerly Assume False"); 23680caa2d47b84337e942b3f6652adfafe4ae506cfeTed Kremenek return std::make_pair(&eagerlyAssumeBinOpBifurcationTrue, 23690caa2d47b84337e942b3f6652adfafe4ae506cfeTed Kremenek &eagerlyAssumeBinOpBifurcationFalse); 23706c7511db998817e64f2e124013e7d7c9a430c580Ted Kremenek} 23716c7511db998817e64f2e124013e7d7c9a430c580Ted Kremenek 23720caa2d47b84337e942b3f6652adfafe4ae506cfeTed Kremenekvoid ExprEngine::evalEagerlyAssumeBinOpBifurcation(ExplodedNodeSet &Dst, 23730caa2d47b84337e942b3f6652adfafe4ae506cfeTed Kremenek ExplodedNodeSet &Src, 23740caa2d47b84337e942b3f6652adfafe4ae506cfeTed Kremenek const Expr *Ex) { 237566c486f275531df6362b3511fc3af6563561801bTed Kremenek StmtNodeBuilder Bldr(Src, Dst, *currBldrCtx); 2376a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar 2377031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu for (ExplodedNodeSet::iterator I=Src.begin(), E=Src.end(); I!=E; ++I) { 2378031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu ExplodedNode *Pred = *I; 2379b293902c5cfa18365ffb0e00763849c9808a2ad1Ted Kremenek // Test if the previous node was as the same expression. This can happen 2380b293902c5cfa18365ffb0e00763849c9808a2ad1Ted Kremenek // when the expression fails to evaluate to anything meaningful and 2381b293902c5cfa18365ffb0e00763849c9808a2ad1Ted Kremenek // (as an optimization) we don't generate a node. 23821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump ProgramPoint P = Pred->getLocation(); 23837a95de68c093991047ed8d339479ccad51b88663David Blaikie if (!P.getAs<PostStmt>() || P.castAs<PostStmt>().getStmt() != Ex) { 2384b293902c5cfa18365ffb0e00763849c9808a2ad1Ted Kremenek continue; 23851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 2386b293902c5cfa18365ffb0e00763849c9808a2ad1Ted Kremenek 23878bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek ProgramStateRef state = Pred->getState(); 23885eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek SVal V = state->getSVal(Ex, Pred->getLocationContext()); 2389dc84cd5efdd3430efb22546b4ac656aa0540b210David Blaikie Optional<nonloc::SymbolVal> SEV = V.getAs<nonloc::SymbolVal>(); 23905344baa704f42b22d9df25c24ffbbf6b4716603bAnna Zaks if (SEV && SEV->isExpression()) { 23916c7511db998817e64f2e124013e7d7c9a430c580Ted Kremenek const std::pair<const ProgramPointTag *, const ProgramPointTag*> &tags = 23920caa2d47b84337e942b3f6652adfafe4ae506cfeTed Kremenek geteagerlyAssumeBinOpBifurcationTags(); 23936c7511db998817e64f2e124013e7d7c9a430c580Ted Kremenek 23946960d08b4ddf389d7c81504df7f16dc645120482Jordan Rose ProgramStateRef StateTrue, StateFalse; 2395651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::tie(StateTrue, StateFalse) = state->assume(*SEV); 23966960d08b4ddf389d7c81504df7f16dc645120482Jordan Rose 239748af2a9c1ed3259512f2d1431720add1fbe8fb5fTed Kremenek // First assume that the condition is true. 23986960d08b4ddf389d7c81504df7f16dc645120482Jordan Rose if (StateTrue) { 2399a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar SVal Val = svalBuilder.makeIntVal(1U, Ex->getType()); 24005eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek StateTrue = StateTrue->BindExpr(Ex, Pred->getLocationContext(), Val); 2401fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose Bldr.generateNode(Ex, Pred, StateTrue, tags.first); 240248af2a9c1ed3259512f2d1431720add1fbe8fb5fTed Kremenek } 24031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 240448af2a9c1ed3259512f2d1431720add1fbe8fb5fTed Kremenek // Next, assume that the condition is false. 24056960d08b4ddf389d7c81504df7f16dc645120482Jordan Rose if (StateFalse) { 240686b39f20d5091ca3fdcbeb4a22766aaffdf6ac35Ted Kremenek SVal Val = svalBuilder.makeIntVal(0U, Ex->getType()); 24075eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek StateFalse = StateFalse->BindExpr(Ex, Pred->getLocationContext(), Val); 2408fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose Bldr.generateNode(Ex, Pred, StateFalse, tags.second); 240948af2a9c1ed3259512f2d1431720add1fbe8fb5fTed Kremenek } 241048af2a9c1ed3259512f2d1431720add1fbe8fb5fTed Kremenek } 241148af2a9c1ed3259512f2d1431720add1fbe8fb5fTed Kremenek } 241248af2a9c1ed3259512f2d1431720add1fbe8fb5fTed Kremenek} 241348af2a9c1ed3259512f2d1431720add1fbe8fb5fTed Kremenek 2414df5faf5e7ae6823d0af0b801c4ac26d47f2cee97Chad Rosiervoid ExprEngine::VisitGCCAsmStmt(const GCCAsmStmt *A, ExplodedNode *Pred, 2415df5faf5e7ae6823d0af0b801c4ac26d47f2cee97Chad Rosier ExplodedNodeSet &Dst) { 241666c486f275531df6362b3511fc3af6563561801bTed Kremenek StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx); 2417a81d3d434e6581ff354eaf5b2a3c25c75771a792Erik Verbruggen // We have processed both the inputs and the outputs. All of the outputs 2418a81d3d434e6581ff354eaf5b2a3c25c75771a792Erik Verbruggen // should evaluate to Locs. Nuke all of their values. 24191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2420a81d3d434e6581ff354eaf5b2a3c25c75771a792Erik Verbruggen // FIXME: Some day in the future it would be nice to allow a "plug-in" 2421a81d3d434e6581ff354eaf5b2a3c25c75771a792Erik Verbruggen // which interprets the inline asm and stores proper results in the 2422a81d3d434e6581ff354eaf5b2a3c25c75771a792Erik Verbruggen // outputs. 24231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2424a81d3d434e6581ff354eaf5b2a3c25c75771a792Erik Verbruggen ProgramStateRef state = Pred->getState(); 24251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2426c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines for (const Expr *O : A->outputs()) { 2427c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines SVal X = state->getSVal(O, Pred->getLocationContext()); 24285251abea41b446c26e3239c8dd6c7edea6fc335dDavid Blaikie assert (!X.getAs<NonLoc>()); // Should be an Lval, or unknown, undef. 24291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2430dc84cd5efdd3430efb22546b4ac656aa0540b210David Blaikie if (Optional<Loc> LV = X.getAs<Loc>()) 24315251abea41b446c26e3239c8dd6c7edea6fc335dDavid Blaikie state = state->bindLoc(*LV, UnknownVal()); 2432ef44bfb9d0f15ba0391f8346c9f01355fb450a09Ted Kremenek } 24331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2434a81d3d434e6581ff354eaf5b2a3c25c75771a792Erik Verbruggen Bldr.generateNode(A, Pred, state); 2435ef44bfb9d0f15ba0391f8346c9f01355fb450a09Ted Kremenek} 2436ef44bfb9d0f15ba0391f8346c9f01355fb450a09Ted Kremenek 24378cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosiervoid ExprEngine::VisitMSAsmStmt(const MSAsmStmt *A, ExplodedNode *Pred, 24388cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier ExplodedNodeSet &Dst) { 243966c486f275531df6362b3511fc3af6563561801bTed Kremenek StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx); 24408cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier Bldr.generateNode(A, Pred, Pred->getState()); 24418cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier} 24428cd64b4c5553fa6284d248336cb7c82dc960a394Chad Rosier 2443094bef56a7900f13bb777f9a352704104b1458e7Ted Kremenek//===----------------------------------------------------------------------===// 2444e01c98767dfd7153c3c84637c36659e3bbe16ff7Ted Kremenek// Visualization. 2445ee98546b0d5f3439c4a590b0d7d1545af794a0ecTed Kremenek//===----------------------------------------------------------------------===// 2446ee98546b0d5f3439c4a590b0d7d1545af794a0ecTed Kremenek 2447aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek#ifndef NDEBUG 2448d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisstatic ExprEngine* GraphPrintCheckerState; 2449e97ca065c91ff9ca2a2a42eb443eaa553c40441cTed Kremenekstatic SourceManager* GraphPrintSourceManager; 24503b4f6702860208692f6ef28401e68de4e3ff9af9Ted Kremenek 2451aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremeneknamespace llvm { 2452aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenektemplate<> 245347491f8b7adf9d42a404d44c073e8a5308fa6cfcDouglas Gregorstruct DOTGraphTraits<ExplodedNode*> : 2454aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek public DefaultDOTGraphTraits { 2455006b0eb3e11162d8c06372db813ac9f71a7a16e8Tobias Grosser 2456006b0eb3e11162d8c06372db813ac9f71a7a16e8Tobias Grosser DOTGraphTraits (bool isSimple=false) : DefaultDOTGraphTraits(isSimple) {} 2457006b0eb3e11162d8c06372db813ac9f71a7a16e8Tobias Grosser 2458d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis // FIXME: Since we do not cache error nodes in ExprEngine now, this does not 2459ec9227fea66c3439991fc84b0d33b0a8b4b8875eZhongxing Xu // work. 24609c378f705405d37f49795d5e915989de774fe11fTed Kremenek static std::string getNodeAttributes(const ExplodedNode *N, void*) { 24611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 246210f51e8785e43d5a22acc2d2a638307c582949c2Ted Kremenek#if 0 246310f51e8785e43d5a22acc2d2a638307c582949c2Ted Kremenek // FIXME: Replace with a general scheme to tell if the node is 246410f51e8785e43d5a22acc2d2a638307c582949c2Ted Kremenek // an error node. 2465a3fadfcce5911742801a302cac82d4fe54d5c682Ted Kremenek if (GraphPrintCheckerState->isImplicitNullDeref(N) || 24669dca062461a6244cf0f733346657fa3eee853f9bTed Kremenek GraphPrintCheckerState->isExplicitNullDeref(N) || 24674a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek GraphPrintCheckerState->isUndefDeref(N) || 24684a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek GraphPrintCheckerState->isUndefStore(N) || 24694a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek GraphPrintCheckerState->isUndefControlFlow(N) || 24705e03fcb5420c33207433dd6f800588e256dd9bdbTed Kremenek GraphPrintCheckerState->isUndefResult(N) || 24712ded35a576e3899553ea0ccfcbf5cbdb3d8cf664Ted Kremenek GraphPrintCheckerState->isBadCall(N) || 24722ded35a576e3899553ea0ccfcbf5cbdb3d8cf664Ted Kremenek GraphPrintCheckerState->isUndefArg(N)) 2473a3fadfcce5911742801a302cac82d4fe54d5c682Ted Kremenek return "color=\"red\",style=\"filled\""; 24741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 24758cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek if (GraphPrintCheckerState->isNoReturnCall(N)) 24768cc13ea74fea1c04042a2f4087665bc5182e8408Ted Kremenek return "color=\"blue\",style=\"filled\""; 24772055effed54d614b51e3501a174c9b1fe92e4de4Zhongxing Xu#endif 2478a3fadfcce5911742801a302cac82d4fe54d5c682Ted Kremenek return ""; 2479a3fadfcce5911742801a302cac82d4fe54d5c682Ted Kremenek } 24801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2481cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko static void printLocation(raw_ostream &Out, SourceLocation SLoc) { 248228038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose if (SLoc.isFileID()) { 248328038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose Out << "\\lline=" 248428038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose << GraphPrintSourceManager->getExpansionLineNumber(SLoc) 248528038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose << " col=" 248628038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose << GraphPrintSourceManager->getExpansionColumnNumber(SLoc) 248728038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose << "\\l"; 248828038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose } 248928038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose } 249028038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose 24919c378f705405d37f49795d5e915989de774fe11fTed Kremenek static std::string getNodeLabel(const ExplodedNode *N, void*){ 24921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 249353ba0b636194dbeaa65a6f85316c9397a0c5298bTed Kremenek std::string sbuf; 249453ba0b636194dbeaa65a6f85316c9397a0c5298bTed Kremenek llvm::raw_string_ostream Out(sbuf); 2495803c9edd06e8f936821525d36b1d8cc131e37d44Ted Kremenek 2496803c9edd06e8f936821525d36b1d8cc131e37d44Ted Kremenek // Program Location. 2497aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek ProgramPoint Loc = N->getLocation(); 24981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2499aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek switch (Loc.getKind()) { 25000b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks case ProgramPoint::BlockEntranceKind: { 25011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Out << "Block Entrance: B" 25027a95de68c093991047ed8d339479ccad51b88663David Blaikie << Loc.castAs<BlockEntrance>().getBlock()->getBlockID(); 25030b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks if (const NamedDecl *ND = 25040b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks dyn_cast<NamedDecl>(Loc.getLocationContext()->getDecl())) { 25050b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks Out << " ("; 25060b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks ND->printName(Out); 25070b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks Out << ")"; 25080b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks } 2509aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek break; 25100b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks } 25111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2512aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek case ProgramPoint::BlockExitKind: 2513aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek assert (false); 2514aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek break; 25151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2516102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor case ProgramPoint::CallEnterKind: 2517102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor Out << "CallEnter"; 2518102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor break; 2519102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor 25200b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks case ProgramPoint::CallExitBeginKind: 25210b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks Out << "CallExitBegin"; 25220b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks break; 25230b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks 25240b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks case ProgramPoint::CallExitEndKind: 25250b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks Out << "CallExitEnd"; 25260b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks break; 25270b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks 25280b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks case ProgramPoint::PostStmtPurgeDeadSymbolsKind: 25290b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks Out << "PostStmtPurgeDeadSymbols"; 25300b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks break; 25310b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks 25320b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks case ProgramPoint::PreStmtPurgeDeadSymbolsKind: 25330b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks Out << "PreStmtPurgeDeadSymbols"; 2534102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor break; 2535102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor 25365903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks case ProgramPoint::EpsilonKind: 25375903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks Out << "Epsilon Point"; 25385903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks break; 25395903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks 254028038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose case ProgramPoint::PreImplicitCallKind: { 25417a95de68c093991047ed8d339479ccad51b88663David Blaikie ImplicitCallPoint PC = Loc.castAs<ImplicitCallPoint>(); 254228038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose Out << "PreCall: "; 254328038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose 254428038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose // FIXME: Get proper printing options. 25457a95de68c093991047ed8d339479ccad51b88663David Blaikie PC.getDecl()->print(Out, LangOptions()); 25467a95de68c093991047ed8d339479ccad51b88663David Blaikie printLocation(Out, PC.getLocation()); 254728038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose break; 254828038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose } 254928038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose 255028038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose case ProgramPoint::PostImplicitCallKind: { 25517a95de68c093991047ed8d339479ccad51b88663David Blaikie ImplicitCallPoint PC = Loc.castAs<ImplicitCallPoint>(); 255228038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose Out << "PostCall: "; 255328038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose 255428038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose // FIXME: Get proper printing options. 25557a95de68c093991047ed8d339479ccad51b88663David Blaikie PC.getDecl()->print(Out, LangOptions()); 25567a95de68c093991047ed8d339479ccad51b88663David Blaikie printLocation(Out, PC.getLocation()); 255728038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose break; 255828038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose } 255928038f33aa2db4833881fea757a1f0daf85ac02bJordan Rose 25601aa4f5019164592643bf46b7d61f15b6ef509c8eJordan Rose case ProgramPoint::PostInitializerKind: { 25611aa4f5019164592643bf46b7d61f15b6ef509c8eJordan Rose Out << "PostInitializer: "; 25621aa4f5019164592643bf46b7d61f15b6ef509c8eJordan Rose const CXXCtorInitializer *Init = 25631aa4f5019164592643bf46b7d61f15b6ef509c8eJordan Rose Loc.castAs<PostInitializer>().getInitializer(); 25641aa4f5019164592643bf46b7d61f15b6ef509c8eJordan Rose if (const FieldDecl *FD = Init->getAnyMember()) 25651aa4f5019164592643bf46b7d61f15b6ef509c8eJordan Rose Out << *FD; 25661aa4f5019164592643bf46b7d61f15b6ef509c8eJordan Rose else { 25671aa4f5019164592643bf46b7d61f15b6ef509c8eJordan Rose QualType Ty = Init->getTypeSourceInfo()->getType(); 25681aa4f5019164592643bf46b7d61f15b6ef509c8eJordan Rose Ty = Ty.getLocalUnqualifiedType(); 2569e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner LangOptions LO; // FIXME. 25701aa4f5019164592643bf46b7d61f15b6ef509c8eJordan Rose Ty.print(Out, LO); 25718c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek } 25721aa4f5019164592643bf46b7d61f15b6ef509c8eJordan Rose break; 25731aa4f5019164592643bf46b7d61f15b6ef509c8eJordan Rose } 25748c354758c2d39db87c77c723d81e34b4d967f762Ted Kremenek 25751aa4f5019164592643bf46b7d61f15b6ef509c8eJordan Rose case ProgramPoint::BlockEdgeKind: { 25767a95de68c093991047ed8d339479ccad51b88663David Blaikie const BlockEdge &E = Loc.castAs<BlockEdge>(); 2577aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek Out << "Edge: (B" << E.getSrc()->getBlockID() << ", B" 2578aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek << E.getDst()->getBlockID() << ')'; 25791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 25809c378f705405d37f49795d5e915989de774fe11fTed Kremenek if (const Stmt *T = E.getSrc()->getTerminator()) { 2581e97ca065c91ff9ca2a2a42eb443eaa553c40441cTed Kremenek SourceLocation SLoc = T->getLocStart(); 25821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2583b38911f16b4943548db6a3695fc6ae23070b25d2Ted Kremenek Out << "\\|Terminator: "; 2584e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner LangOptions LO; // FIXME. 2585e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner E.getSrc()->printTerminator(Out, LO); 25861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 25879b5551d7f0209cec8b9c555cf70e893940674e5cTed Kremenek if (SLoc.isFileID()) { 25889b5551d7f0209cec8b9c555cf70e893940674e5cTed Kremenek Out << "\\lline=" 2589642116259e8df6286063a17361c20e95b5017a0aChandler Carruth << GraphPrintSourceManager->getExpansionLineNumber(SLoc) 25907da5aea7669e6db3e593162b8a123aef06a04d07Chris Lattner << " col=" 2591a77c031cb66f75d22672070052cc6e0205289ff8Chandler Carruth << GraphPrintSourceManager->getExpansionColumnNumber(SLoc); 25929b5551d7f0209cec8b9c555cf70e893940674e5cTed Kremenek } 25931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2594daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek if (isa<SwitchStmt>(T)) { 25959c378f705405d37f49795d5e915989de774fe11fTed Kremenek const Stmt *Label = E.getDst()->getLabel(); 25961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 25971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (Label) { 25989c378f705405d37f49795d5e915989de774fe11fTed Kremenek if (const CaseStmt *C = dyn_cast<CaseStmt>(Label)) { 2599daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek Out << "\\lcase "; 2600e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner LangOptions LO; // FIXME. 2601c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (C->getLHS()) 2602c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines C->getLHS()->printPretty(Out, nullptr, PrintingPolicy(LO)); 26031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 26049c378f705405d37f49795d5e915989de774fe11fTed Kremenek if (const Stmt *RHS = C->getRHS()) { 2605daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek Out << " .. "; 26066bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines RHS->printPretty(Out, nullptr, PrintingPolicy(LO)); 2607daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek } 26081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2609daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek Out << ":"; 2610daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek } 2611daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek else { 2612daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek assert (isa<DefaultStmt>(Label)); 2613daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek Out << "\\ldefault:"; 2614daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek } 2615daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek } 26161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump else 2617daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek Out << "\\l(implicit) default:"; 2618daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek } 2619daeb9a7376830d637e02b5bc51faf4750a7bce70Ted Kremenek else if (isa<IndirectGotoStmt>(T)) { 2620b38911f16b4943548db6a3695fc6ae23070b25d2Ted Kremenek // FIXME 2621b38911f16b4943548db6a3695fc6ae23070b25d2Ted Kremenek } 2622b38911f16b4943548db6a3695fc6ae23070b25d2Ted Kremenek else { 2623b38911f16b4943548db6a3695fc6ae23070b25d2Ted Kremenek Out << "\\lCondition: "; 2624b38911f16b4943548db6a3695fc6ae23070b25d2Ted Kremenek if (*E.getSrc()->succ_begin() == E.getDst()) 2625b38911f16b4943548db6a3695fc6ae23070b25d2Ted Kremenek Out << "true"; 2626b38911f16b4943548db6a3695fc6ae23070b25d2Ted Kremenek else 26271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Out << "false"; 2628b38911f16b4943548db6a3695fc6ae23070b25d2Ted Kremenek } 26291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2630b38911f16b4943548db6a3695fc6ae23070b25d2Ted Kremenek Out << "\\l"; 2631b38911f16b4943548db6a3695fc6ae23070b25d2Ted Kremenek } 26321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 263310f51e8785e43d5a22acc2d2a638307c582949c2Ted Kremenek#if 0 263410f51e8785e43d5a22acc2d2a638307c582949c2Ted Kremenek // FIXME: Replace with a general scheme to determine 263510f51e8785e43d5a22acc2d2a638307c582949c2Ted Kremenek // the name of the check. 26364a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek if (GraphPrintCheckerState->isUndefControlFlow(N)) { 26374a4e524afef40d6f3ddb25d0e407c814e4ca56a8Ted Kremenek Out << "\\|Control-flow based on\\lUndefined value.\\l"; 26383b4f6702860208692f6ef28401e68de4e3ff9af9Ted Kremenek } 263910f51e8785e43d5a22acc2d2a638307c582949c2Ted Kremenek#endif 26401aa4f5019164592643bf46b7d61f15b6ef509c8eJordan Rose break; 26411aa4f5019164592643bf46b7d61f15b6ef509c8eJordan Rose } 26421aa4f5019164592643bf46b7d61f15b6ef509c8eJordan Rose 26431aa4f5019164592643bf46b7d61f15b6ef509c8eJordan Rose default: { 26441aa4f5019164592643bf46b7d61f15b6ef509c8eJordan Rose const Stmt *S = Loc.castAs<StmtPoint>().getStmt(); 2645c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines assert(S != nullptr && "Expecting non-null Stmt"); 26461aa4f5019164592643bf46b7d61f15b6ef509c8eJordan Rose 26471aa4f5019164592643bf46b7d61f15b6ef509c8eJordan Rose Out << S->getStmtClassName() << ' ' << (const void*) S << ' '; 26481aa4f5019164592643bf46b7d61f15b6ef509c8eJordan Rose LangOptions LO; // FIXME. 26496bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines S->printPretty(Out, nullptr, PrintingPolicy(LO)); 26501aa4f5019164592643bf46b7d61f15b6ef509c8eJordan Rose printLocation(Out, S->getLocStart()); 26511aa4f5019164592643bf46b7d61f15b6ef509c8eJordan Rose 26521aa4f5019164592643bf46b7d61f15b6ef509c8eJordan Rose if (Loc.getAs<PreStmt>()) 26531aa4f5019164592643bf46b7d61f15b6ef509c8eJordan Rose Out << "\\lPreStmt\\l;"; 26541aa4f5019164592643bf46b7d61f15b6ef509c8eJordan Rose else if (Loc.getAs<PostLoad>()) 26551aa4f5019164592643bf46b7d61f15b6ef509c8eJordan Rose Out << "\\lPostLoad\\l;"; 26561aa4f5019164592643bf46b7d61f15b6ef509c8eJordan Rose else if (Loc.getAs<PostStore>()) 26571aa4f5019164592643bf46b7d61f15b6ef509c8eJordan Rose Out << "\\lPostStore\\l"; 26581aa4f5019164592643bf46b7d61f15b6ef509c8eJordan Rose else if (Loc.getAs<PostLValue>()) 26591aa4f5019164592643bf46b7d61f15b6ef509c8eJordan Rose Out << "\\lPostLValue\\l"; 26601aa4f5019164592643bf46b7d61f15b6ef509c8eJordan Rose 26611aa4f5019164592643bf46b7d61f15b6ef509c8eJordan Rose#if 0 26621aa4f5019164592643bf46b7d61f15b6ef509c8eJordan Rose // FIXME: Replace with a general scheme to determine 26631aa4f5019164592643bf46b7d61f15b6ef509c8eJordan Rose // the name of the check. 26641aa4f5019164592643bf46b7d61f15b6ef509c8eJordan Rose if (GraphPrintCheckerState->isImplicitNullDeref(N)) 26651aa4f5019164592643bf46b7d61f15b6ef509c8eJordan Rose Out << "\\|Implicit-Null Dereference.\\l"; 26661aa4f5019164592643bf46b7d61f15b6ef509c8eJordan Rose else if (GraphPrintCheckerState->isExplicitNullDeref(N)) 26671aa4f5019164592643bf46b7d61f15b6ef509c8eJordan Rose Out << "\\|Explicit-Null Dereference.\\l"; 26681aa4f5019164592643bf46b7d61f15b6ef509c8eJordan Rose else if (GraphPrintCheckerState->isUndefDeref(N)) 26691aa4f5019164592643bf46b7d61f15b6ef509c8eJordan Rose Out << "\\|Dereference of undefialied value.\\l"; 26701aa4f5019164592643bf46b7d61f15b6ef509c8eJordan Rose else if (GraphPrintCheckerState->isUndefStore(N)) 26711aa4f5019164592643bf46b7d61f15b6ef509c8eJordan Rose Out << "\\|Store to Undefined Loc."; 26721aa4f5019164592643bf46b7d61f15b6ef509c8eJordan Rose else if (GraphPrintCheckerState->isUndefResult(N)) 26731aa4f5019164592643bf46b7d61f15b6ef509c8eJordan Rose Out << "\\|Result of operation is undefined."; 26741aa4f5019164592643bf46b7d61f15b6ef509c8eJordan Rose else if (GraphPrintCheckerState->isNoReturnCall(N)) 26751aa4f5019164592643bf46b7d61f15b6ef509c8eJordan Rose Out << "\\|Call to function marked \"noreturn\"."; 26761aa4f5019164592643bf46b7d61f15b6ef509c8eJordan Rose else if (GraphPrintCheckerState->isBadCall(N)) 26771aa4f5019164592643bf46b7d61f15b6ef509c8eJordan Rose Out << "\\|Call to NULL/Undefined."; 26781aa4f5019164592643bf46b7d61f15b6ef509c8eJordan Rose else if (GraphPrintCheckerState->isUndefArg(N)) 26791aa4f5019164592643bf46b7d61f15b6ef509c8eJordan Rose Out << "\\|Argument in call is undefined"; 26801aa4f5019164592643bf46b7d61f15b6ef509c8eJordan Rose#endif 26811aa4f5019164592643bf46b7d61f15b6ef509c8eJordan Rose 26821aa4f5019164592643bf46b7d61f15b6ef509c8eJordan Rose break; 2683aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek } 2684aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek } 26851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 26868bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek ProgramStateRef state = N->getState(); 2687c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Out << "\\|StateID: " << (const void*) state.get() 268831ba6135375433b617a8587ea6cc836a014ebd86Roman Divacky << " NodeID: " << (const void*) N << "\\|"; 26895eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek state->printDOT(Out); 2690ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek 2691a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar Out << "\\l"; 2692ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek 2693ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek if (const ProgramPointTag *tag = Loc.getTag()) { 2694a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar Out << "\\|Tag: " << tag->getTagDescription(); 2695ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek Out << "\\l"; 2696ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek } 2697aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek return Out.str(); 2698aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek } 2699aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek}; 27001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump} // end llvm namespace 2701aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek#endif 2702aa66a32ba177338763cd0cf9df8310dfa2e24ff7Ted Kremenek 2703d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisvoid ExprEngine::ViewGraph(bool trim) { 27041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump#ifndef NDEBUG 2705ffe0f43806d4823271c2406c1fccc2373115c36aTed Kremenek if (trim) { 2706c9963132736782d0c9178c744b3e2307cfb98a08Jordan Rose std::vector<const ExplodedNode*> Src; 2707940abcc574580e454689be801f38a3d4d41ab01fTed Kremenek 2708940abcc574580e454689be801f38a3d4d41ab01fTed Kremenek // Flush any outstanding reports to make sure we cover all the nodes. 2709940abcc574580e454689be801f38a3d4d41ab01fTed Kremenek // This does not cause them to get displayed. 2710940abcc574580e454689be801f38a3d4d41ab01fTed Kremenek for (BugReporter::iterator I=BR.begin(), E=BR.end(); I!=E; ++I) 2711940abcc574580e454689be801f38a3d4d41ab01fTed Kremenek const_cast<BugType*>(*I)->FlushReports(BR); 2712940abcc574580e454689be801f38a3d4d41ab01fTed Kremenek 2713940abcc574580e454689be801f38a3d4d41ab01fTed Kremenek // Iterate through the reports and get their nodes. 2714404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis for (BugReporter::EQClasses_iterator 2715404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis EI = BR.EQClasses_begin(), EE = BR.EQClasses_end(); EI != EE; ++EI) { 27164a5f724538cbc275370c9504e8169ce92503256cBenjamin Kramer ExplodedNode *N = const_cast<ExplodedNode*>(EI->begin()->getErrorNode()); 2717404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis if (N) Src.push_back(N); 2718940abcc574580e454689be801f38a3d4d41ab01fTed Kremenek } 27191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2720c9963132736782d0c9178c744b3e2307cfb98a08Jordan Rose ViewGraph(Src); 2721ffe0f43806d4823271c2406c1fccc2373115c36aTed Kremenek } 2722493d7a26d5ea319770ba904b43f2740d43b820cbTed Kremenek else { 2723493d7a26d5ea319770ba904b43f2740d43b820cbTed Kremenek GraphPrintCheckerState = this; 2724493d7a26d5ea319770ba904b43f2740d43b820cbTed Kremenek GraphPrintSourceManager = &getContext().getSourceManager(); 2725ae6814efb6c41bd0c0f6413d25097105284d5be7Ted Kremenek 2726d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis llvm::ViewGraph(*G.roots_begin(), "ExprEngine"); 27271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 27286bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines GraphPrintCheckerState = nullptr; 27296bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines GraphPrintSourceManager = nullptr; 2730493d7a26d5ea319770ba904b43f2740d43b820cbTed Kremenek } 2731493d7a26d5ea319770ba904b43f2740d43b820cbTed Kremenek#endif 2732493d7a26d5ea319770ba904b43f2740d43b820cbTed Kremenek} 2733493d7a26d5ea319770ba904b43f2740d43b820cbTed Kremenek 2734c9963132736782d0c9178c744b3e2307cfb98a08Jordan Rosevoid ExprEngine::ViewGraph(ArrayRef<const ExplodedNode*> Nodes) { 2735493d7a26d5ea319770ba904b43f2740d43b820cbTed Kremenek#ifndef NDEBUG 2736493d7a26d5ea319770ba904b43f2740d43b820cbTed Kremenek GraphPrintCheckerState = this; 2737493d7a26d5ea319770ba904b43f2740d43b820cbTed Kremenek GraphPrintSourceManager = &getContext().getSourceManager(); 27381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2739651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::unique_ptr<ExplodedGraph> TrimmedG(G.trim(Nodes)); 2740493d7a26d5ea319770ba904b43f2740d43b820cbTed Kremenek 2741cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek if (!TrimmedG.get()) 27426cb7c1a43b0c8f739d1f54b7fdae5ede86033496Benjamin Kramer llvm::errs() << "warning: Trimmed ExplodedGraph is empty.\n"; 2743cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek else 2744d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis llvm::ViewGraph(*TrimmedG->roots_begin(), "TrimmedExprEngine"); 27451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 27466bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines GraphPrintCheckerState = nullptr; 27476bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines GraphPrintSourceManager = nullptr; 2748e01c98767dfd7153c3c84637c36659e3bbe16ff7Ted Kremenek#endif 2749ee98546b0d5f3439c4a590b0d7d1545af794a0ecTed Kremenek} 2750