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" 296cb7c1a43b0c8f739d1f54b7fdae5ede86033496Benjamin Kramer#include "llvm/ADT/ImmutableList.h" 30c2994283aa7538b7420c8e398cde7afa328d7042Anna Zaks#include "llvm/ADT/Statistic.h" 3155fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "llvm/Support/raw_ostream.h" 324323a57627e796dcfdfdb7d47672dc09ed308edaTed Kremenek 330f5f0595d6a038843a7051c5a65fca7bce2915a0Ted Kremenek#ifndef NDEBUG 340f5f0595d6a038843a7051c5a65fca7bce2915a0Ted Kremenek#include "llvm/Support/GraphWriter.h" 350f5f0595d6a038843a7051c5a65fca7bce2915a0Ted Kremenek#endif 360f5f0595d6a038843a7051c5a65fca7bce2915a0Ted Kremenek 37b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenekusing namespace clang; 389ef6537a894c33003359b1f9b9676e9178e028b7Ted Kremenekusing namespace ento; 39b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenekusing llvm::APSInt; 40ab2b8c54bca82866876f91e756788916d3fa20c3Ted Kremenek 416bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#define DEBUG_TYPE "ExprEngine" 426bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 43c2994283aa7538b7420c8e398cde7afa328d7042Anna ZaksSTATISTIC(NumRemoveDeadBindings, 44c2994283aa7538b7420c8e398cde7afa328d7042Anna Zaks "The # of times RemoveDeadBindings is called"); 45749bbe6f5f23676244f12a0d41511c8e73516febAnna ZaksSTATISTIC(NumMaxBlockCountReached, 46749bbe6f5f23676244f12a0d41511c8e73516febAnna Zaks "The # of aborted paths due to reaching the maximum block count in " 47749bbe6f5f23676244f12a0d41511c8e73516febAnna Zaks "a top level function"); 48749bbe6f5f23676244f12a0d41511c8e73516febAnna ZaksSTATISTIC(NumMaxBlockCountReachedInInlined, 49749bbe6f5f23676244f12a0d41511c8e73516febAnna Zaks "The # of aborted paths due to reaching the maximum block count in " 50749bbe6f5f23676244f12a0d41511c8e73516febAnna Zaks "an inlined function"); 515903a373db3d27794c90b25687e0dd6adb0e497dAnna ZaksSTATISTIC(NumTimesRetriedWithoutInlining, 525903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks "The # of times we re-evaluated a call without inlining"); 535903a373db3d27794c90b25687e0dd6adb0e497dAnna Zaks 54e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek//===----------------------------------------------------------------------===// 55bdb435ddaafd5069becd543d638112f68825b89dTed Kremenek// Engine construction and deletion. 56bdb435ddaafd5069becd543d638112f68825b89dTed Kremenek//===----------------------------------------------------------------------===// 57bdb435ddaafd5069becd543d638112f68825b89dTed Kremenek 58651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstatic const char* TagProviderName = "ExprEngine"; 59651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 603fd5f370a28552976c52e76c3035d79012d78ddaAnna ZaksExprEngine::ExprEngine(AnalysisManager &mgr, bool gcEnabled, 61fbcb3f11fc90e9f00e6074e9b118b8dc11ca604cAnna Zaks SetOfConstDecls *VisitedCalleesIn, 6275f31c4862643ab09479c979fabf754e7ffe1460Anna Zaks FunctionSummariesTy *FS, 6375f31c4862643ab09479c979fabf754e7ffe1460Anna Zaks InliningModes HowToInlineIn) 6425e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu : AMgr(mgr), 651d26f48dc2eea1c07431ca1519d7034a21b9bcffTed Kremenek AnalysisDeclContexts(mgr.getAnalysisDeclContextManager()), 66fbcb3f11fc90e9f00e6074e9b118b8dc11ca604cAnna Zaks Engine(*this, FS), 67d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis G(Engine.getGraph()), 68c77a55126fcad66fb086f8e100a494caa2496a2dZhongxing Xu StateMgr(getContext(), mgr.getStoreManagerCreator(), 6932a58084a4c53e6938dd81bfce224db25a5976d1Ted Kremenek mgr.getConstraintManagerCreator(), G.getAllocator(), 70ca5d78d0bc3010164f2f9682967d64d7e305a167Jordan Rose this), 7150a6d0ce344c02782e0207574005c3b2aaa5077cTed Kremenek SymMgr(StateMgr.getSymbolManager()), 72c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek svalBuilder(StateMgr.getSValBuilder()), 736bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines currStmtIdx(0), currBldrCtx(nullptr), 744ef19205b6912316296db74a9073ad6fa60e4ccaTed Kremenek ObjCNoRet(mgr.getASTContext()), 75fbcb3f11fc90e9f00e6074e9b118b8dc11ca604cAnna Zaks ObjCGCEnabled(gcEnabled), BR(mgr, *this), 7675f31c4862643ab09479c979fabf754e7ffe1460Anna Zaks VisitedCallees(VisitedCalleesIn), 7775f31c4862643ab09479c979fabf754e7ffe1460Anna Zaks HowToInline(HowToInlineIn) 78255d4d4226b24036ceb11228fbb74286e58620f7Ted Kremenek{ 794d9e497a2b1eab3b1214848216050c64fc3acfd6Jordan Rose unsigned TrimInterval = mgr.options.getGraphTrimInterval(); 804d9e497a2b1eab3b1214848216050c64fc3acfd6Jordan Rose if (TrimInterval != 0) { 814d9e497a2b1eab3b1214848216050c64fc3acfd6Jordan Rose // Enable eager node reclaimation when constructing the ExplodedGraph. 824d9e497a2b1eab3b1214848216050c64fc3acfd6Jordan Rose G.enableNodeReclamation(TrimInterval); 834d9e497a2b1eab3b1214848216050c64fc3acfd6Jordan Rose } 84c80135ba857da48173578b9c528fce6777e18168Ted Kremenek} 8550a6d0ce344c02782e0207574005c3b2aaa5077cTed Kremenek 86d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios KyrtzidisExprEngine::~ExprEngine() { 87cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek BR.FlushReports(); 8850a6d0ce344c02782e0207574005c3b2aaa5077cTed Kremenek} 8950a6d0ce344c02782e0207574005c3b2aaa5077cTed Kremenek 90e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek//===----------------------------------------------------------------------===// 91e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek// Utility methods. 92e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek//===----------------------------------------------------------------------===// 93e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek 948bef8238181a30e52dea380789a7e2d760eac532Ted KremenekProgramStateRef ExprEngine::getInitialState(const LocationContext *InitLoc) { 958bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek ProgramStateRef state = StateMgr.getInitialState(InitLoc); 96a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek const Decl *D = InitLoc->getDecl(); 971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 98cfcd7fd0de701c5ce05e96de1ed2d0bf8c7035d9Ted Kremenek // Preconditions. 9952e5602056e4cade24cbcca57767e94e1d430b03Ted Kremenek // FIXME: It would be nice if we had a more general mechanism to add 10052e5602056e4cade24cbcca57767e94e1d430b03Ted Kremenek // such preconditions. Some day. 1015974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek do { 102a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek 1035974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 1045974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek // Precondition: the first argument of 'main' is an integer guaranteed 1055974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek // to be > 0. 1065974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek const IdentifierInfo *II = FD->getIdentifier(); 1075974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek if (!II || !(II->getName() == "main" && FD->getNumParams() > 0)) 1085974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek break; 1095974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek 1105974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek const ParmVarDecl *PD = FD->getParamDecl(0); 1115974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek QualType T = PD->getType(); 112a5796f87229b4aeebca71fa6ee1790ae7a5a0382Jordan Rose const BuiltinType *BT = dyn_cast<BuiltinType>(T); 113a5796f87229b4aeebca71fa6ee1790ae7a5a0382Jordan Rose if (!BT || !BT->isInteger()) 1145974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek break; 115b9bbd592c7ea72ada8d982e40a729beb9b53371eTed Kremenek 1165974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek const MemRegion *R = state->getRegion(PD, InitLoc); 1175974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek if (!R) 1185974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek break; 119b9bbd592c7ea72ada8d982e40a729beb9b53371eTed Kremenek 1201397663af9dbcc24dbf0e11de43931b3dc08fdbbTed Kremenek SVal V = state->getSVal(loc::MemRegionVal(R)); 1219c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek SVal Constraint_untested = evalBinOp(state, BO_GT, V, 122c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek svalBuilder.makeZeroVal(T), 123651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines svalBuilder.getConditionType()); 1245974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek 125dc84cd5efdd3430efb22546b4ac656aa0540b210David Blaikie Optional<DefinedOrUnknownSVal> Constraint = 126dc84cd5efdd3430efb22546b4ac656aa0540b210David Blaikie Constraint_untested.getAs<DefinedOrUnknownSVal>(); 127b9bbd592c7ea72ada8d982e40a729beb9b53371eTed Kremenek 1285974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek if (!Constraint) 1295974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek break; 130b9bbd592c7ea72ada8d982e40a729beb9b53371eTed Kremenek 1318bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek if (ProgramStateRef newState = state->assume(*Constraint, true)) 1325974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek state = newState; 13352e5602056e4cade24cbcca57767e94e1d430b03Ted Kremenek } 134a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek break; 135a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek } 136a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek while (0); 137a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek 138a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) { 139a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek // Precondition: 'self' is always non-null upon entry to an Objective-C 140a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek // method. 141a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek const ImplicitParamDecl *SelfD = MD->getSelfDecl(); 142a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek const MemRegion *R = state->getRegion(SelfD, InitLoc); 143a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek SVal V = state->getSVal(loc::MemRegionVal(R)); 144a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek 145dc84cd5efdd3430efb22546b4ac656aa0540b210David Blaikie if (Optional<Loc> LV = V.getAs<Loc>()) { 146a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek // Assume that the pointer value in 'self' is non-null. 147a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek state = state->assume(*LV, true); 148a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek assert(state && "'self' cannot be null"); 149a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek } 150a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek } 1515974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek 152a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) { 153a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek if (!MD->isStatic()) { 154a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek // Precondition: 'this' is always non-null upon entry to the 155a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek // top-level function. This is our starting assumption for 156a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek // analyzing an "open" program. 157a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek const StackFrameContext *SFC = InitLoc->getCurrentStackFrame(); 1586bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (SFC->getParent() == nullptr) { 15910f77ad7fc5e5cf3f37a9b14ff5843468b8b84d2Ted Kremenek loc::MemRegionVal L = svalBuilder.getCXXThis(MD, SFC); 160a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek SVal V = state->getSVal(L); 161dc84cd5efdd3430efb22546b4ac656aa0540b210David Blaikie if (Optional<Loc> LV = V.getAs<Loc>()) { 162a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek state = state->assume(*LV, true); 163a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek assert(state && "'this' cannot be null"); 164a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek } 1655974ec518289a719fdd18122060bbcfe49d439e3Ted Kremenek } 166cfcd7fd0de701c5ce05e96de1ed2d0bf8c7035d9Ted Kremenek } 167a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek } 168a078ecf3484d62b01d9f8c01e0fecffd65c583e1Ted Kremenek 16952e5602056e4cade24cbcca57767e94e1d430b03Ted Kremenek return state; 170e070a1df66aab6d4168fb28f7559fdf996df3567Ted Kremenek} 171e070a1df66aab6d4168fb28f7559fdf996df3567Ted Kremenek 1725e5440ba9c135f523f72e7e7c5da59d390d697c5Jordan RoseProgramStateRef 1735e5440ba9c135f523f72e7e7c5da59d390d697c5Jordan RoseExprEngine::createTemporaryRegionIfNeeded(ProgramStateRef State, 1745e5440ba9c135f523f72e7e7c5da59d390d697c5Jordan Rose const LocationContext *LC, 1755e5440ba9c135f523f72e7e7c5da59d390d697c5Jordan Rose const Expr *Ex, 1765e5440ba9c135f523f72e7e7c5da59d390d697c5Jordan Rose const Expr *Result) { 17787193dac8f2c6c8f7ee1aa9eeb64622ec75c881bJordan Rose SVal V = State->getSVal(Ex, LC); 17808291a937a149dbd036fd6ac8ab061eb8034343dJordan Rose if (!Result) { 17908291a937a149dbd036fd6ac8ab061eb8034343dJordan Rose // If we don't have an explicit result expression, we're in "if needed" 18008291a937a149dbd036fd6ac8ab061eb8034343dJordan Rose // mode. Only create a region if the current value is a NonLoc. 18108291a937a149dbd036fd6ac8ab061eb8034343dJordan Rose if (!V.getAs<NonLoc>()) 18208291a937a149dbd036fd6ac8ab061eb8034343dJordan Rose return State; 18308291a937a149dbd036fd6ac8ab061eb8034343dJordan Rose Result = Ex; 18408291a937a149dbd036fd6ac8ab061eb8034343dJordan Rose } else { 18508291a937a149dbd036fd6ac8ab061eb8034343dJordan Rose // We need to create a region no matter what. For sanity, make sure we don't 18608291a937a149dbd036fd6ac8ab061eb8034343dJordan Rose // try to stuff a Loc into a non-pointer temporary region. 18728117be48de465bc2862a8f4aaab09338be5090bJordan Rose assert(!V.getAs<Loc>() || Loc::isLocType(Result->getType()) || 18828117be48de465bc2862a8f4aaab09338be5090bJordan Rose Result->getType()->isMemberPointerType()); 18908291a937a149dbd036fd6ac8ab061eb8034343dJordan Rose } 1905e5440ba9c135f523f72e7e7c5da59d390d697c5Jordan Rose 1915e5440ba9c135f523f72e7e7c5da59d390d697c5Jordan Rose ProgramStateManager &StateMgr = State->getStateManager(); 1925e5440ba9c135f523f72e7e7c5da59d390d697c5Jordan Rose MemRegionManager &MRMgr = StateMgr.getRegionManager(); 1935e5440ba9c135f523f72e7e7c5da59d390d697c5Jordan Rose StoreManager &StoreMgr = StateMgr.getStoreManager(); 1945e5440ba9c135f523f72e7e7c5da59d390d697c5Jordan Rose 1955e5440ba9c135f523f72e7e7c5da59d390d697c5Jordan Rose // We need to be careful about treating a derived type's value as 19608291a937a149dbd036fd6ac8ab061eb8034343dJordan Rose // bindings for a base type. Unless we're creating a temporary pointer region, 19708291a937a149dbd036fd6ac8ab061eb8034343dJordan Rose // start by stripping and recording base casts. 1985e5440ba9c135f523f72e7e7c5da59d390d697c5Jordan Rose SmallVector<const CastExpr *, 4> Casts; 1995e5440ba9c135f523f72e7e7c5da59d390d697c5Jordan Rose const Expr *Inner = Ex->IgnoreParens(); 20008291a937a149dbd036fd6ac8ab061eb8034343dJordan Rose if (!Loc::isLocType(Result->getType())) { 201eafb5c694cc5d165149fcb9453bc9355fb0d44a5Jordan Rose while (const CastExpr *CE = dyn_cast<CastExpr>(Inner)) { 202eafb5c694cc5d165149fcb9453bc9355fb0d44a5Jordan Rose if (CE->getCastKind() == CK_DerivedToBase || 203eafb5c694cc5d165149fcb9453bc9355fb0d44a5Jordan Rose CE->getCastKind() == CK_UncheckedDerivedToBase) 204eafb5c694cc5d165149fcb9453bc9355fb0d44a5Jordan Rose Casts.push_back(CE); 205eafb5c694cc5d165149fcb9453bc9355fb0d44a5Jordan Rose else if (CE->getCastKind() != CK_NoOp) 206eafb5c694cc5d165149fcb9453bc9355fb0d44a5Jordan Rose break; 2075e5440ba9c135f523f72e7e7c5da59d390d697c5Jordan Rose 208eafb5c694cc5d165149fcb9453bc9355fb0d44a5Jordan Rose Inner = CE->getSubExpr()->IgnoreParens(); 209eafb5c694cc5d165149fcb9453bc9355fb0d44a5Jordan Rose } 2105e5440ba9c135f523f72e7e7c5da59d390d697c5Jordan Rose } 211f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose 2125e5440ba9c135f523f72e7e7c5da59d390d697c5Jordan Rose // Create a temporary object region for the inner expression (which may have 21308291a937a149dbd036fd6ac8ab061eb8034343dJordan Rose // a more derived type) and bind the value into it. 2146bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const TypedValueRegion *TR = nullptr; 21576b5dd48c9dbf2ed3e5830060ea55b81b7d1cca0Pavel Labath if (const MaterializeTemporaryExpr *MT = 21676b5dd48c9dbf2ed3e5830060ea55b81b7d1cca0Pavel Labath dyn_cast<MaterializeTemporaryExpr>(Result)) { 21776b5dd48c9dbf2ed3e5830060ea55b81b7d1cca0Pavel Labath StorageDuration SD = MT->getStorageDuration(); 21876b5dd48c9dbf2ed3e5830060ea55b81b7d1cca0Pavel Labath // If this object is bound to a reference with static storage duration, we 21976b5dd48c9dbf2ed3e5830060ea55b81b7d1cca0Pavel Labath // put it in a different region to prevent "address leakage" warnings. 22076b5dd48c9dbf2ed3e5830060ea55b81b7d1cca0Pavel Labath if (SD == SD_Static || SD == SD_Thread) 22176b5dd48c9dbf2ed3e5830060ea55b81b7d1cca0Pavel Labath TR = MRMgr.getCXXStaticTempObjectRegion(Inner); 22276b5dd48c9dbf2ed3e5830060ea55b81b7d1cca0Pavel Labath } 22376b5dd48c9dbf2ed3e5830060ea55b81b7d1cca0Pavel Labath if (!TR) 22476b5dd48c9dbf2ed3e5830060ea55b81b7d1cca0Pavel Labath TR = MRMgr.getCXXTempObjectRegion(Inner, LC); 22576b5dd48c9dbf2ed3e5830060ea55b81b7d1cca0Pavel Labath 22608291a937a149dbd036fd6ac8ab061eb8034343dJordan Rose SVal Reg = loc::MemRegionVal(TR); 22708291a937a149dbd036fd6ac8ab061eb8034343dJordan Rose 22808291a937a149dbd036fd6ac8ab061eb8034343dJordan Rose if (V.isUnknown()) 22908291a937a149dbd036fd6ac8ab061eb8034343dJordan Rose V = getSValBuilder().conjureSymbolVal(Result, LC, TR->getValueType(), 23008291a937a149dbd036fd6ac8ab061eb8034343dJordan Rose currBldrCtx->blockCount()); 2315e5440ba9c135f523f72e7e7c5da59d390d697c5Jordan Rose State = State->bindLoc(Reg, V); 2329f1d541ef1aca8f953e5bb4e7177969f0a2062d5Jordan Rose 2335e5440ba9c135f523f72e7e7c5da59d390d697c5Jordan Rose // Re-apply the casts (from innermost to outermost) for type sanity. 2345e5440ba9c135f523f72e7e7c5da59d390d697c5Jordan Rose for (SmallVectorImpl<const CastExpr *>::reverse_iterator I = Casts.rbegin(), 2355e5440ba9c135f523f72e7e7c5da59d390d697c5Jordan Rose E = Casts.rend(); 2365e5440ba9c135f523f72e7e7c5da59d390d697c5Jordan Rose I != E; ++I) { 2375e5440ba9c135f523f72e7e7c5da59d390d697c5Jordan Rose Reg = StoreMgr.evalDerivedToBase(Reg, *I); 238f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose } 239f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose 24008291a937a149dbd036fd6ac8ab061eb8034343dJordan Rose State = State->BindExpr(Result, LC, Reg); 241f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose return State; 242f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose} 243f1e67d75fc922ff905de9faa6326bb1a96685ec1Jordan Rose 244e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek//===----------------------------------------------------------------------===// 245e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek// Top-level transfer function logic (Dispatcher). 246e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek//===----------------------------------------------------------------------===// 247e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek 2489c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek/// evalAssume - Called by ConstraintManager. Used to call checker-specific 24932a58084a4c53e6938dd81bfce224db25a5976d1Ted Kremenek/// logic for handling assumptions on symbolic values. 2508bef8238181a30e52dea380789a7e2d760eac532Ted KremenekProgramStateRef ExprEngine::processAssume(ProgramStateRef state, 251fe27971d54d26997149d6b84057f04ff398d1d5dJordy Rose SVal cond, bool assumption) { 252fe27971d54d26997149d6b84057f04ff398d1d5dJordy Rose return getCheckerManager().runCheckersForEvalAssume(state, cond, assumption); 25332a58084a4c53e6938dd81bfce224db25a5976d1Ted Kremenek} 25432a58084a4c53e6938dd81bfce224db25a5976d1Ted Kremenek 2558bef8238181a30e52dea380789a7e2d760eac532Ted Kremenekbool ExprEngine::wantsRegionChangeUpdate(ProgramStateRef state) { 256183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis return getCheckerManager().wantsRegionChangeUpdate(state); 257c2b7dfaad674587cfd220ff447b3710d252130c3Jordy Rose} 258c2b7dfaad674587cfd220ff447b3710d252130c3Jordy Rose 2598bef8238181a30e52dea380789a7e2d760eac532Ted KremenekProgramStateRef 2608bef8238181a30e52dea380789a7e2d760eac532Ted KremenekExprEngine::processRegionChanges(ProgramStateRef state, 261bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks const InvalidatedSymbols *invalidated, 262537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose ArrayRef<const MemRegion *> Explicits, 26366c40400e7d6272b0cd675ada18dd62c1f0362c7Anna Zaks ArrayRef<const MemRegion *> Regions, 264740d490593e0de8732a697c9f77b90ddd463863bJordan Rose const CallEvent *Call) { 26535bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek return getCheckerManager().runCheckersForRegionChanges(state, invalidated, 26666c40400e7d6272b0cd675ada18dd62c1f0362c7Anna Zaks Explicits, Regions, Call); 267c2b7dfaad674587cfd220ff447b3710d252130c3Jordy Rose} 268c2b7dfaad674587cfd220ff447b3710d252130c3Jordy Rose 2698bef8238181a30e52dea380789a7e2d760eac532Ted Kremenekvoid ExprEngine::printState(raw_ostream &Out, ProgramStateRef State, 270dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose const char *NL, const char *Sep) { 271dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose getCheckerManager().runCheckersForPrintState(Out, State, NL, Sep); 272dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose} 273dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose 274e36de1fe51c39d9161915dd3dbef880954af6476Ted Kremenekvoid ExprEngine::processEndWorklist(bool hasWorkRemaining) { 27530726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis getCheckerManager().runCheckersForEndAnalysis(G, BR, *this); 276ccc263b44c62ce3a02f797a3ddb3d6017cf0e5e4Ted Kremenek} 277ccc263b44c62ce3a02f797a3ddb3d6017cf0e5e4Ted Kremenek 278ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaksvoid ExprEngine::processCFGElement(const CFGElement E, ExplodedNode *Pred, 279ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks unsigned StmtIdx, NodeBuilderContext *Ctx) { 280ac7cc2d37e82181e73fcc265c1d0a619d18b7605Jordan Rose PrettyStackTraceLocationContext CrashInfo(Pred->getLocationContext()); 28166c486f275531df6362b3511fc3af6563561801bTed Kremenek currStmtIdx = StmtIdx; 28266c486f275531df6362b3511fc3af6563561801bTed Kremenek currBldrCtx = Ctx; 283ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks 2849c6cd67ea416bace666d614c84d5531124287653Zhongxing Xu switch (E.getKind()) { 2853c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek case CFGElement::Statement: 286fdf6a279c9a75c778eba382d9a156697092982a1David Blaikie ProcessStmt(const_cast<Stmt*>(E.castAs<CFGStmt>().getStmt()), Pred); 2873c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek return; 2883c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek case CFGElement::Initializer: 289fdf6a279c9a75c778eba382d9a156697092982a1David Blaikie ProcessInitializer(E.castAs<CFGInitializer>().getInitializer(), Pred); 2903c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek return; 291651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines case CFGElement::NewAllocator: 292651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ProcessNewAllocator(E.castAs<CFGNewAllocator>().getAllocatorExpr(), 293651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Pred); 294651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return; 2953c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek case CFGElement::AutomaticObjectDtor: 29636d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose case CFGElement::DeleteDtor: 2973c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek case CFGElement::BaseDtor: 2983c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek case CFGElement::MemberDtor: 2993c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek case CFGElement::TemporaryDtor: 300fdf6a279c9a75c778eba382d9a156697092982a1David Blaikie ProcessImplicitDtor(E.castAs<CFGImplicitDtor>(), Pred); 3013c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek return; 3029c6cd67ea416bace666d614c84d5531124287653Zhongxing Xu } 3039c6cd67ea416bace666d614c84d5531124287653Zhongxing Xu} 3049c6cd67ea416bace666d614c84d5531124287653Zhongxing Xu 305ce117a7d289f57f792e5cc3294280cfe070433deTed Kremenekstatic bool shouldRemoveDeadBindings(AnalysisManager &AMgr, 306ce117a7d289f57f792e5cc3294280cfe070433deTed Kremenek const CFGStmt S, 307ce117a7d289f57f792e5cc3294280cfe070433deTed Kremenek const ExplodedNode *Pred, 308ce117a7d289f57f792e5cc3294280cfe070433deTed Kremenek const LocationContext *LC) { 309ce117a7d289f57f792e5cc3294280cfe070433deTed Kremenek 310ce117a7d289f57f792e5cc3294280cfe070433deTed Kremenek // Are we never purging state values? 311255d4d4226b24036ceb11228fbb74286e58620f7Ted Kremenek if (AMgr.options.AnalysisPurgeOpt == PurgeNone) 312ce117a7d289f57f792e5cc3294280cfe070433deTed Kremenek return false; 313ce117a7d289f57f792e5cc3294280cfe070433deTed Kremenek 314ce117a7d289f57f792e5cc3294280cfe070433deTed Kremenek // Is this the beginning of a basic block? 3157a95de68c093991047ed8d339479ccad51b88663David Blaikie if (Pred->getLocation().getAs<BlockEntrance>()) 316ce117a7d289f57f792e5cc3294280cfe070433deTed Kremenek return true; 317ce117a7d289f57f792e5cc3294280cfe070433deTed Kremenek 318ce117a7d289f57f792e5cc3294280cfe070433deTed Kremenek // Is this on a non-expression? 319ce117a7d289f57f792e5cc3294280cfe070433deTed Kremenek if (!isa<Expr>(S.getStmt())) 320ce117a7d289f57f792e5cc3294280cfe070433deTed Kremenek return true; 321ff80afcfb2b00ccffcb6cb10528bec565fc59eddAnna Zaks 322ff80afcfb2b00ccffcb6cb10528bec565fc59eddAnna Zaks // Run before processing a call. 3236062334cc388bce69fb3978c4ecb26c6485a5c2bJordan Rose if (CallEvent::isCallStmt(S.getStmt())) 324ff80afcfb2b00ccffcb6cb10528bec565fc59eddAnna Zaks return true; 325ff80afcfb2b00ccffcb6cb10528bec565fc59eddAnna Zaks 326ce117a7d289f57f792e5cc3294280cfe070433deTed Kremenek // Is this an expression that is consumed by another expression? If so, 327ce117a7d289f57f792e5cc3294280cfe070433deTed Kremenek // postpone cleaning out the state. 328ce117a7d289f57f792e5cc3294280cfe070433deTed Kremenek ParentMap &PM = LC->getAnalysisDeclContext()->getParentMap(); 329ce117a7d289f57f792e5cc3294280cfe070433deTed Kremenek return !PM.isConsumedExpr(cast<Expr>(S.getStmt())); 330ce117a7d289f57f792e5cc3294280cfe070433deTed Kremenek} 331ce117a7d289f57f792e5cc3294280cfe070433deTed Kremenek 3320b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaksvoid ExprEngine::removeDead(ExplodedNode *Pred, ExplodedNodeSet &Out, 3330b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks const Stmt *ReferenceStmt, 33484c484545c5906ba55143e212b4a5275ab55889fJordan Rose const LocationContext *LC, 3350b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks const Stmt *DiagnosticStmt, 3360b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks ProgramPoint::Kind K) { 3370b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks assert((K == ProgramPoint::PreStmtPurgeDeadSymbolsKind || 3386bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ReferenceStmt == nullptr || isa<ReturnStmt>(ReferenceStmt)) 3398501b7a1c4c4a9ba0ea6cb8e500e601ef3759debAnna Zaks && "PostStmt is not generally supported by the SymbolReaper yet"); 34084c484545c5906ba55143e212b4a5275ab55889fJordan Rose assert(LC && "Must pass the current (or expiring) LocationContext"); 34184c484545c5906ba55143e212b4a5275ab55889fJordan Rose 34284c484545c5906ba55143e212b4a5275ab55889fJordan Rose if (!DiagnosticStmt) { 34384c484545c5906ba55143e212b4a5275ab55889fJordan Rose DiagnosticStmt = ReferenceStmt; 34484c484545c5906ba55143e212b4a5275ab55889fJordan Rose assert(DiagnosticStmt && "Required for clearing a LocationContext"); 34584c484545c5906ba55143e212b4a5275ab55889fJordan Rose } 34684c484545c5906ba55143e212b4a5275ab55889fJordan Rose 3470b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks NumRemoveDeadBindings++; 3489428723d6730f4fd257e15b78d24991ae95bbd84Jordan Rose ProgramStateRef CleanedState = Pred->getState(); 34984c484545c5906ba55143e212b4a5275ab55889fJordan Rose 35084c484545c5906ba55143e212b4a5275ab55889fJordan Rose // LC is the location context being destroyed, but SymbolReaper wants a 35184c484545c5906ba55143e212b4a5275ab55889fJordan Rose // location context that is still live. (If this is the top-level stack 35284c484545c5906ba55143e212b4a5275ab55889fJordan Rose // frame, this will be null.) 35384c484545c5906ba55143e212b4a5275ab55889fJordan Rose if (!ReferenceStmt) { 35484c484545c5906ba55143e212b4a5275ab55889fJordan Rose assert(K == ProgramPoint::PostStmtPurgeDeadSymbolsKind && 35584c484545c5906ba55143e212b4a5275ab55889fJordan Rose "Use PostStmtPurgeDeadSymbolsKind for clearing a LocationContext"); 35684c484545c5906ba55143e212b4a5275ab55889fJordan Rose LC = LC->getParent(); 35784c484545c5906ba55143e212b4a5275ab55889fJordan Rose } 35884c484545c5906ba55143e212b4a5275ab55889fJordan Rose 3596bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const StackFrameContext *SFC = LC ? LC->getCurrentStackFrame() : nullptr; 36084c484545c5906ba55143e212b4a5275ab55889fJordan Rose SymbolReaper SymReaper(SFC, ReferenceStmt, SymMgr, getStoreManager()); 3610b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks 3620b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks getCheckerManager().runCheckersForLiveSymbols(CleanedState, SymReaper); 3630b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks 3640b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks // Create a state in which dead bindings are removed from the environment 3650b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks // and the store. TODO: The function should just return new env and store, 3660b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks // not a new state. 3670b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks CleanedState = StateMgr.removeDeadBindings(CleanedState, SFC, SymReaper); 368241677a13cc46647a8f5098b3e3239bd9480dca2Ted Kremenek 36977d7ef8d8a80ccb2ab3d25c80810571e3ab14ee4Ted Kremenek // Process any special transfer function for dead symbols. 370f185cc1ac77a84139c603eee3473b88dcb839c68Anna Zaks // A tag to track convenience transitions, which can be removed at cleanup. 371651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines static SimpleProgramPointTag cleanupTag(TagProviderName, "Clean Node"); 3726bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks if (!SymReaper.hasDeadSymbols()) { 3736bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks // Generate a CleanedNode that has the environment and store cleaned 3746bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks // up. Since no symbols are dead, we can optimize and not clean out 3756bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks // the constraint manager. 37666c486f275531df6362b3511fc3af6563561801bTed Kremenek StmtNodeBuilder Bldr(Pred, Out, *currBldrCtx); 377fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose Bldr.generateNode(DiagnosticStmt, Pred, CleanedState, &cleanupTag, K); 3781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3796bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks } else { 3806bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks // Call checkers with the non-cleaned state so that they could query the 3816bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks // values of the soon to be dead symbols. 382fe27971d54d26997149d6b84057f04ff398d1d5dJordy Rose ExplodedNodeSet CheckedSet; 3830b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks getCheckerManager().runCheckersForDeadSymbols(CheckedSet, Pred, SymReaper, 3840b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks DiagnosticStmt, *this, K); 385183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis 386fe27971d54d26997149d6b84057f04ff398d1d5dJordy Rose // For each node in CheckedSet, generate CleanedNodes that have the 387fe27971d54d26997149d6b84057f04ff398d1d5dJordy Rose // environment, the store, and the constraints cleaned up but have the 388fe27971d54d26997149d6b84057f04ff398d1d5dJordy Rose // user-supplied states as the predecessors. 38966c486f275531df6362b3511fc3af6563561801bTed Kremenek StmtNodeBuilder Bldr(CheckedSet, Out, *currBldrCtx); 390fe27971d54d26997149d6b84057f04ff398d1d5dJordy Rose for (ExplodedNodeSet::const_iterator 391fe27971d54d26997149d6b84057f04ff398d1d5dJordy Rose I = CheckedSet.begin(), E = CheckedSet.end(); I != E; ++I) { 3928bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek ProgramStateRef CheckerState = (*I)->getState(); 3936bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks 3946bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks // The constraint manager has not been cleaned up yet, so clean up now. 3956bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks CheckerState = getConstraintManager().removeDeadBindings(CheckerState, 3966bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks SymReaper); 3976bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks 3980b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks assert(StateMgr.haveEqualEnvironments(CheckerState, Pred->getState()) && 3996bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks "Checkers are not allowed to modify the Environment as a part of " 4006bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks "checkDeadSymbols processing."); 4010b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks assert(StateMgr.haveEqualStores(CheckerState, Pred->getState()) && 4026bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks "Checkers are not allowed to modify the Store as a part of " 4036bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks "checkDeadSymbols processing."); 4046bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks 4056bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks // Create a state based on CleanedState with CheckerState GDM and 4066bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks // generate a transition to that state. 4078bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek ProgramStateRef CleanedCheckerSt = 4086bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks StateMgr.getPersistentStateWithGDM(CleanedState, CheckerState); 409fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose Bldr.generateNode(DiagnosticStmt, *I, CleanedCheckerSt, &cleanupTag, K); 4106bd528b9d703fdea51053719d9c53504a61a6bd7Anna Zaks } 41177d7ef8d8a80ccb2ab3d25c80810571e3ab14ee4Ted Kremenek } 4120b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks} 4130b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks 4140b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaksvoid ExprEngine::ProcessStmt(const CFGStmt S, 4150b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks ExplodedNode *Pred) { 4160b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks // Reclaim any unnecessary nodes in the ExplodedGraph. 4170b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks G.reclaimRecentlyAllocatedNodes(); 4180b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks 4199428723d6730f4fd257e15b78d24991ae95bbd84Jordan Rose const Stmt *currStmt = S.getStmt(); 4200b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(), 42166c486f275531df6362b3511fc3af6563561801bTed Kremenek currStmt->getLocStart(), 4220b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks "Error evaluating statement"); 4231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4240b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks // Remove dead bindings and symbols. 4250b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks ExplodedNodeSet CleanedStates; 4269428723d6730f4fd257e15b78d24991ae95bbd84Jordan Rose if (shouldRemoveDeadBindings(AMgr, S, Pred, Pred->getLocationContext())){ 4279428723d6730f4fd257e15b78d24991ae95bbd84Jordan Rose removeDead(Pred, CleanedStates, currStmt, Pred->getLocationContext()); 4280b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks } else 4299428723d6730f4fd257e15b78d24991ae95bbd84Jordan Rose CleanedStates.Add(Pred); 4300b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks 4310b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks // Visit the statement. 432dd7ddf2b2296f95e7591ca3f9791f0eb9a15ee42Anna Zaks ExplodedNodeSet Dst; 4330b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks for (ExplodedNodeSet::iterator I = CleanedStates.begin(), 4340b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks E = CleanedStates.end(); I != E; ++I) { 435dd7ddf2b2296f95e7591ca3f9791f0eb9a15ee42Anna Zaks ExplodedNodeSet DstI; 4361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // Visit the statement. 43766c486f275531df6362b3511fc3af6563561801bTed Kremenek Visit(currStmt, *I, DstI); 438dd7ddf2b2296f95e7591ca3f9791f0eb9a15ee42Anna Zaks Dst.insert(DstI); 439ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks } 440ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks 441dd7ddf2b2296f95e7591ca3f9791f0eb9a15ee42Anna Zaks // Enqueue the new nodes onto the work list. 44266c486f275531df6362b3511fc3af6563561801bTed Kremenek Engine.enqueue(Dst, currBldrCtx->getBlock(), currStmtIdx); 443e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek} 444e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek 445d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisvoid ExprEngine::ProcessInitializer(const CFGInitializer Init, 446056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks ExplodedNode *Pred) { 447cbb67480094b3bcb5b715acd827cbad55e2a204cSean Hunt const CXXCtorInitializer *BMI = Init.getInitializer(); 448563ea2335d7d0df44bbfe8941f64523e8af1fc14Jordan Rose 449563ea2335d7d0df44bbfe8941f64523e8af1fc14Jordan Rose PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(), 450563ea2335d7d0df44bbfe8941f64523e8af1fc14Jordan Rose BMI->getSourceLocation(), 451563ea2335d7d0df44bbfe8941f64523e8af1fc14Jordan Rose "Error evaluating initializer"); 452563ea2335d7d0df44bbfe8941f64523e8af1fc14Jordan Rose 4539428723d6730f4fd257e15b78d24991ae95bbd84Jordan Rose // We don't clean up dead bindings here. 454056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks const StackFrameContext *stackFrame = 455056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks cast<StackFrameContext>(Pred->getLocationContext()); 456056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks const CXXConstructorDecl *decl = 457056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks cast<CXXConstructorDecl>(stackFrame->getDecl()); 4583682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose 4593682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose ProgramStateRef State = Pred->getState(); 4603a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose SVal thisVal = State->getSVal(svalBuilder.getCXXThis(decl, stackFrame)); 4619dc84c9455df2a77195147d0210c915dc1775a88Zhongxing Xu 4623682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose ExplodedNodeSet Tmp(Pred); 463610f79cbab4d752349b5c81a94682a6a82b102e7Anna Zaks SVal FieldLoc; 4643682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose 4653a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose // Evaluate the initializer, if necessary 46600eb3f9c5b33e3d99aee1f8b75dd9c9678fdd66bFrancois Pichet if (BMI->isAnyMemberInitializer()) { 4673a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose // Constructors build the object directly in the field, 4683a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose // but non-objects must be copied in from the initializer. 46907c52d2813a6b5e4025276d3687bd25f75fd51b9Jordan Rose const Expr *Init = BMI->getInit()->IgnoreImplicit(); 4703682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose if (!isa<CXXConstructExpr>(Init)) { 471ecee1651c100342366a9417c85c6e50399039930Jordan Rose const ValueDecl *Field; 472ecee1651c100342366a9417c85c6e50399039930Jordan Rose if (BMI->isIndirectMemberInitializer()) { 473ecee1651c100342366a9417c85c6e50399039930Jordan Rose Field = BMI->getIndirectMember(); 4743a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose FieldLoc = State->getLValue(BMI->getIndirectMember(), thisVal); 475ecee1651c100342366a9417c85c6e50399039930Jordan Rose } else { 476ecee1651c100342366a9417c85c6e50399039930Jordan Rose Field = BMI->getMember(); 4773a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose FieldLoc = State->getLValue(BMI->getMember(), thisVal); 478ecee1651c100342366a9417c85c6e50399039930Jordan Rose } 4793a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose 480ecee1651c100342366a9417c85c6e50399039930Jordan Rose SVal InitVal; 481ecee1651c100342366a9417c85c6e50399039930Jordan Rose if (BMI->getNumArrayIndices() > 0) { 482ecee1651c100342366a9417c85c6e50399039930Jordan Rose // Handle arrays of trivial type. We can represent this with a 483ecee1651c100342366a9417c85c6e50399039930Jordan Rose // primitive load/copy from the base array region. 484ecee1651c100342366a9417c85c6e50399039930Jordan Rose const ArraySubscriptExpr *ASE; 485ecee1651c100342366a9417c85c6e50399039930Jordan Rose while ((ASE = dyn_cast<ArraySubscriptExpr>(Init))) 486ecee1651c100342366a9417c85c6e50399039930Jordan Rose Init = ASE->getBase()->IgnoreImplicit(); 487ecee1651c100342366a9417c85c6e50399039930Jordan Rose 488ecee1651c100342366a9417c85c6e50399039930Jordan Rose SVal LValue = State->getSVal(Init, stackFrame); 489ecee1651c100342366a9417c85c6e50399039930Jordan Rose if (Optional<Loc> LValueLoc = LValue.getAs<Loc>()) 490ecee1651c100342366a9417c85c6e50399039930Jordan Rose InitVal = State->getSVal(*LValueLoc); 491ecee1651c100342366a9417c85c6e50399039930Jordan Rose 492ecee1651c100342366a9417c85c6e50399039930Jordan Rose // If we fail to get the value for some reason, use a symbolic value. 493ecee1651c100342366a9417c85c6e50399039930Jordan Rose if (InitVal.isUnknownOrUndef()) { 494ecee1651c100342366a9417c85c6e50399039930Jordan Rose SValBuilder &SVB = getSValBuilder(); 495ecee1651c100342366a9417c85c6e50399039930Jordan Rose InitVal = SVB.conjureSymbolVal(BMI->getInit(), stackFrame, 496ecee1651c100342366a9417c85c6e50399039930Jordan Rose Field->getType(), 497ecee1651c100342366a9417c85c6e50399039930Jordan Rose currBldrCtx->blockCount()); 498ecee1651c100342366a9417c85c6e50399039930Jordan Rose } 499ecee1651c100342366a9417c85c6e50399039930Jordan Rose } else { 500ecee1651c100342366a9417c85c6e50399039930Jordan Rose InitVal = State->getSVal(BMI->getInit(), stackFrame); 501ecee1651c100342366a9417c85c6e50399039930Jordan Rose } 5023682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose 503ecee1651c100342366a9417c85c6e50399039930Jordan Rose assert(Tmp.size() == 1 && "have not generated any new nodes yet"); 504ecee1651c100342366a9417c85c6e50399039930Jordan Rose assert(*Tmp.begin() == Pred && "have not generated any new nodes yet"); 5053682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose Tmp.clear(); 506610f79cbab4d752349b5c81a94682a6a82b102e7Anna Zaks 507610f79cbab4d752349b5c81a94682a6a82b102e7Anna Zaks PostInitializer PP(BMI, FieldLoc.getAsRegion(), stackFrame); 5083682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose evalBind(Tmp, Init, Pred, FieldLoc, InitVal, /*isInit=*/true, &PP); 5093a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose } 510056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks } else { 511563ea2335d7d0df44bbfe8941f64523e8af1fc14Jordan Rose assert(BMI->isBaseInitializer() || BMI->isDelegatingInitializer()); 512888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose // We already did all the work when visiting the CXXConstructExpr. 513056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks } 514dd7ddf2b2296f95e7591ca3f9791f0eb9a15ee42Anna Zaks 5153682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose // Construct PostInitializer nodes whether the state changed or not, 5163a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose // so that the diagnostics don't get confused. 517610f79cbab4d752349b5c81a94682a6a82b102e7Anna Zaks PostInitializer PP(BMI, FieldLoc.getAsRegion(), stackFrame); 5183682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose ExplodedNodeSet Dst; 5193682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose NodeBuilder Bldr(Tmp, Dst, *currBldrCtx); 5203682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose for (ExplodedNodeSet::iterator I = Tmp.begin(), E = Tmp.end(); I != E; ++I) { 5213682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose ExplodedNode *N = *I; 5223682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose Bldr.generateNode(PP, N->getState(), N); 5233682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose } 5243a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose 525dd7ddf2b2296f95e7591ca3f9791f0eb9a15ee42Anna Zaks // Enqueue the new nodes onto the work list. 52666c486f275531df6362b3511fc3af6563561801bTed Kremenek Engine.enqueue(Dst, currBldrCtx->getBlock(), currStmtIdx); 5279c6cd67ea416bace666d614c84d5531124287653Zhongxing Xu} 5289c6cd67ea416bace666d614c84d5531124287653Zhongxing Xu 529d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisvoid ExprEngine::ProcessImplicitDtor(const CFGImplicitDtor D, 530ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks ExplodedNode *Pred) { 531ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks ExplodedNodeSet Dst; 5323c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek switch (D.getKind()) { 5334ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu case CFGElement::AutomaticObjectDtor: 534fdf6a279c9a75c778eba382d9a156697092982a1David Blaikie ProcessAutomaticObjDtor(D.castAs<CFGAutomaticObjDtor>(), Pred, Dst); 5354ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu break; 5364ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu case CFGElement::BaseDtor: 537fdf6a279c9a75c778eba382d9a156697092982a1David Blaikie ProcessBaseDtor(D.castAs<CFGBaseDtor>(), Pred, Dst); 5384ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu break; 5394ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu case CFGElement::MemberDtor: 540fdf6a279c9a75c778eba382d9a156697092982a1David Blaikie ProcessMemberDtor(D.castAs<CFGMemberDtor>(), Pred, Dst); 5414ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu break; 5424ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu case CFGElement::TemporaryDtor: 543fdf6a279c9a75c778eba382d9a156697092982a1David Blaikie ProcessTemporaryDtor(D.castAs<CFGTemporaryDtor>(), Pred, Dst); 5444ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu break; 54536d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose case CFGElement::DeleteDtor: 54636d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose ProcessDeleteDtor(D.castAs<CFGDeleteDtor>(), Pred, Dst); 54736d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose break; 5484ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu default: 5494ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu llvm_unreachable("Unexpected dtor kind."); 5504ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu } 551ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks 552dd7ddf2b2296f95e7591ca3f9791f0eb9a15ee42Anna Zaks // Enqueue the new nodes onto the work list. 55366c486f275531df6362b3511fc3af6563561801bTed Kremenek Engine.enqueue(Dst, currBldrCtx->getBlock(), currStmtIdx); 5544ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu} 5554ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu 556651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid ExprEngine::ProcessNewAllocator(const CXXNewExpr *NE, 557651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ExplodedNode *Pred) { 558651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ExplodedNodeSet Dst; 559651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines AnalysisManager &AMgr = getAnalysisManager(); 560651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines AnalyzerOptions &Opts = AMgr.options; 561651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // TODO: We're not evaluating allocators for all cases just yet as 562651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // we're not handling the return value correctly, which causes false 563651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // positives when the alpha.cplusplus.NewDeleteLeaks check is on. 564651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (Opts.mayInlineCXXAllocator()) 565651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines VisitCXXNewAllocatorCall(NE, Pred, Dst); 566651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines else { 567651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines NodeBuilder Bldr(Pred, Dst, *currBldrCtx); 568651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const LocationContext *LCtx = Pred->getLocationContext(); 569651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines PostImplicitCall PP(NE->getOperatorNew(), NE->getLocStart(), LCtx); 570651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Bldr.generateNode(PP, Pred->getState(), Pred); 571651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 572651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Engine.enqueue(Dst, currBldrCtx->getBlock(), currStmtIdx); 573651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 574651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 575056c4b46335a3bd2612414735d5749ee159c0165Anna Zaksvoid ExprEngine::ProcessAutomaticObjDtor(const CFGAutomaticObjDtor Dtor, 576056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks ExplodedNode *Pred, 577056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks ExplodedNodeSet &Dst) { 578056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks const VarDecl *varDecl = Dtor.getVarDecl(); 5792210490e6d099b7a5b4f68f44a136e4dcf3cdea2Zhongxing Xu QualType varType = varDecl->getType(); 5802210490e6d099b7a5b4f68f44a136e4dcf3cdea2Zhongxing Xu 58108291a937a149dbd036fd6ac8ab061eb8034343dJordan Rose ProgramStateRef state = Pred->getState(); 58208291a937a149dbd036fd6ac8ab061eb8034343dJordan Rose SVal dest = state->getLValue(varDecl, Pred->getLocationContext()); 58308291a937a149dbd036fd6ac8ab061eb8034343dJordan Rose const MemRegion *Region = dest.castAs<loc::MemRegionVal>().getRegion(); 5842210490e6d099b7a5b4f68f44a136e4dcf3cdea2Zhongxing Xu 58508291a937a149dbd036fd6ac8ab061eb8034343dJordan Rose if (const ReferenceType *refType = varType->getAs<ReferenceType>()) { 58608291a937a149dbd036fd6ac8ab061eb8034343dJordan Rose varType = refType->getPointeeType(); 58708291a937a149dbd036fd6ac8ab061eb8034343dJordan Rose Region = state->getSVal(Region).getAsRegion(); 58808291a937a149dbd036fd6ac8ab061eb8034343dJordan Rose } 589b13453bd8a91f331d0910ca95ad52aa41b52f648Zhongxing Xu 59008291a937a149dbd036fd6ac8ab061eb8034343dJordan Rose VisitCXXDestructor(varType, Region, Dtor.getTriggerStmt(), /*IsBase=*/ false, 59108291a937a149dbd036fd6ac8ab061eb8034343dJordan Rose Pred, Dst); 5924ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu} 5934ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu 59436d558d85653315edb389677e995ec9ccdbfbf3dJordan Rosevoid ExprEngine::ProcessDeleteDtor(const CFGDeleteDtor Dtor, 59536d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose ExplodedNode *Pred, 59636d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose ExplodedNodeSet &Dst) { 59781557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose ProgramStateRef State = Pred->getState(); 59881557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose const LocationContext *LCtx = Pred->getLocationContext(); 59981557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose const CXXDeleteExpr *DE = Dtor.getDeleteExpr(); 60081557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose const Stmt *Arg = DE->getArgument(); 60181557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose SVal ArgVal = State->getSVal(Arg, LCtx); 60281557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose 60381557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose // If the argument to delete is known to be a null value, 60481557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose // don't run destructor. 60581557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose if (State->isNull(ArgVal).isConstrainedTrue()) { 60681557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose QualType DTy = DE->getDestroyedType(); 60781557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose QualType BTy = getContext().getBaseElementType(DTy); 60881557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose const CXXRecordDecl *RD = BTy->getAsCXXRecordDecl(); 60981557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose const CXXDestructorDecl *Dtor = RD->getDestructor(); 61081557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose 61181557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose PostImplicitCall PP(Dtor, DE->getLocStart(), LCtx); 61281557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose NodeBuilder Bldr(Pred, Dst, *currBldrCtx); 61381557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose Bldr.generateNode(PP, Pred->getState(), Pred); 61481557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose return; 61581557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose } 61681557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose 61781557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose VisitCXXDestructor(DE->getDestroyedType(), 61881557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose ArgVal.getAsRegion(), 61981557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose DE, /*IsBase=*/ false, 62081557223ba8d7ef8b0468a6e1dc8fc79f2de46f2Jordan Rose Pred, Dst); 62136d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose} 62236d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose 623d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisvoid ExprEngine::ProcessBaseDtor(const CFGBaseDtor D, 624888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose ExplodedNode *Pred, ExplodedNodeSet &Dst) { 625888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose const LocationContext *LCtx = Pred->getLocationContext(); 626888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose 627888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose const CXXDestructorDecl *CurDtor = cast<CXXDestructorDecl>(LCtx->getDecl()); 628888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose Loc ThisPtr = getSValBuilder().getCXXThis(CurDtor, 629888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose LCtx->getCurrentStackFrame()); 630888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose SVal ThisVal = Pred->getState()->getSVal(ThisPtr); 631888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose 632888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose // Create the base object region. 6334411b423e91da0a2c879b70c0222aeba35f72044Jordan Rose const CXXBaseSpecifier *Base = D.getBaseSpecifier(); 6344411b423e91da0a2c879b70c0222aeba35f72044Jordan Rose QualType BaseTy = Base->getType(); 6354411b423e91da0a2c879b70c0222aeba35f72044Jordan Rose SVal BaseVal = getStoreManager().evalDerivedToBase(ThisVal, BaseTy, 6364411b423e91da0a2c879b70c0222aeba35f72044Jordan Rose Base->isVirtual()); 637888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose 6385251abea41b446c26e3239c8dd6c7edea6fc335dDavid Blaikie VisitCXXDestructor(BaseTy, BaseVal.castAs<loc::MemRegionVal>().getRegion(), 6395251abea41b446c26e3239c8dd6c7edea6fc335dDavid Blaikie CurDtor->getBody(), /*IsBase=*/ true, Pred, Dst); 640888c90ac0ef6baf7d47e86cf5cc4715707d223b1Jordan Rose} 6414ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu 642d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisvoid ExprEngine::ProcessMemberDtor(const CFGMemberDtor D, 6433a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose ExplodedNode *Pred, ExplodedNodeSet &Dst) { 6443a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose const FieldDecl *Member = D.getFieldDecl(); 6453a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose ProgramStateRef State = Pred->getState(); 6463a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose const LocationContext *LCtx = Pred->getLocationContext(); 6473a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose 6483a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose const CXXDestructorDecl *CurDtor = cast<CXXDestructorDecl>(LCtx->getDecl()); 6493a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose Loc ThisVal = getSValBuilder().getCXXThis(CurDtor, 6503a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose LCtx->getCurrentStackFrame()); 6515251abea41b446c26e3239c8dd6c7edea6fc335dDavid Blaikie SVal FieldVal = 6525251abea41b446c26e3239c8dd6c7edea6fc335dDavid Blaikie State->getLValue(Member, State->getSVal(ThisVal).castAs<Loc>()); 6533a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose 6543a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose VisitCXXDestructor(Member->getType(), 6555251abea41b446c26e3239c8dd6c7edea6fc335dDavid Blaikie FieldVal.castAs<loc::MemRegionVal>().getRegion(), 656200fa2e70d52ae6d620e81cd45536071fdde70c0Jordan Rose CurDtor->getBody(), /*IsBase=*/false, Pred, Dst); 6573a0a9e3e8bbaa45f3ca22b1e20b3beaac0f5861eJordan Rose} 6584ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu 659d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisvoid ExprEngine::ProcessTemporaryDtor(const CFGTemporaryDtor D, 660056c4b46335a3bd2612414735d5749ee159c0165Anna Zaks ExplodedNode *Pred, 66195ab9e306f4deefeabd89ea61987f4a8d67e0890Pavel Labath ExplodedNodeSet &Dst) { 66295ab9e306f4deefeabd89ea61987f4a8d67e0890Pavel Labath 66395ab9e306f4deefeabd89ea61987f4a8d67e0890Pavel Labath QualType varType = D.getBindTemporaryExpr()->getSubExpr()->getType(); 66495ab9e306f4deefeabd89ea61987f4a8d67e0890Pavel Labath 66595ab9e306f4deefeabd89ea61987f4a8d67e0890Pavel Labath // FIXME: Inlining of temporary destructors is not supported yet anyway, so we 666