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