blob: 9d8e09c7041aac2a40f13ac614db1c5380e2d3c3 [file] [log] [blame]
Ted Kremenekd4931632008-11-12 19:21:30 +00001//== Environment.cpp - Map from Stmt* to Locations/Values -------*- C++ -*--==//
Ted Kremenek8133a262008-07-08 21:46:56 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defined the Environment and EnvironmentManager classes.
11//
12//===----------------------------------------------------------------------===//
Ted Kremenek5216ad72009-02-14 03:16:10 +000013#include "clang/Analysis/PathSensitive/GRState.h"
Ted Kremenekdf9cdf82008-08-20 17:08:29 +000014#include "clang/Analysis/Analyses/LiveVariables.h"
Ted Kremenek5216ad72009-02-14 03:16:10 +000015#include "llvm/Support/Compiler.h"
Benjamin Kramer6cb7c1a2009-08-23 12:08:50 +000016#include "llvm/ADT/ImmutableMap.h"
Ted Kremenek8133a262008-07-08 21:46:56 +000017
18using namespace clang;
19
Zhongxing Xud91ee272009-06-23 09:02:15 +000020SVal Environment::GetSVal(const Stmt *E, ValueManager& ValMgr) const {
Ted Kremenekd72ee902008-07-10 17:19:18 +000021
22 for (;;) {
23
24 switch (E->getStmtClass()) {
25
26 case Stmt::AddrLabelExprClass:
Zhongxing Xud91ee272009-06-23 09:02:15 +000027 return ValMgr.makeLoc(cast<AddrLabelExpr>(E));
Ted Kremenekd72ee902008-07-10 17:19:18 +000028
29 // ParenExprs are no-ops.
30
31 case Stmt::ParenExprClass:
32 E = cast<ParenExpr>(E)->getSubExpr();
33 continue;
34
35 case Stmt::CharacterLiteralClass: {
Ted Kremenek23ec48c2009-06-18 23:58:37 +000036 const CharacterLiteral* C = cast<CharacterLiteral>(E);
Zhongxing Xud91ee272009-06-23 09:02:15 +000037 return ValMgr.makeIntVal(C->getValue(), C->getType());
Ted Kremenekd72ee902008-07-10 17:19:18 +000038 }
39
40 case Stmt::IntegerLiteralClass: {
Zhongxing Xud91ee272009-06-23 09:02:15 +000041 return ValMgr.makeIntVal(cast<IntegerLiteral>(E));
Ted Kremenekd72ee902008-07-10 17:19:18 +000042 }
43
Zhongxing Xu143bf822008-10-25 14:18:57 +000044 // Casts where the source and target type are the same
45 // are no-ops. We blast through these to get the descendant
46 // subexpression that has a value.
47
Argyrios Kyrtzidis0835a3c2008-08-18 23:01:59 +000048 case Stmt::ImplicitCastExprClass:
Douglas Gregor6eec8e82008-10-28 15:36:24 +000049 case Stmt::CStyleCastExprClass: {
Ted Kremenek23ec48c2009-06-18 23:58:37 +000050 const CastExpr* C = cast<CastExpr>(E);
Ted Kremenekd72ee902008-07-10 17:19:18 +000051 QualType CT = C->getType();
Ted Kremenekd72ee902008-07-10 17:19:18 +000052
53 if (CT->isVoidType())
54 return UnknownVal();
55
56 break;
57 }
58
Ted Kremenekd4931632008-11-12 19:21:30 +000059 // Handle all other Stmt* using a lookup.
Ted Kremenekd72ee902008-07-10 17:19:18 +000060
61 default:
62 break;
63 };
64
65 break;
66 }
67
68 return LookupExpr(E);
69}
Ted Kremenek8133a262008-07-08 21:46:56 +000070
Zhongxing Xud91ee272009-06-23 09:02:15 +000071SVal Environment::GetBlkExprSVal(const Stmt *E, ValueManager& ValMgr) const {
Ted Kremenekd72ee902008-07-10 17:19:18 +000072
Ted Kremenekd4931632008-11-12 19:21:30 +000073 while (1) {
74 switch (E->getStmtClass()) {
75 case Stmt::ParenExprClass:
76 E = cast<ParenExpr>(E)->getSubExpr();
77 continue;
78
79 case Stmt::CharacterLiteralClass: {
Ted Kremenek23ec48c2009-06-18 23:58:37 +000080 const CharacterLiteral* C = cast<CharacterLiteral>(E);
Zhongxing Xud91ee272009-06-23 09:02:15 +000081 return ValMgr.makeIntVal(C->getValue(), C->getType());
Ted Kremenekd4931632008-11-12 19:21:30 +000082 }
83
84 case Stmt::IntegerLiteralClass: {
Zhongxing Xud91ee272009-06-23 09:02:15 +000085 return ValMgr.makeIntVal(cast<IntegerLiteral>(E));
Ted Kremenekd4931632008-11-12 19:21:30 +000086 }
87
88 default:
89 return LookupBlkExpr(E);
Ted Kremenekd72ee902008-07-10 17:19:18 +000090 }
Ted Kremenekd72ee902008-07-10 17:19:18 +000091 }
92}
Ted Kremenek8133a262008-07-08 21:46:56 +000093
Ted Kremenek23ec48c2009-06-18 23:58:37 +000094Environment EnvironmentManager::BindExpr(const Environment& Env, const Stmt* E,
95 SVal V, bool isBlkExpr,
96 bool Invalidate) {
Ted Kremenekd72ee902008-07-10 17:19:18 +000097 assert (E);
98
99 if (V.isUnknown()) {
100 if (Invalidate)
101 return isBlkExpr ? RemoveBlkExpr(Env, E) : RemoveSubExpr(Env, E);
102 else
103 return Env;
104 }
Ted Kremenek8133a262008-07-08 21:46:56 +0000105
Ted Kremenekd72ee902008-07-10 17:19:18 +0000106 return isBlkExpr ? AddBlkExpr(Env, E, V) : AddSubExpr(Env, E, V);
107}
Ted Kremenekdf9cdf82008-08-20 17:08:29 +0000108
Ted Kremenek5216ad72009-02-14 03:16:10 +0000109namespace {
110class VISIBILITY_HIDDEN MarkLiveCallback : public SymbolVisitor {
111 SymbolReaper &SymReaper;
112public:
113 MarkLiveCallback(SymbolReaper &symreaper) : SymReaper(symreaper) {}
114 bool VisitSymbol(SymbolRef sym) { SymReaper.markLive(sym); return true; }
115};
116} // end anonymous namespace
117
Zhongxing Xu9d8d0fc2009-03-12 07:54:17 +0000118// RemoveDeadBindings:
119// - Remove subexpression bindings.
120// - Remove dead block expression bindings.
121// - Keep live block expression bindings:
122// - Mark their reachable symbols live in SymbolReaper,
123// see ScanReachableSymbols.
124// - Mark the region in DRoots if the binding is a loc::MemRegionVal.
125
Ted Kremenekdf9cdf82008-08-20 17:08:29 +0000126Environment
Ted Kremenek9e240492008-10-04 05:50:14 +0000127EnvironmentManager::RemoveDeadBindings(Environment Env, Stmt* Loc,
Ted Kremenek241677a2009-01-21 22:26:05 +0000128 SymbolReaper& SymReaper,
Ted Kremenek5216ad72009-02-14 03:16:10 +0000129 GRStateManager& StateMgr,
Ted Kremenek5dc27462009-03-03 02:51:43 +0000130 const GRState *state,
Ted Kremenek241677a2009-01-21 22:26:05 +0000131 llvm::SmallVectorImpl<const MemRegion*>& DRoots) {
Ted Kremenek9e240492008-10-04 05:50:14 +0000132
Ted Kremenekdf9cdf82008-08-20 17:08:29 +0000133 // Drop bindings for subexpressions.
134 Env = RemoveSubExprBindings(Env);
135
136 // Iterate over the block-expr bindings.
137 for (Environment::beb_iterator I = Env.beb_begin(), E = Env.beb_end();
138 I != E; ++I) {
Ted Kremenek23ec48c2009-06-18 23:58:37 +0000139 const Stmt *BlkExpr = I.getKey();
Ted Kremenekdf9cdf82008-08-20 17:08:29 +0000140
Ted Kremenek241677a2009-01-21 22:26:05 +0000141 if (SymReaper.isLive(Loc, BlkExpr)) {
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000142 SVal X = I.getData();
Ted Kremenekdf9cdf82008-08-20 17:08:29 +0000143
Ted Kremenek9e240492008-10-04 05:50:14 +0000144 // If the block expr's value is a memory region, then mark that region.
Zhongxing Xuce2f9bd2009-06-30 13:00:53 +0000145 if (isa<loc::MemRegionVal>(X)) {
146 const MemRegion* R = cast<loc::MemRegionVal>(X).getRegion();
147 DRoots.push_back(R);
148 // Mark the super region of the RX as live.
149 // e.g.: int x; char *y = (char*) &x; if (*y) ...
150 // 'y' => element region. 'x' is its super region.
151 // We only add one level super region for now.
Zhongxing Xu5ff8e8c2009-07-01 02:12:57 +0000152
153 // FIXME: maybe multiple level of super regions should be added.
Zhongxing Xuce2f9bd2009-06-30 13:00:53 +0000154 if (const SubRegion *SR = dyn_cast<SubRegion>(R)) {
155 DRoots.push_back(SR->getSuperRegion());
156 }
157 }
Ted Kremenek9e240492008-10-04 05:50:14 +0000158
Ted Kremenek5216ad72009-02-14 03:16:10 +0000159 // Mark all symbols in the block expr's value live.
160 MarkLiveCallback cb(SymReaper);
Ted Kremenek47fed902009-06-18 01:33:24 +0000161 state->scanReachableSymbols(X, cb);
Ted Kremenekdf9cdf82008-08-20 17:08:29 +0000162 } else {
163 // The block expr is dead.
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000164 SVal X = I.getData();
Ted Kremenekdf9cdf82008-08-20 17:08:29 +0000165
Zhongxing Xua950fe22008-08-21 23:00:21 +0000166 // Do not misclean LogicalExpr or ConditionalOperator. It is dead at the
167 // beginning of itself, but we need its UndefinedVal to determine its
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000168 // SVal.
Ted Kremenekdf9cdf82008-08-20 17:08:29 +0000169
170 if (X.isUndef() && cast<UndefinedVal>(X).getData())
171 continue;
172
173 Env = RemoveBlkExpr(Env, BlkExpr);
174 }
175 }
176
177 return Env;
178}