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