1d4931632946fe86fc2b09496f2b62443440a7da4Ted Kremenek//== Environment.cpp - Map from Stmt* to Locations/Values -------*- C++ -*--==//
28133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek//
38133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek//                     The LLVM Compiler Infrastructure
48133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek//
58133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek// This file is distributed under the University of Illinois Open Source
68133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek// License. See LICENSE.TXT for details.
78133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek//
88133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek//===----------------------------------------------------------------------===//
98133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek//
108133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek//  This file defined the Environment and EnvironmentManager classes.
118133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek//
128133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek//===----------------------------------------------------------------------===//
135e2d2c2ee3cf410643e0f9a5701708e51409d973Benjamin Kramer
14c35fb7d67d515659ad2325b4f6ec97c9fe64fb63Benjamin Kramer#include "clang/AST/ExprCXX.h"
15f8b5aae41e46f94fe90ed5f1ee98f36f0aa59dc9Ted Kremenek#include "clang/AST/ExprObjC.h"
165e2d2c2ee3cf410643e0f9a5701708e51409d973Benjamin Kramer#include "clang/Analysis/AnalysisContext.h"
175e2d2c2ee3cf410643e0f9a5701708e51409d973Benjamin Kramer#include "clang/Analysis/CFG.h"
1818c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
198133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek
208133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenekusing namespace clang;
219ef6537a894c33003359b1f9b9676e9178e028b7Ted Kremenekusing namespace ento;
228133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek
235eca482fe895ea57bc82410222e6426c09e63284Ted KremenekSVal Environment::lookupExpr(const EnvironmentEntry &E) const {
24465846324f412055dd1ce270d757bfeead0811dcTed Kremenek  const SVal* X = ExprBindings.lookup(E);
25465846324f412055dd1ce270d757bfeead0811dcTed Kremenek  if (X) {
26465846324f412055dd1ce270d757bfeead0811dcTed Kremenek    SVal V = *X;
27465846324f412055dd1ce270d757bfeead0811dcTed Kremenek    return V;
28465846324f412055dd1ce270d757bfeead0811dcTed Kremenek  }
29465846324f412055dd1ce270d757bfeead0811dcTed Kremenek  return UnknownVal();
30465846324f412055dd1ce270d757bfeead0811dcTed Kremenek}
31465846324f412055dd1ce270d757bfeead0811dcTed Kremenek
325eca482fe895ea57bc82410222e6426c09e63284Ted KremenekSVal Environment::getSVal(const EnvironmentEntry &Entry,
335eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek                          SValBuilder& svalBuilder,
345eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek                          bool useOnlyDirectBindings) const {
356b4f567109d76ce1f1de289554e35f2a7bbeff6bTed Kremenek
366b4f567109d76ce1f1de289554e35f2a7bbeff6bTed Kremenek  if (useOnlyDirectBindings) {
376b4f567109d76ce1f1de289554e35f2a7bbeff6bTed Kremenek    // This branch is rarely taken, but can be exercised by
386b4f567109d76ce1f1de289554e35f2a7bbeff6bTed Kremenek    // checkers that explicitly bind values to arbitrary
396b4f567109d76ce1f1de289554e35f2a7bbeff6bTed Kremenek    // expressions.  It is crucial that we do not ignore any
406b4f567109d76ce1f1de289554e35f2a7bbeff6bTed Kremenek    // expression here, and do a direct lookup.
415eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek    return lookupExpr(Entry);
426b4f567109d76ce1f1de289554e35f2a7bbeff6bTed Kremenek  }
436b4f567109d76ce1f1de289554e35f2a7bbeff6bTed Kremenek
445eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek  const Stmt *E = Entry.getStmt();
455eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek  const LocationContext *LCtx = Entry.getLocationContext();
465eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek
47d72ee907f76000446c706471e93d1f299104f9a7Ted Kremenek  for (;;) {
4822043b5ad4278cba814608f0368813acfcf24b67Jordy Rose    if (const Expr *Ex = dyn_cast<Expr>(E))
4922043b5ad4278cba814608f0368813acfcf24b67Jordy Rose      E = Ex->IgnoreParens();
5022043b5ad4278cba814608f0368813acfcf24b67Jordy Rose
51d72ee907f76000446c706471e93d1f299104f9a7Ted Kremenek    switch (E->getStmtClass()) {
521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      case Stmt::AddrLabelExprClass:
53c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek        return svalBuilder.makeLoc(cast<AddrLabelExpr>(E));
54f226d18f0f49394cec460699f4268e32bd0ce833Ted Kremenek      case Stmt::OpaqueValueExprClass: {
55f226d18f0f49394cec460699f4268e32bd0ce833Ted Kremenek        const OpaqueValueExpr *ope = cast<OpaqueValueExpr>(E);
56f226d18f0f49394cec460699f4268e32bd0ce833Ted Kremenek        E = ope->getSourceExpr();
57f226d18f0f49394cec460699f4268e32bd0ce833Ted Kremenek        continue;
58f226d18f0f49394cec460699f4268e32bd0ce833Ted Kremenek      }
591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      case Stmt::ParenExprClass:
60f111d935722ed488144600cea5ed03a6b5069e8fPeter Collingbourne      case Stmt::GenericSelectionExprClass:
6122043b5ad4278cba814608f0368813acfcf24b67Jordy Rose        llvm_unreachable("ParenExprs and GenericSelectionExprs should "
6222043b5ad4278cba814608f0368813acfcf24b67Jordy Rose                         "have been handled by IgnoreParens()");
63d72ee907f76000446c706471e93d1f299104f9a7Ted Kremenek      case Stmt::CharacterLiteralClass: {
6423ec48cd3369c8d7d1ab3c3f2226cfcffd2cd3d3Ted Kremenek        const CharacterLiteral* C = cast<CharacterLiteral>(E);
65c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek        return svalBuilder.makeIntVal(C->getValue(), C->getType());
66d72ee907f76000446c706471e93d1f299104f9a7Ted Kremenek      }
67477323d58a0de352c6a61e08b5a83127c4adc904Zhongxing Xu      case Stmt::CXXBoolLiteralExprClass: {
685eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek        const SVal *X = ExprBindings.lookup(EnvironmentEntry(E, LCtx));
69477323d58a0de352c6a61e08b5a83127c4adc904Zhongxing Xu        if (X)
70477323d58a0de352c6a61e08b5a83127c4adc904Zhongxing Xu          return *X;
71477323d58a0de352c6a61e08b5a83127c4adc904Zhongxing Xu        else
72370e6e984cc32167228b66eaf9610c010da0d794Argyrios Kyrtzidis          return svalBuilder.makeBoolVal(cast<CXXBoolLiteralExpr>(E));
73477323d58a0de352c6a61e08b5a83127c4adc904Zhongxing Xu      }
74c319c585c0d5899cba0dca2272e6e4909c8b9f16Ted Kremenek      case Stmt::CXXScalarValueInitExprClass:
75c319c585c0d5899cba0dca2272e6e4909c8b9f16Ted Kremenek      case Stmt::ImplicitValueInitExprClass: {
76c319c585c0d5899cba0dca2272e6e4909c8b9f16Ted Kremenek        QualType Ty = cast<Expr>(E)->getType();
77c319c585c0d5899cba0dca2272e6e4909c8b9f16Ted Kremenek        return svalBuilder.makeZeroVal(Ty);
78c319c585c0d5899cba0dca2272e6e4909c8b9f16Ted Kremenek      }
79d72ee907f76000446c706471e93d1f299104f9a7Ted Kremenek      case Stmt::IntegerLiteralClass: {
80bc37b8dd9914e02580f531fa6e5e72be34d9675eZhongxing Xu        // In C++, this expression may have been bound to a temporary object.
815eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek        SVal const *X = ExprBindings.lookup(EnvironmentEntry(E, LCtx));
82bc37b8dd9914e02580f531fa6e5e72be34d9675eZhongxing Xu        if (X)
83bc37b8dd9914e02580f531fa6e5e72be34d9675eZhongxing Xu          return *X;
84bc37b8dd9914e02580f531fa6e5e72be34d9675eZhongxing Xu        else
85c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek          return svalBuilder.makeIntVal(cast<IntegerLiteral>(E));
86d72ee907f76000446c706471e93d1f299104f9a7Ted Kremenek      }
871a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek      case Stmt::ObjCBoolLiteralExprClass:
881a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek        return svalBuilder.makeBoolVal(cast<ObjCBoolLiteralExpr>(E));
891a45a5ff5d495cb6cd9a3d4d06317af79c0f634dTed Kremenek
90e970c60dadaf22019743724bac879dbefbc4f5e3Ted Kremenek      // For special C0xx nullptr case, make a null pointer SVal.
91e970c60dadaf22019743724bac879dbefbc4f5e3Ted Kremenek      case Stmt::CXXNullPtrLiteralExprClass:
92e970c60dadaf22019743724bac879dbefbc4f5e3Ted Kremenek        return svalBuilder.makeNull();
934765fa05b5652fcc4356371c2f481d0ea9a1b007John McCall      case Stmt::ExprWithCleanupsClass:
944765fa05b5652fcc4356371c2f481d0ea9a1b007John McCall        E = cast<ExprWithCleanups>(E)->getSubExpr();
95d706434b0231c76fd9acf30060646a7aa8f69aefZhongxing Xu        continue;
96d706434b0231c76fd9acf30060646a7aa8f69aefZhongxing Xu      case Stmt::CXXBindTemporaryExprClass:
97d706434b0231c76fd9acf30060646a7aa8f69aefZhongxing Xu        E = cast<CXXBindTemporaryExpr>(E)->getSubExpr();
98d706434b0231c76fd9acf30060646a7aa8f69aefZhongxing Xu        continue;
9969a0e5021c5c49a34aa25cd89b1e613a52097e65Jordan Rose      case Stmt::SubstNonTypeTemplateParmExprClass:
10069a0e5021c5c49a34aa25cd89b1e613a52097e65Jordan Rose        E = cast<SubstNonTypeTemplateParmExpr>(E)->getReplacement();
10169a0e5021c5c49a34aa25cd89b1e613a52097e65Jordan Rose        continue;
102b66529d04727dc686b97ea3d937fc9785792f505Jordan Rose      case Stmt::CXXDefaultArgExprClass:
103b66529d04727dc686b97ea3d937fc9785792f505Jordan Rose        E = cast<CXXDefaultArgExpr>(E)->getExpr();
104b66529d04727dc686b97ea3d937fc9785792f505Jordan Rose        continue;
1054c62b557e269a27515dfca1f754ae936c8fdb824Ted Kremenek      case Stmt::ObjCStringLiteralClass: {
1064c62b557e269a27515dfca1f754ae936c8fdb824Ted Kremenek        MemRegionManager &MRMgr = svalBuilder.getRegionManager();
1074c62b557e269a27515dfca1f754ae936c8fdb824Ted Kremenek        const ObjCStringLiteral *SL = cast<ObjCStringLiteral>(E);
1084c62b557e269a27515dfca1f754ae936c8fdb824Ted Kremenek        return svalBuilder.makeLoc(MRMgr.getObjCStringRegion(SL));
1094c62b557e269a27515dfca1f754ae936c8fdb824Ted Kremenek      }
110e739a29c62c67eaec0af5c4d5c75f9e8f11228bdTed Kremenek      case Stmt::StringLiteralClass: {
111e739a29c62c67eaec0af5c4d5c75f9e8f11228bdTed Kremenek        MemRegionManager &MRMgr = svalBuilder.getRegionManager();
112e739a29c62c67eaec0af5c4d5c75f9e8f11228bdTed Kremenek        const StringLiteral *SL = cast<StringLiteral>(E);
113e739a29c62c67eaec0af5c4d5c75f9e8f11228bdTed Kremenek        return svalBuilder.makeLoc(MRMgr.getStringRegion(SL));
114e739a29c62c67eaec0af5c4d5c75f9e8f11228bdTed Kremenek      }
115256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek      case Stmt::ReturnStmtClass: {
116256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek        const ReturnStmt *RS = cast<ReturnStmt>(E);
117256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek        if (const Expr *RE = RS->getRetValue()) {
118256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek          E = RE;
119256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek          continue;
120256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek        }
121256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek        return UndefinedVal();
122256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek      }
123f8b5aae41e46f94fe90ed5f1ee98f36f0aa59dc9Ted Kremenek
124d706434b0231c76fd9acf30060646a7aa8f69aefZhongxing Xu      // Handle all other Stmt* using a lookup.
125d72ee907f76000446c706471e93d1f299104f9a7Ted Kremenek      default:
126d72ee907f76000446c706471e93d1f299104f9a7Ted Kremenek        break;
127d72ee907f76000446c706471e93d1f299104f9a7Ted Kremenek    };
128d72ee907f76000446c706471e93d1f299104f9a7Ted Kremenek    break;
129d72ee907f76000446c706471e93d1f299104f9a7Ted Kremenek  }
1305eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek  return lookupExpr(EnvironmentEntry(E, LCtx));
131d72ee907f76000446c706471e93d1f299104f9a7Ted Kremenek}
1328133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek
1335eca482fe895ea57bc82410222e6426c09e63284Ted KremenekEnvironment EnvironmentManager::bindExpr(Environment Env,
1345eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek                                         const EnvironmentEntry &E,
1355eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek                                         SVal V,
1365eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek                                         bool Invalidate) {
1371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  if (V.isUnknown()) {
138d72ee907f76000446c706471e93d1f299104f9a7Ted Kremenek    if (Invalidate)
1395eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek      return Environment(F.remove(Env.ExprBindings, E));
140d72ee907f76000446c706471e93d1f299104f9a7Ted Kremenek    else
141d72ee907f76000446c706471e93d1f299104f9a7Ted Kremenek      return Env;
142d72ee907f76000446c706471e93d1f299104f9a7Ted Kremenek  }
1435eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek  return Environment(F.add(Env.ExprBindings, E, V));
144d72ee907f76000446c706471e93d1f299104f9a7Ted Kremenek}
145df9cdf8fce5bb43b335994f946f7c8e3a3bca7faTed Kremenek
1465eca482fe895ea57bc82410222e6426c09e63284Ted Kremenekstatic inline EnvironmentEntry MakeLocation(const EnvironmentEntry &E) {
1475eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek  const Stmt *S = E.getStmt();
1485eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek  S = (const Stmt*) (((uintptr_t) S) | 0x1);
1495eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek  return EnvironmentEntry(S, E.getLocationContext());
1506d4c022695c2d780ccb63ce43a50588412b80813Ted Kremenek}
1516d4c022695c2d780ccb63ce43a50588412b80813Ted Kremenek
1526d4c022695c2d780ccb63ce43a50588412b80813Ted KremenekEnvironment EnvironmentManager::bindExprAndLocation(Environment Env,
1535eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek                                                    const EnvironmentEntry &E,
1546d4c022695c2d780ccb63ce43a50588412b80813Ted Kremenek                                                    SVal location, SVal V) {
1555eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek  return Environment(F.add(F.add(Env.ExprBindings, MakeLocation(E), location),
1565eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek                           E, V));
1576d4c022695c2d780ccb63ce43a50588412b80813Ted Kremenek}
1586d4c022695c2d780ccb63ce43a50588412b80813Ted Kremenek
1595216ad7e095873f19e535ad1efba91973f05d8e8Ted Kremeneknamespace {
160ba5fb5a955c896815c439289fc51c03cf0635129Kovarththanan Rajaratnamclass MarkLiveCallback : public SymbolVisitor {
1615216ad7e095873f19e535ad1efba91973f05d8e8Ted Kremenek  SymbolReaper &SymReaper;
1625216ad7e095873f19e535ad1efba91973f05d8e8Ted Kremenekpublic:
1631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  MarkLiveCallback(SymbolReaper &symreaper) : SymReaper(symreaper) {}
1647f9b1d963d4b7e2faff7305733e3453130b402feTed Kremenek  bool VisitSymbol(SymbolRef sym) {
1657f9b1d963d4b7e2faff7305733e3453130b402feTed Kremenek    SymReaper.markLive(sym);
1667f9b1d963d4b7e2faff7305733e3453130b402feTed Kremenek    return true;
1677f9b1d963d4b7e2faff7305733e3453130b402feTed Kremenek  }
1687f9b1d963d4b7e2faff7305733e3453130b402feTed Kremenek  bool VisitMemRegion(const MemRegion *R) {
1697f9b1d963d4b7e2faff7305733e3453130b402feTed Kremenek    SymReaper.markLive(R);
1707f9b1d963d4b7e2faff7305733e3453130b402feTed Kremenek    return true;
1717f9b1d963d4b7e2faff7305733e3453130b402feTed Kremenek  }
1725216ad7e095873f19e535ad1efba91973f05d8e8Ted Kremenek};
1735216ad7e095873f19e535ad1efba91973f05d8e8Ted Kremenek} // end anonymous namespace
1745216ad7e095873f19e535ad1efba91973f05d8e8Ted Kremenek
1755eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek// In addition to mapping from EnvironmentEntry - > SVals in the Environment,
1765eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek// we also maintain a mapping from EnvironmentEntry -> SVals (locations)
1775eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek// that were used during a load and store.
1785eca482fe895ea57bc82410222e6426c09e63284Ted Kremenekstatic inline bool IsLocation(const EnvironmentEntry &E) {
1795eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek  const Stmt *S = E.getStmt();
1806d4c022695c2d780ccb63ce43a50588412b80813Ted Kremenek  return (bool) (((uintptr_t) S) & 0x1);
1816d4c022695c2d780ccb63ce43a50588412b80813Ted Kremenek}
1827b73b92870aa6271ac3d0a91eca83f6dde68c904Zhongxing Xu
183db0594bfc013131f88429add4eb653c285fa94fbTed Kremenek// removeDeadBindings:
1849d8d0fc04d69bfae2478eb17df5e0335648a82c5Zhongxing Xu//  - Remove subexpression bindings.
1859d8d0fc04d69bfae2478eb17df5e0335648a82c5Zhongxing Xu//  - Remove dead block expression bindings.
1869d8d0fc04d69bfae2478eb17df5e0335648a82c5Zhongxing Xu//  - Keep live block expression bindings:
1871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump//   - Mark their reachable symbols live in SymbolReaper,
1889d8d0fc04d69bfae2478eb17df5e0335648a82c5Zhongxing Xu//     see ScanReachableSymbols.
1899d8d0fc04d69bfae2478eb17df5e0335648a82c5Zhongxing Xu//   - Mark the region in DRoots if the binding is a loc::MemRegionVal.
1901eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpEnvironment
191db0594bfc013131f88429add4eb653c285fa94fbTed KremenekEnvironmentManager::removeDeadBindings(Environment Env,
1920fb0bc4067d6c9d7c0e655300ef309b05d3adfc9Ted Kremenek                                       SymbolReaper &SymReaper,
1938bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek                                       ProgramStateRef ST) {
1941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1950fb0bc4067d6c9d7c0e655300ef309b05d3adfc9Ted Kremenek  // We construct a new Environment object entirely, as this is cheaper than
1960fb0bc4067d6c9d7c0e655300ef309b05d3adfc9Ted Kremenek  // individually removing all the subexpression bindings (which will greatly
1970fb0bc4067d6c9d7c0e655300ef309b05d3adfc9Ted Kremenek  // outnumber block-level expression bindings).
198c179a7fbb294fe3ff6cf5479f6239a10f39628c7Zhongxing Xu  Environment NewEnv = getInitialEnvironment();
1996d4c022695c2d780ccb63ce43a50588412b80813Ted Kremenek
2005eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek  SmallVector<std::pair<EnvironmentEntry, SVal>, 10> deferredLocations;
2011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2025f625712f622f6e57de17b6f7eec242956b993eeAnna Zaks  MarkLiveCallback CB(SymReaper);
2035f625712f622f6e57de17b6f7eec242956b993eeAnna Zaks  ScanReachableSymbols RSScaner(ST, CB);
2045f625712f622f6e57de17b6f7eec242956b993eeAnna Zaks
2055eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek  llvm::ImmutableMapRef<EnvironmentEntry,SVal>
2061e705d57f27f6f899882440cbd5b0fbf520e2fe4Anna Zaks    EBMapRef(NewEnv.ExprBindings.getRootWithoutRetain(),
2071e705d57f27f6f899882440cbd5b0fbf520e2fe4Anna Zaks             F.getTreeFactory());
2081e705d57f27f6f899882440cbd5b0fbf520e2fe4Anna Zaks
209df9cdf8fce5bb43b335994f946f7c8e3a3bca7faTed Kremenek  // Iterate over the block-expr bindings.
2101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  for (Environment::iterator I = Env.begin(), E = Env.end();
211df9cdf8fce5bb43b335994f946f7c8e3a3bca7faTed Kremenek       I != E; ++I) {
2121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2135eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek    const EnvironmentEntry &BlkExpr = I.getKey();
2146d4c022695c2d780ccb63ce43a50588412b80813Ted Kremenek    // For recorded locations (used when evaluating loads and stores), we
2156d4c022695c2d780ccb63ce43a50588412b80813Ted Kremenek    // consider them live only when their associated normal expression is
2166d4c022695c2d780ccb63ce43a50588412b80813Ted Kremenek    // also live.
2176d4c022695c2d780ccb63ce43a50588412b80813Ted Kremenek    // NOTE: This assumes that loads/stores that evaluated to UnknownVal
2186d4c022695c2d780ccb63ce43a50588412b80813Ted Kremenek    // still have an entry in the map.
2196d4c022695c2d780ccb63ce43a50588412b80813Ted Kremenek    if (IsLocation(BlkExpr)) {
2206d4c022695c2d780ccb63ce43a50588412b80813Ted Kremenek      deferredLocations.push_back(std::make_pair(BlkExpr, I.getData()));
2216d4c022695c2d780ccb63ce43a50588412b80813Ted Kremenek      continue;
2226d4c022695c2d780ccb63ce43a50588412b80813Ted Kremenek    }
2237b73b92870aa6271ac3d0a91eca83f6dde68c904Zhongxing Xu    const SVal &X = I.getData();
2247b73b92870aa6271ac3d0a91eca83f6dde68c904Zhongxing Xu
2255eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek    if (SymReaper.isLive(BlkExpr.getStmt(), BlkExpr.getLocationContext())) {
2260fb0bc4067d6c9d7c0e655300ef309b05d3adfc9Ted Kremenek      // Copy the binding to the new map.
2271e705d57f27f6f899882440cbd5b0fbf520e2fe4Anna Zaks      EBMapRef = EBMapRef.add(BlkExpr, X);
2281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2299e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek      // If the block expr's value is a memory region, then mark that region.
230ce2f9bd2bc7dd4e070d46114b6a921127bd1ca86Zhongxing Xu      if (isa<loc::MemRegionVal>(X)) {
231bea2753da897ede723e70bcd17023d050b0603d0Ted Kremenek        const MemRegion *R = cast<loc::MemRegionVal>(X).getRegion();
232bea2753da897ede723e70bcd17023d050b0603d0Ted Kremenek        SymReaper.markLive(R);
233ce2f9bd2bc7dd4e070d46114b6a921127bd1ca86Zhongxing Xu      }
2349e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek
2355216ad7e095873f19e535ad1efba91973f05d8e8Ted Kremenek      // Mark all symbols in the block expr's value live.
2365f625712f622f6e57de17b6f7eec242956b993eeAnna Zaks      RSScaner.scan(X);
2370fb0bc4067d6c9d7c0e655300ef309b05d3adfc9Ted Kremenek      continue;
238df9cdf8fce5bb43b335994f946f7c8e3a3bca7faTed Kremenek    }
239df9cdf8fce5bb43b335994f946f7c8e3a3bca7faTed Kremenek  }
2406d4c022695c2d780ccb63ce43a50588412b80813Ted Kremenek
2416d4c022695c2d780ccb63ce43a50588412b80813Ted Kremenek  // Go through he deferred locations and add them to the new environment if
2426d4c022695c2d780ccb63ce43a50588412b80813Ted Kremenek  // the correspond Stmt* is in the map as well.
2435eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek  for (SmallVectorImpl<std::pair<EnvironmentEntry, SVal> >::iterator
2446d4c022695c2d780ccb63ce43a50588412b80813Ted Kremenek      I = deferredLocations.begin(), E = deferredLocations.end(); I != E; ++I) {
2455eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek    const EnvironmentEntry &En = I->first;
2465eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek    const Stmt *S = (Stmt*) (((uintptr_t) En.getStmt()) & (uintptr_t) ~0x1);
2475eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek    if (EBMapRef.lookup(EnvironmentEntry(S, En.getLocationContext())))
2485eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek      EBMapRef = EBMapRef.add(En, I->second);
2496d4c022695c2d780ccb63ce43a50588412b80813Ted Kremenek  }
250df9cdf8fce5bb43b335994f946f7c8e3a3bca7faTed Kremenek
2511e705d57f27f6f899882440cbd5b0fbf520e2fe4Anna Zaks  NewEnv.ExprBindings = EBMapRef.asImmutableMap();
2520fb0bc4067d6c9d7c0e655300ef309b05d3adfc9Ted Kremenek  return NewEnv;
253df9cdf8fce5bb43b335994f946f7c8e3a3bca7faTed Kremenek}
2545eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek
2555eca482fe895ea57bc82410222e6426c09e63284Ted Kremenekvoid Environment::print(raw_ostream &Out, const char *NL,
2565eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek                        const char *Sep) const {
2575eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek  printAux(Out, false, NL, Sep);
2585eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek  printAux(Out, true, NL, Sep);
2595eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek}
2605eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek
2615eca482fe895ea57bc82410222e6426c09e63284Ted Kremenekvoid Environment::printAux(raw_ostream &Out, bool printLocations,
2625eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek                           const char *NL,
2635eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek                           const char *Sep) const{
2645eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek
2655eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek  bool isFirst = true;
2665eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek
2675eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek  for (Environment::iterator I = begin(), E = end(); I != E; ++I) {
2685eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek    const EnvironmentEntry &En = I.getKey();
2695eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek    if (IsLocation(En)) {
2705eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek      if (!printLocations)
2715eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek        continue;
2725eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek    }
2735eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek    else {
2745eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek      if (printLocations)
2755eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek        continue;
2765eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek    }
2775eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek
2785eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek    if (isFirst) {
2795eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek      Out << NL << NL
2805eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek          << (printLocations ? "Load/Store locations:" : "Expressions:")
2815eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek          << NL;
2825eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek      isFirst = false;
2835eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek    } else {
2845eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek      Out << NL;
2855eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek    }
2865eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek
2875eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek    const Stmt *S = En.getStmt();
2885eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek    if (printLocations) {
2895eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek      S = (Stmt*) (((uintptr_t) S) & ((uintptr_t) ~0x1));
2905eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek    }
2915eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek
29231ba6135375433b617a8587ea6cc836a014ebd86Roman Divacky    Out << " (" << (const void*) En.getLocationContext() << ','
29331ba6135375433b617a8587ea6cc836a014ebd86Roman Divacky      << (const void*) S << ") ";
2945eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek    LangOptions LO; // FIXME.
2955eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek    S->printPretty(Out, 0, PrintingPolicy(LO));
2965eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek    Out << " : " << I.getData();
2975eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek  }
2985eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek}
299