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