Environment.cpp revision db0594bfc013131f88429add4eb653c285fa94fb
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
145e2d2c2ee3cf410643e0f9a5701708e51409d973Benjamin Kramer#include "clang/Analysis/AnalysisContext.h"
155e2d2c2ee3cf410643e0f9a5701708e51409d973Benjamin Kramer#include "clang/Analysis/CFG.h"
1621142581d55918beed544a757e4af3bb865b1812Ted Kremenek#include "clang/StaticAnalyzer/PathSensitive/GRState.h"
178133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek
188133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenekusing namespace clang;
199ef6537a894c33003359b1f9b9676e9178e028b7Ted Kremenekusing namespace ento;
208133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek
21465846324f412055dd1ce270d757bfeead0811dcTed KremenekSVal Environment::lookupExpr(const Stmt* E) const {
22465846324f412055dd1ce270d757bfeead0811dcTed Kremenek  const SVal* X = ExprBindings.lookup(E);
23465846324f412055dd1ce270d757bfeead0811dcTed Kremenek  if (X) {
24465846324f412055dd1ce270d757bfeead0811dcTed Kremenek    SVal V = *X;
25465846324f412055dd1ce270d757bfeead0811dcTed Kremenek    return V;
26465846324f412055dd1ce270d757bfeead0811dcTed Kremenek  }
27465846324f412055dd1ce270d757bfeead0811dcTed Kremenek  return UnknownVal();
28465846324f412055dd1ce270d757bfeead0811dcTed Kremenek}
29465846324f412055dd1ce270d757bfeead0811dcTed Kremenek
30c8413fd03f73084a5c93028f8b4db619fc388087Ted KremenekSVal Environment::getSVal(const Stmt *E, SValBuilder& svalBuilder) const {
31d72ee907f76000446c706471e93d1f299104f9a7Ted Kremenek  for (;;) {
32d72ee907f76000446c706471e93d1f299104f9a7Ted Kremenek    switch (E->getStmtClass()) {
331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      case Stmt::AddrLabelExprClass:
34c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek        return svalBuilder.makeLoc(cast<AddrLabelExpr>(E));
351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      case Stmt::ParenExprClass:
36c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek        // ParenExprs are no-ops.
37d72ee907f76000446c706471e93d1f299104f9a7Ted Kremenek        E = cast<ParenExpr>(E)->getSubExpr();
38d72ee907f76000446c706471e93d1f299104f9a7Ted Kremenek        continue;
39d72ee907f76000446c706471e93d1f299104f9a7Ted Kremenek      case Stmt::CharacterLiteralClass: {
4023ec48cd3369c8d7d1ab3c3f2226cfcffd2cd3d3Ted Kremenek        const CharacterLiteral* C = cast<CharacterLiteral>(E);
41c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek        return svalBuilder.makeIntVal(C->getValue(), C->getType());
42d72ee907f76000446c706471e93d1f299104f9a7Ted Kremenek      }
43477323d58a0de352c6a61e08b5a83127c4adc904Zhongxing Xu      case Stmt::CXXBoolLiteralExprClass: {
44477323d58a0de352c6a61e08b5a83127c4adc904Zhongxing Xu        const SVal *X = ExprBindings.lookup(E);
45477323d58a0de352c6a61e08b5a83127c4adc904Zhongxing Xu        if (X)
46477323d58a0de352c6a61e08b5a83127c4adc904Zhongxing Xu          return *X;
47477323d58a0de352c6a61e08b5a83127c4adc904Zhongxing Xu        else
48c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek          return svalBuilder.makeIntVal(cast<CXXBoolLiteralExpr>(E));
49477323d58a0de352c6a61e08b5a83127c4adc904Zhongxing Xu      }
50d72ee907f76000446c706471e93d1f299104f9a7Ted Kremenek      case Stmt::IntegerLiteralClass: {
51bc37b8dd9914e02580f531fa6e5e72be34d9675eZhongxing Xu        // In C++, this expression may have been bound to a temporary object.
52bc37b8dd9914e02580f531fa6e5e72be34d9675eZhongxing Xu        SVal const *X = ExprBindings.lookup(E);
53bc37b8dd9914e02580f531fa6e5e72be34d9675eZhongxing Xu        if (X)
54bc37b8dd9914e02580f531fa6e5e72be34d9675eZhongxing Xu          return *X;
55bc37b8dd9914e02580f531fa6e5e72be34d9675eZhongxing Xu        else
56c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek          return svalBuilder.makeIntVal(cast<IntegerLiteral>(E));
57d72ee907f76000446c706471e93d1f299104f9a7Ted Kremenek      }
580835a3cdeefe714b4959d31127ea155e56393125Argyrios Kyrtzidis      case Stmt::ImplicitCastExprClass:
596eec8e883de118b431e3ead5b1e604a6ac68ff6bDouglas Gregor      case Stmt::CStyleCastExprClass: {
60c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek        // We blast through no-op casts to get the descendant
61c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek        // subexpression that has a value.
6223ec48cd3369c8d7d1ab3c3f2226cfcffd2cd3d3Ted Kremenek        const CastExpr* C = cast<CastExpr>(E);
63d72ee907f76000446c706471e93d1f299104f9a7Ted Kremenek        QualType CT = C->getType();
64d72ee907f76000446c706471e93d1f299104f9a7Ted Kremenek        if (CT->isVoidType())
65d72ee907f76000446c706471e93d1f299104f9a7Ted Kremenek          return UnknownVal();
66892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek        if (C->getCastKind() == CK_NoOp) {
67a8d835abb81eb26850fa27738df0e42f12fae66aZhongxing Xu          E = C->getSubExpr();
68d706434b0231c76fd9acf30060646a7aa8f69aefZhongxing Xu          continue;
69d706434b0231c76fd9acf30060646a7aa8f69aefZhongxing Xu        }
70d72ee907f76000446c706471e93d1f299104f9a7Ted Kremenek        break;
71d72ee907f76000446c706471e93d1f299104f9a7Ted Kremenek      }
724765fa05b5652fcc4356371c2f481d0ea9a1b007John McCall      case Stmt::ExprWithCleanupsClass:
734765fa05b5652fcc4356371c2f481d0ea9a1b007John McCall        E = cast<ExprWithCleanups>(E)->getSubExpr();
74d706434b0231c76fd9acf30060646a7aa8f69aefZhongxing Xu        continue;
75d706434b0231c76fd9acf30060646a7aa8f69aefZhongxing Xu      case Stmt::CXXBindTemporaryExprClass:
76d706434b0231c76fd9acf30060646a7aa8f69aefZhongxing Xu        E = cast<CXXBindTemporaryExpr>(E)->getSubExpr();
77d706434b0231c76fd9acf30060646a7aa8f69aefZhongxing Xu        continue;
780e38d5d6775a26f8f39df353e34b0dc14c2d6cfcZhongxing Xu      case Stmt::CXXFunctionalCastExprClass:
790e38d5d6775a26f8f39df353e34b0dc14c2d6cfcZhongxing Xu        E = cast<CXXFunctionalCastExpr>(E)->getSubExpr();
80c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek        continue;
81d706434b0231c76fd9acf30060646a7aa8f69aefZhongxing Xu      // Handle all other Stmt* using a lookup.
82d72ee907f76000446c706471e93d1f299104f9a7Ted Kremenek      default:
83d72ee907f76000446c706471e93d1f299104f9a7Ted Kremenek        break;
84d72ee907f76000446c706471e93d1f299104f9a7Ted Kremenek    };
85d72ee907f76000446c706471e93d1f299104f9a7Ted Kremenek    break;
86d72ee907f76000446c706471e93d1f299104f9a7Ted Kremenek  }
87465846324f412055dd1ce270d757bfeead0811dcTed Kremenek  return lookupExpr(E);
88d72ee907f76000446c706471e93d1f299104f9a7Ted Kremenek}
898133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek
906d4c022695c2d780ccb63ce43a50588412b80813Ted KremenekEnvironment EnvironmentManager::bindExpr(Environment Env, const Stmt *S,
911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                         SVal V, bool Invalidate) {
920fb0bc4067d6c9d7c0e655300ef309b05d3adfc9Ted Kremenek  assert(S);
931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  if (V.isUnknown()) {
95d72ee907f76000446c706471e93d1f299104f9a7Ted Kremenek    if (Invalidate)
963baf672378f105602d2b12f03f00277ae1936fe9Ted Kremenek      return Environment(F.remove(Env.ExprBindings, S));
97d72ee907f76000446c706471e93d1f299104f9a7Ted Kremenek    else
98d72ee907f76000446c706471e93d1f299104f9a7Ted Kremenek      return Env;
99d72ee907f76000446c706471e93d1f299104f9a7Ted Kremenek  }
1008133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek
1013baf672378f105602d2b12f03f00277ae1936fe9Ted Kremenek  return Environment(F.add(Env.ExprBindings, S, V));
102d72ee907f76000446c706471e93d1f299104f9a7Ted Kremenek}
103df9cdf8fce5bb43b335994f946f7c8e3a3bca7faTed Kremenek
1046d4c022695c2d780ccb63ce43a50588412b80813Ted Kremenekstatic inline const Stmt *MakeLocation(const Stmt *S) {
1056d4c022695c2d780ccb63ce43a50588412b80813Ted Kremenek  return (const Stmt*) (((uintptr_t) S) | 0x1);
1066d4c022695c2d780ccb63ce43a50588412b80813Ted Kremenek}
1076d4c022695c2d780ccb63ce43a50588412b80813Ted Kremenek
1086d4c022695c2d780ccb63ce43a50588412b80813Ted KremenekEnvironment EnvironmentManager::bindExprAndLocation(Environment Env,
1096d4c022695c2d780ccb63ce43a50588412b80813Ted Kremenek                                                    const Stmt *S,
1106d4c022695c2d780ccb63ce43a50588412b80813Ted Kremenek                                                    SVal location, SVal V) {
1113baf672378f105602d2b12f03f00277ae1936fe9Ted Kremenek  return Environment(F.add(F.add(Env.ExprBindings, MakeLocation(S), location),
112cf848879ff280e7114f78e058019c1e8b527b3c9Zhanyong Wan                           S, V));
1136d4c022695c2d780ccb63ce43a50588412b80813Ted Kremenek}
1146d4c022695c2d780ccb63ce43a50588412b80813Ted Kremenek
1155216ad7e095873f19e535ad1efba91973f05d8e8Ted Kremeneknamespace {
116ba5fb5a955c896815c439289fc51c03cf0635129Kovarththanan Rajaratnamclass MarkLiveCallback : public SymbolVisitor {
1175216ad7e095873f19e535ad1efba91973f05d8e8Ted Kremenek  SymbolReaper &SymReaper;
1185216ad7e095873f19e535ad1efba91973f05d8e8Ted Kremenekpublic:
1191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  MarkLiveCallback(SymbolReaper &symreaper) : SymReaper(symreaper) {}
1205216ad7e095873f19e535ad1efba91973f05d8e8Ted Kremenek  bool VisitSymbol(SymbolRef sym) { SymReaper.markLive(sym); return true; }
1215216ad7e095873f19e535ad1efba91973f05d8e8Ted Kremenek};
1225216ad7e095873f19e535ad1efba91973f05d8e8Ted Kremenek} // end anonymous namespace
1235216ad7e095873f19e535ad1efba91973f05d8e8Ted Kremenek
1247b73b92870aa6271ac3d0a91eca83f6dde68c904Zhongxing Xustatic bool isBlockExprInCallers(const Stmt *E, const LocationContext *LC) {
1257b73b92870aa6271ac3d0a91eca83f6dde68c904Zhongxing Xu  const LocationContext *ParentLC = LC->getParent();
1267b73b92870aa6271ac3d0a91eca83f6dde68c904Zhongxing Xu  while (ParentLC) {
1277b73b92870aa6271ac3d0a91eca83f6dde68c904Zhongxing Xu    CFG &C = *ParentLC->getCFG();
1287b73b92870aa6271ac3d0a91eca83f6dde68c904Zhongxing Xu    if (C.isBlkExpr(E))
1297b73b92870aa6271ac3d0a91eca83f6dde68c904Zhongxing Xu      return true;
1307b73b92870aa6271ac3d0a91eca83f6dde68c904Zhongxing Xu    ParentLC = ParentLC->getParent();
1317b73b92870aa6271ac3d0a91eca83f6dde68c904Zhongxing Xu  }
1327b73b92870aa6271ac3d0a91eca83f6dde68c904Zhongxing Xu
1337b73b92870aa6271ac3d0a91eca83f6dde68c904Zhongxing Xu  return false;
1347b73b92870aa6271ac3d0a91eca83f6dde68c904Zhongxing Xu}
1357b73b92870aa6271ac3d0a91eca83f6dde68c904Zhongxing Xu
1366d4c022695c2d780ccb63ce43a50588412b80813Ted Kremenek// In addition to mapping from Stmt * - > SVals in the Environment, we also
1376d4c022695c2d780ccb63ce43a50588412b80813Ted Kremenek// maintain a mapping from Stmt * -> SVals (locations) that were used during
1386d4c022695c2d780ccb63ce43a50588412b80813Ted Kremenek// a load and store.
1396d4c022695c2d780ccb63ce43a50588412b80813Ted Kremenekstatic inline bool IsLocation(const Stmt *S) {
1406d4c022695c2d780ccb63ce43a50588412b80813Ted Kremenek  return (bool) (((uintptr_t) S) & 0x1);
1416d4c022695c2d780ccb63ce43a50588412b80813Ted Kremenek}
1427b73b92870aa6271ac3d0a91eca83f6dde68c904Zhongxing Xu
143db0594bfc013131f88429add4eb653c285fa94fbTed Kremenek// removeDeadBindings:
1449d8d0fc04d69bfae2478eb17df5e0335648a82c5Zhongxing Xu//  - Remove subexpression bindings.
1459d8d0fc04d69bfae2478eb17df5e0335648a82c5Zhongxing Xu//  - Remove dead block expression bindings.
1469d8d0fc04d69bfae2478eb17df5e0335648a82c5Zhongxing Xu//  - Keep live block expression bindings:
1471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump//   - Mark their reachable symbols live in SymbolReaper,
1489d8d0fc04d69bfae2478eb17df5e0335648a82c5Zhongxing Xu//     see ScanReachableSymbols.
1499d8d0fc04d69bfae2478eb17df5e0335648a82c5Zhongxing Xu//   - Mark the region in DRoots if the binding is a loc::MemRegionVal.
1501eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpEnvironment
151db0594bfc013131f88429add4eb653c285fa94fbTed KremenekEnvironmentManager::removeDeadBindings(Environment Env,
1520fb0bc4067d6c9d7c0e655300ef309b05d3adfc9Ted Kremenek                                       SymbolReaper &SymReaper,
1530fb0bc4067d6c9d7c0e655300ef309b05d3adfc9Ted Kremenek                                       const GRState *ST,
1540fb0bc4067d6c9d7c0e655300ef309b05d3adfc9Ted Kremenek                              llvm::SmallVectorImpl<const MemRegion*> &DRoots) {
1551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
156c179a7fbb294fe3ff6cf5479f6239a10f39628c7Zhongxing Xu  CFG &C = *SymReaper.getLocationContext()->getCFG();
1571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1580fb0bc4067d6c9d7c0e655300ef309b05d3adfc9Ted Kremenek  // We construct a new Environment object entirely, as this is cheaper than
1590fb0bc4067d6c9d7c0e655300ef309b05d3adfc9Ted Kremenek  // individually removing all the subexpression bindings (which will greatly
1600fb0bc4067d6c9d7c0e655300ef309b05d3adfc9Ted Kremenek  // outnumber block-level expression bindings).
161c179a7fbb294fe3ff6cf5479f6239a10f39628c7Zhongxing Xu  Environment NewEnv = getInitialEnvironment();
1626d4c022695c2d780ccb63ce43a50588412b80813Ted Kremenek
1636d4c022695c2d780ccb63ce43a50588412b80813Ted Kremenek  llvm::SmallVector<std::pair<const Stmt*, SVal>, 10> deferredLocations;
1641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
165df9cdf8fce5bb43b335994f946f7c8e3a3bca7faTed Kremenek  // Iterate over the block-expr bindings.
1661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  for (Environment::iterator I = Env.begin(), E = Env.end();
167df9cdf8fce5bb43b335994f946f7c8e3a3bca7faTed Kremenek       I != E; ++I) {
1681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
16923ec48cd3369c8d7d1ab3c3f2226cfcffd2cd3d3Ted Kremenek    const Stmt *BlkExpr = I.getKey();
1706d4c022695c2d780ccb63ce43a50588412b80813Ted Kremenek
1716d4c022695c2d780ccb63ce43a50588412b80813Ted Kremenek    // For recorded locations (used when evaluating loads and stores), we
1726d4c022695c2d780ccb63ce43a50588412b80813Ted Kremenek    // consider them live only when their associated normal expression is
1736d4c022695c2d780ccb63ce43a50588412b80813Ted Kremenek    // also live.
1746d4c022695c2d780ccb63ce43a50588412b80813Ted Kremenek    // NOTE: This assumes that loads/stores that evaluated to UnknownVal
1756d4c022695c2d780ccb63ce43a50588412b80813Ted Kremenek    // still have an entry in the map.
1766d4c022695c2d780ccb63ce43a50588412b80813Ted Kremenek    if (IsLocation(BlkExpr)) {
1776d4c022695c2d780ccb63ce43a50588412b80813Ted Kremenek      deferredLocations.push_back(std::make_pair(BlkExpr, I.getData()));
1786d4c022695c2d780ccb63ce43a50588412b80813Ted Kremenek      continue;
1796d4c022695c2d780ccb63ce43a50588412b80813Ted Kremenek    }
1806d4c022695c2d780ccb63ce43a50588412b80813Ted Kremenek
1817b73b92870aa6271ac3d0a91eca83f6dde68c904Zhongxing Xu    const SVal &X = I.getData();
1827b73b92870aa6271ac3d0a91eca83f6dde68c904Zhongxing Xu
1837b73b92870aa6271ac3d0a91eca83f6dde68c904Zhongxing Xu    // Block-level expressions in callers are assumed always live.
1847b73b92870aa6271ac3d0a91eca83f6dde68c904Zhongxing Xu    if (isBlockExprInCallers(BlkExpr, SymReaper.getLocationContext())) {
1853baf672378f105602d2b12f03f00277ae1936fe9Ted Kremenek      NewEnv.ExprBindings = F.add(NewEnv.ExprBindings, BlkExpr, X);
1867b73b92870aa6271ac3d0a91eca83f6dde68c904Zhongxing Xu
1877b73b92870aa6271ac3d0a91eca83f6dde68c904Zhongxing Xu      if (isa<loc::MemRegionVal>(X)) {
1887b73b92870aa6271ac3d0a91eca83f6dde68c904Zhongxing Xu        const MemRegion* R = cast<loc::MemRegionVal>(X).getRegion();
1897b73b92870aa6271ac3d0a91eca83f6dde68c904Zhongxing Xu        DRoots.push_back(R);
1907b73b92870aa6271ac3d0a91eca83f6dde68c904Zhongxing Xu      }
1917b73b92870aa6271ac3d0a91eca83f6dde68c904Zhongxing Xu
1927b73b92870aa6271ac3d0a91eca83f6dde68c904Zhongxing Xu      // Mark all symbols in the block expr's value live.
1937b73b92870aa6271ac3d0a91eca83f6dde68c904Zhongxing Xu      MarkLiveCallback cb(SymReaper);
1947b73b92870aa6271ac3d0a91eca83f6dde68c904Zhongxing Xu      ST->scanReachableSymbols(X, cb);
1957b73b92870aa6271ac3d0a91eca83f6dde68c904Zhongxing Xu      continue;
1967b73b92870aa6271ac3d0a91eca83f6dde68c904Zhongxing Xu    }
1971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1980fb0bc4067d6c9d7c0e655300ef309b05d3adfc9Ted Kremenek    // Not a block-level expression?
1990fb0bc4067d6c9d7c0e655300ef309b05d3adfc9Ted Kremenek    if (!C.isBlkExpr(BlkExpr))
2000fb0bc4067d6c9d7c0e655300ef309b05d3adfc9Ted Kremenek      continue;
2011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2027dadf79bd809cc01fe275f9a7243593bc2af5c10Jordy Rose    if (SymReaper.isLive(BlkExpr)) {
2030fb0bc4067d6c9d7c0e655300ef309b05d3adfc9Ted Kremenek      // Copy the binding to the new map.
2043baf672378f105602d2b12f03f00277ae1936fe9Ted Kremenek      NewEnv.ExprBindings = F.add(NewEnv.ExprBindings, BlkExpr, X);
2051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2069e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek      // If the block expr's value is a memory region, then mark that region.
207ce2f9bd2bc7dd4e070d46114b6a921127bd1ca86Zhongxing Xu      if (isa<loc::MemRegionVal>(X)) {
208ce2f9bd2bc7dd4e070d46114b6a921127bd1ca86Zhongxing Xu        const MemRegion* R = cast<loc::MemRegionVal>(X).getRegion();
209ce2f9bd2bc7dd4e070d46114b6a921127bd1ca86Zhongxing Xu        DRoots.push_back(R);
210ce2f9bd2bc7dd4e070d46114b6a921127bd1ca86Zhongxing Xu      }
2119e24049bef26b6289cce9ac9b483c5cbb096e3aeTed Kremenek
2125216ad7e095873f19e535ad1efba91973f05d8e8Ted Kremenek      // Mark all symbols in the block expr's value live.
2135216ad7e095873f19e535ad1efba91973f05d8e8Ted Kremenek      MarkLiveCallback cb(SymReaper);
2140fb0bc4067d6c9d7c0e655300ef309b05d3adfc9Ted Kremenek      ST->scanReachableSymbols(X, cb);
2150fb0bc4067d6c9d7c0e655300ef309b05d3adfc9Ted Kremenek      continue;
216df9cdf8fce5bb43b335994f946f7c8e3a3bca7faTed Kremenek    }
2170fb0bc4067d6c9d7c0e655300ef309b05d3adfc9Ted Kremenek
2180fb0bc4067d6c9d7c0e655300ef309b05d3adfc9Ted Kremenek    // Otherwise the expression is dead with a couple exceptions.
2190fb0bc4067d6c9d7c0e655300ef309b05d3adfc9Ted Kremenek    // Do not misclean LogicalExpr or ConditionalOperator.  It is dead at the
2200fb0bc4067d6c9d7c0e655300ef309b05d3adfc9Ted Kremenek    // beginning of itself, but we need its UndefinedVal to determine its
2210fb0bc4067d6c9d7c0e655300ef309b05d3adfc9Ted Kremenek    // SVal.
2220fb0bc4067d6c9d7c0e655300ef309b05d3adfc9Ted Kremenek    if (X.isUndef() && cast<UndefinedVal>(X).getData())
2233baf672378f105602d2b12f03f00277ae1936fe9Ted Kremenek      NewEnv.ExprBindings = F.add(NewEnv.ExprBindings, BlkExpr, X);
224df9cdf8fce5bb43b335994f946f7c8e3a3bca7faTed Kremenek  }
2256d4c022695c2d780ccb63ce43a50588412b80813Ted Kremenek
2266d4c022695c2d780ccb63ce43a50588412b80813Ted Kremenek  // Go through he deferred locations and add them to the new environment if
2276d4c022695c2d780ccb63ce43a50588412b80813Ted Kremenek  // the correspond Stmt* is in the map as well.
2286d4c022695c2d780ccb63ce43a50588412b80813Ted Kremenek  for (llvm::SmallVectorImpl<std::pair<const Stmt*, SVal> >::iterator
2296d4c022695c2d780ccb63ce43a50588412b80813Ted Kremenek      I = deferredLocations.begin(), E = deferredLocations.end(); I != E; ++I) {
2306d4c022695c2d780ccb63ce43a50588412b80813Ted Kremenek    const Stmt *S = (Stmt*) (((uintptr_t) I->first) & (uintptr_t) ~0x1);
2316d4c022695c2d780ccb63ce43a50588412b80813Ted Kremenek    if (NewEnv.ExprBindings.lookup(S))
2323baf672378f105602d2b12f03f00277ae1936fe9Ted Kremenek      NewEnv.ExprBindings = F.add(NewEnv.ExprBindings, I->first, I->second);
2336d4c022695c2d780ccb63ce43a50588412b80813Ted Kremenek  }
234df9cdf8fce5bb43b335994f946f7c8e3a3bca7faTed Kremenek
2350fb0bc4067d6c9d7c0e655300ef309b05d3adfc9Ted Kremenek  return NewEnv;
236df9cdf8fce5bb43b335994f946f7c8e3a3bca7faTed Kremenek}
237