blob: b94580380435cc0a2d13691eef14e2f880993f56 [file] [log] [blame]
Ted Kremenek4adc81e2008-08-13 04:27:00 +00001//= GRState*cpp - Path-Sens. "State" for tracking valuues -----*- C++ -*--=//
Ted Kremenek9153f732008-02-05 07:17:49 +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//
Ted Kremenek4adc81e2008-08-13 04:27:00 +000010// This file defines SymbolID, ExprBindKey, and GRState*
Ted Kremenek9153f732008-02-05 07:17:49 +000011//
12//===----------------------------------------------------------------------===//
13
Ted Kremenek4adc81e2008-08-13 04:27:00 +000014#include "clang/Analysis/PathSensitive/GRState.h"
Ted Kremenek90e14812008-02-14 23:25:54 +000015#include "llvm/ADT/SmallSet.h"
Ted Kremenek729a9a22008-07-17 23:15:45 +000016#include "clang/Analysis/PathSensitive/GRTransferFuncs.h"
Ted Kremenekf66ea2cd2008-02-04 21:59:22 +000017
18using namespace clang;
19
Ted Kremenek4adc81e2008-08-13 04:27:00 +000020bool GRState::isNotEqual(SymbolID sym, const llvm::APSInt& V) const {
Ted Kremenekaa1c4e52008-02-21 18:02:17 +000021
22 // Retrieve the NE-set associated with the given symbol.
Ted Kremeneke8fdc832008-07-07 16:21:19 +000023 const ConstNotEqTy::data_type* T = ConstNotEq.lookup(sym);
Ted Kremenekaa1c4e52008-02-21 18:02:17 +000024
25 // See if V is present in the NE-set.
Ted Kremeneke8fdc832008-07-07 16:21:19 +000026 return T ? T->contains(&V) : false;
Ted Kremenek862d5bb2008-02-06 00:54:14 +000027}
28
Ted Kremenek4adc81e2008-08-13 04:27:00 +000029bool GRState::isEqual(SymbolID sym, const llvm::APSInt& V) const {
Ted Kremenek584def72008-07-22 00:46:16 +000030
31 // Retrieve the EQ-set associated with the given symbol.
32 const ConstEqTy::data_type* T = ConstEq.lookup(sym);
33
34 // See if V is present in the EQ-set.
35 return T ? **T == V : false;
36}
37
Ted Kremenek4adc81e2008-08-13 04:27:00 +000038const llvm::APSInt* GRState::getSymVal(SymbolID sym) const {
Ted Kremeneke8fdc832008-07-07 16:21:19 +000039 ConstEqTy::data_type* T = ConstEq.lookup(sym);
40 return T ? *T : NULL;
Ted Kremenek862d5bb2008-02-06 00:54:14 +000041}
42
Ted Kremenek4adc81e2008-08-13 04:27:00 +000043const GRState*
44GRStateManager::RemoveDeadBindings(const GRState* St, Stmt* Loc,
Ted Kremenek77d7ef82008-04-24 18:31:42 +000045 const LiveVariables& Liveness,
Ted Kremenekf59bf482008-07-17 18:38:48 +000046 DeadSymbolsTy& DSymbols) {
Ted Kremenekb87d9092008-02-08 19:17:19 +000047
48 // This code essentially performs a "mark-and-sweep" of the VariableBindings.
49 // The roots are any Block-level exprs and Decls that our liveness algorithm
50 // tells us are live. We then see what Decls they may reference, and keep
51 // those around. This code more than likely can be made faster, and the
52 // frequency of which this method is called should be experimented with
Ted Kremenekf59bf482008-07-17 18:38:48 +000053 // for optimum performance.
54 DRoots.clear();
55 StoreManager::LiveSymbolsTy LSymbols;
Ted Kremeneke7d22112008-02-11 19:21:59 +000056
Ted Kremenek4adc81e2008-08-13 04:27:00 +000057 GRState NewSt = *St;
Ted Kremenekf59bf482008-07-17 18:38:48 +000058
59 // FIXME: Put this in environment.
60 // Clean up the environment.
Ted Kremeneke7d22112008-02-11 19:21:59 +000061
62 // Drop bindings for subexpressions.
Ted Kremenek8133a262008-07-08 21:46:56 +000063 NewSt.Env = EnvMgr.RemoveSubExprBindings(NewSt.Env);
Ted Kremeneke7d22112008-02-11 19:21:59 +000064
65 // Iterate over the block-expr bindings.
Ted Kremenekaa1c4e52008-02-21 18:02:17 +000066
Ted Kremenek4adc81e2008-08-13 04:27:00 +000067 for (GRState::beb_iterator I = St->beb_begin(), E = St->beb_end();
Ted Kremenekaa1c4e52008-02-21 18:02:17 +000068 I!=E ; ++I) {
Ted Kremeneke7d22112008-02-11 19:21:59 +000069 Expr* BlkExpr = I.getKey();
Ted Kremenekb87d9092008-02-08 19:17:19 +000070
Ted Kremeneke7d22112008-02-11 19:21:59 +000071 if (Liveness.isLive(Loc, BlkExpr)) {
Ted Kremenekaa1c4e52008-02-21 18:02:17 +000072 RVal X = I.getData();
Ted Kremenek90e14812008-02-14 23:25:54 +000073
74 if (isa<lval::DeclVal>(X)) {
75 lval::DeclVal LV = cast<lval::DeclVal>(X);
Ted Kremenekf59bf482008-07-17 18:38:48 +000076 DRoots.push_back(LV.getDecl());
Ted Kremenekb87d9092008-02-08 19:17:19 +000077 }
Ted Kremenek90e14812008-02-14 23:25:54 +000078
Ted Kremenekaa1c4e52008-02-21 18:02:17 +000079 for (RVal::symbol_iterator SI = X.symbol_begin(), SE = X.symbol_end();
80 SI != SE; ++SI) {
Ted Kremenekf59bf482008-07-17 18:38:48 +000081 LSymbols.insert(*SI);
Ted Kremenekaa1c4e52008-02-21 18:02:17 +000082 }
Ted Kremenekb87d9092008-02-08 19:17:19 +000083 }
Ted Kremenek05a23782008-02-26 19:05:15 +000084 else {
85 RVal X = I.getData();
86
Ted Kremenek4a4e5242008-02-28 09:25:22 +000087 if (X.isUndef() && cast<UndefinedVal>(X).getData())
Ted Kremenek05a23782008-02-26 19:05:15 +000088 continue;
89
Ted Kremenek8133a262008-07-08 21:46:56 +000090 NewSt.Env = EnvMgr.RemoveBlkExpr(NewSt.Env, BlkExpr);
Ted Kremenek05a23782008-02-26 19:05:15 +000091 }
Ted Kremenekb87d9092008-02-08 19:17:19 +000092 }
Ted Kremenek016f52f2008-02-08 21:10:02 +000093
Ted Kremenekf59bf482008-07-17 18:38:48 +000094 // Clean up the store.
95 DSymbols.clear();
96 NewSt.St = StMgr->RemoveDeadBindings(St->getStore(), Loc, Liveness, DRoots,
97 LSymbols, DSymbols);
Ted Kremenekb87d9092008-02-08 19:17:19 +000098
Ted Kremenekf59bf482008-07-17 18:38:48 +000099 // Remove the dead symbols from the symbol tracker.
Ted Kremenek4adc81e2008-08-13 04:27:00 +0000100 for (GRState::ce_iterator I = St->ce_begin(), E=St->ce_end(); I!=E; ++I) {
Ted Kremenek77d7ef82008-04-24 18:31:42 +0000101
102 SymbolID sym = I.getKey();
103
Ted Kremenekf59bf482008-07-17 18:38:48 +0000104 if (!LSymbols.count(sym)) {
105 DSymbols.insert(sym);
Ted Kremenek77d7ef82008-04-24 18:31:42 +0000106 NewSt.ConstEq = CEFactory.Remove(NewSt.ConstEq, sym);
107 }
108 }
109
Ted Kremenek4adc81e2008-08-13 04:27:00 +0000110 for (GRState::cne_iterator I = St->cne_begin(), E=St->cne_end(); I!=E;++I){
Ted Kremenek77d7ef82008-04-24 18:31:42 +0000111
112 SymbolID sym = I.getKey();
113
Ted Kremenekf59bf482008-07-17 18:38:48 +0000114 if (!LSymbols.count(sym)) {
115 DSymbols.insert(sym);
Ted Kremenek77d7ef82008-04-24 18:31:42 +0000116 NewSt.ConstNotEq = CNEFactory.Remove(NewSt.ConstNotEq, sym);
117 }
118 }
Ted Kremenek90e14812008-02-14 23:25:54 +0000119
Ted Kremeneke7d22112008-02-11 19:21:59 +0000120 return getPersistentState(NewSt);
Ted Kremenekb87d9092008-02-08 19:17:19 +0000121}
Ted Kremenek862d5bb2008-02-06 00:54:14 +0000122
Ted Kremenek4adc81e2008-08-13 04:27:00 +0000123const GRState* GRStateManager::SetRVal(const GRState* St, LVal LV,
Ted Kremenek4323a572008-07-10 22:03:41 +0000124 RVal V) {
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000125
Ted Kremenek4323a572008-07-10 22:03:41 +0000126 Store OldStore = St->getStore();
127 Store NewStore = StMgr->SetRVal(OldStore, LV, V);
Ted Kremenek3271f8d2008-02-07 04:16:04 +0000128
Ted Kremenek4323a572008-07-10 22:03:41 +0000129 if (NewStore == OldStore)
130 return St;
Ted Kremenek692416c2008-02-18 22:57:02 +0000131
Ted Kremenek4adc81e2008-08-13 04:27:00 +0000132 GRState NewSt = *St;
Ted Kremenek4323a572008-07-10 22:03:41 +0000133 NewSt.St = NewStore;
134 return getPersistentState(NewSt);
Ted Kremenekf66ea2cd2008-02-04 21:59:22 +0000135}
136
Ted Kremenek4adc81e2008-08-13 04:27:00 +0000137const GRState* GRStateManager::Unbind(const GRState* St, LVal LV) {
Ted Kremenek4323a572008-07-10 22:03:41 +0000138 Store OldStore = St->getStore();
139 Store NewStore = StMgr->Remove(OldStore, LV);
140
141 if (NewStore == OldStore)
142 return St;
143
Ted Kremenek4adc81e2008-08-13 04:27:00 +0000144 GRState NewSt = *St;
Ted Kremenek4323a572008-07-10 22:03:41 +0000145 NewSt.St = NewStore;
146 return getPersistentState(NewSt);
147}
148
149
Ted Kremenek4adc81e2008-08-13 04:27:00 +0000150const GRState* GRStateManager::AddNE(const GRState* St, SymbolID sym,
Ted Kremenek4323a572008-07-10 22:03:41 +0000151 const llvm::APSInt& V) {
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000152
Ted Kremenek862d5bb2008-02-06 00:54:14 +0000153 // First, retrieve the NE-set associated with the given symbol.
Ted Kremenek4adc81e2008-08-13 04:27:00 +0000154 GRState::ConstNotEqTy::data_type* T = St->ConstNotEq.lookup(sym);
155 GRState::IntSetTy S = T ? *T : ISetFactory.GetEmptySet();
Ted Kremenek862d5bb2008-02-06 00:54:14 +0000156
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000157 // Now add V to the NE set.
Ted Kremenek862d5bb2008-02-06 00:54:14 +0000158 S = ISetFactory.Add(S, &V);
159
160 // Create a new state with the old binding replaced.
Ted Kremenek4adc81e2008-08-13 04:27:00 +0000161 GRState NewSt = *St;
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000162 NewSt.ConstNotEq = CNEFactory.Add(NewSt.ConstNotEq, sym, S);
Ted Kremenek862d5bb2008-02-06 00:54:14 +0000163
164 // Get the persistent copy.
Ted Kremeneke7d22112008-02-11 19:21:59 +0000165 return getPersistentState(NewSt);
Ted Kremenek862d5bb2008-02-06 00:54:14 +0000166}
167
Ted Kremenek4adc81e2008-08-13 04:27:00 +0000168const GRState* GRStateManager::AddEQ(const GRState* St, SymbolID sym,
Ted Kremenek4323a572008-07-10 22:03:41 +0000169 const llvm::APSInt& V) {
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000170
Ted Kremenek862d5bb2008-02-06 00:54:14 +0000171 // Create a new state with the old binding replaced.
Ted Kremenek4adc81e2008-08-13 04:27:00 +0000172 GRState NewSt = *St;
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000173 NewSt.ConstEq = CEFactory.Add(NewSt.ConstEq, sym, &V);
Ted Kremenek862d5bb2008-02-06 00:54:14 +0000174
175 // Get the persistent copy.
Ted Kremeneke7d22112008-02-11 19:21:59 +0000176 return getPersistentState(NewSt);
Ted Kremenek862d5bb2008-02-06 00:54:14 +0000177}
178
Ted Kremenek4adc81e2008-08-13 04:27:00 +0000179const GRState* GRStateManager::getInitialState() {
Ted Kremenek5a7b3822008-02-26 23:37:01 +0000180
Ted Kremenek72cd17f2008-08-14 21:16:54 +0000181 GRState StateImpl(EnvMgr.getInitialEnvironment(), StMgr->getInitialStore(),
182 GDMFactory.GetEmptyMap(), CNEFactory.GetEmptyMap(),
183 CEFactory.GetEmptyMap());
Ted Kremenek9153f732008-02-05 07:17:49 +0000184
185 return getPersistentState(StateImpl);
186}
187
Ted Kremenek4adc81e2008-08-13 04:27:00 +0000188const GRState* GRStateManager::getPersistentState(GRState& State) {
Ted Kremenek9153f732008-02-05 07:17:49 +0000189
190 llvm::FoldingSetNodeID ID;
191 State.Profile(ID);
Ted Kremeneke7d22112008-02-11 19:21:59 +0000192 void* InsertPos;
Ted Kremenek9153f732008-02-05 07:17:49 +0000193
Ted Kremenek4adc81e2008-08-13 04:27:00 +0000194 if (GRState* I = StateSet.FindNodeOrInsertPos(ID, InsertPos))
Ted Kremenek9153f732008-02-05 07:17:49 +0000195 return I;
196
Ted Kremenek4adc81e2008-08-13 04:27:00 +0000197 GRState* I = (GRState*) Alloc.Allocate<GRState>();
198 new (I) GRState(State);
Ted Kremenek9153f732008-02-05 07:17:49 +0000199 StateSet.InsertNode(I, InsertPos);
200 return I;
201}
Ted Kremeneke7d22112008-02-11 19:21:59 +0000202
Ted Kremenekae6814e2008-08-13 21:24:49 +0000203void GRState::printDOT(std::ostream& Out,
204 Printer** Beg, Printer** End) const {
205 print(Out, Beg, End, "\\l", "\\|");
Ted Kremenek59894f92008-03-04 18:30:35 +0000206}
207
Ted Kremenekae6814e2008-08-13 21:24:49 +0000208void GRState::printStdErr(Printer** Beg, Printer** End) const {
209 print(*llvm::cerr, Beg, End);
Ted Kremenek461f9772008-03-11 18:57:24 +0000210}
211
Ted Kremenekae6814e2008-08-13 21:24:49 +0000212void GRState::print(std::ostream& Out, Printer** Beg, Printer** End,
213 const char* nl, const char* sep) const {
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000214
Ted Kremeneke7d22112008-02-11 19:21:59 +0000215 // Print Variable Bindings
Ted Kremenek59894f92008-03-04 18:30:35 +0000216 Out << "Variables:" << nl;
Ted Kremeneke7d22112008-02-11 19:21:59 +0000217
218 bool isFirst = true;
219
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000220 for (vb_iterator I = vb_begin(), E = vb_end(); I != E; ++I) {
Ted Kremeneke7d22112008-02-11 19:21:59 +0000221
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000222 if (isFirst) isFirst = false;
Ted Kremenek59894f92008-03-04 18:30:35 +0000223 else Out << nl;
Ted Kremeneke7d22112008-02-11 19:21:59 +0000224
225 Out << ' ' << I.getKey()->getName() << " : ";
226 I.getData().print(Out);
227 }
228
229 // Print Subexpression bindings.
230
231 isFirst = true;
232
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000233 for (seb_iterator I = seb_begin(), E = seb_end(); I != E; ++I) {
Ted Kremeneke7d22112008-02-11 19:21:59 +0000234
235 if (isFirst) {
Ted Kremenek59894f92008-03-04 18:30:35 +0000236 Out << nl << nl << "Sub-Expressions:" << nl;
Ted Kremeneke7d22112008-02-11 19:21:59 +0000237 isFirst = false;
238 }
Ted Kremenek59894f92008-03-04 18:30:35 +0000239 else { Out << nl; }
Ted Kremeneke7d22112008-02-11 19:21:59 +0000240
241 Out << " (" << (void*) I.getKey() << ") ";
242 I.getKey()->printPretty(Out);
243 Out << " : ";
244 I.getData().print(Out);
245 }
246
247 // Print block-expression bindings.
248
249 isFirst = true;
250
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000251 for (beb_iterator I = beb_begin(), E = beb_end(); I != E; ++I) {
Ted Kremeneke7d22112008-02-11 19:21:59 +0000252
253 if (isFirst) {
Ted Kremenek59894f92008-03-04 18:30:35 +0000254 Out << nl << nl << "Block-level Expressions:" << nl;
Ted Kremeneke7d22112008-02-11 19:21:59 +0000255 isFirst = false;
256 }
Ted Kremenek59894f92008-03-04 18:30:35 +0000257 else { Out << nl; }
Ted Kremeneke7d22112008-02-11 19:21:59 +0000258
259 Out << " (" << (void*) I.getKey() << ") ";
260 I.getKey()->printPretty(Out);
261 Out << " : ";
262 I.getData().print(Out);
263 }
264
265 // Print equality constraints.
Ted Kremenekae6814e2008-08-13 21:24:49 +0000266 // FIXME: Make just another printer do this.
Ted Kremeneke7d22112008-02-11 19:21:59 +0000267
Ted Kremenekaed9b6a2008-02-28 10:21:43 +0000268 if (!ConstEq.isEmpty()) {
Ted Kremeneke7d22112008-02-11 19:21:59 +0000269
Ted Kremenek59894f92008-03-04 18:30:35 +0000270 Out << nl << sep << "'==' constraints:";
Ted Kremeneke7d22112008-02-11 19:21:59 +0000271
Ted Kremenekaed9b6a2008-02-28 10:21:43 +0000272 for (ConstEqTy::iterator I = ConstEq.begin(),
273 E = ConstEq.end(); I!=E; ++I) {
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000274
Ted Kremenek59894f92008-03-04 18:30:35 +0000275 Out << nl << " $" << I.getKey()
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000276 << " : " << I.getData()->toString();
277 }
Ted Kremeneke7d22112008-02-11 19:21:59 +0000278 }
Ted Kremeneke7d22112008-02-11 19:21:59 +0000279
280 // Print != constraints.
Ted Kremenekae6814e2008-08-13 21:24:49 +0000281 // FIXME: Make just another printer do this.
Ted Kremeneke7d22112008-02-11 19:21:59 +0000282
Ted Kremenekaed9b6a2008-02-28 10:21:43 +0000283 if (!ConstNotEq.isEmpty()) {
Ted Kremeneke7d22112008-02-11 19:21:59 +0000284
Ted Kremenek59894f92008-03-04 18:30:35 +0000285 Out << nl << sep << "'!=' constraints:";
Ted Kremeneke7d22112008-02-11 19:21:59 +0000286
Ted Kremenekaed9b6a2008-02-28 10:21:43 +0000287 for (ConstNotEqTy::iterator I = ConstNotEq.begin(),
288 EI = ConstNotEq.end(); I != EI; ++I) {
Ted Kremeneke7d22112008-02-11 19:21:59 +0000289
Ted Kremenek59894f92008-03-04 18:30:35 +0000290 Out << nl << " $" << I.getKey() << " : ";
Ted Kremeneke7d22112008-02-11 19:21:59 +0000291 isFirst = true;
292
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000293 IntSetTy::iterator J = I.getData().begin(), EJ = I.getData().end();
Ted Kremeneke7d22112008-02-11 19:21:59 +0000294
295 for ( ; J != EJ; ++J) {
296 if (isFirst) isFirst = false;
297 else Out << ", ";
298
299 Out << (*J)->toString();
300 }
301 }
302 }
Ted Kremenek461f9772008-03-11 18:57:24 +0000303
Ted Kremenekae6814e2008-08-13 21:24:49 +0000304 // Print checker-specific data.
305 for ( ; Beg != End ; ++Beg) (*Beg)->Print(Out, this, nl, sep);
Ted Kremeneke7d22112008-02-11 19:21:59 +0000306}
Ted Kremenek729a9a22008-07-17 23:15:45 +0000307
Ted Kremenek72cd17f2008-08-14 21:16:54 +0000308//===----------------------------------------------------------------------===//
309// Generic Data Map.
310//===----------------------------------------------------------------------===//
311
312void* const* GRState::FindGDM(void* K) const {
313 return GDM.lookup(K);
314}
315
316const GRState* GRStateManager::addGDM(const GRState* St, void* Key, void* Data){
317 GRState::GenericDataMap M1 = St->getGDM();
318 GRState::GenericDataMap M2 = GDMFactory.Add(M1, Key, Data);
319
320 if (M1 == M2)
321 return St;
322
323 GRState NewSt = *St;
324 NewSt.GDM = M2;
325 return getPersistentState(NewSt);
326}
Ted Kremenek584def72008-07-22 00:46:16 +0000327
328//===----------------------------------------------------------------------===//
329// Queries.
330//===----------------------------------------------------------------------===//
331
Ted Kremenek4adc81e2008-08-13 04:27:00 +0000332bool GRStateManager::isEqual(const GRState* state, Expr* Ex,
Ted Kremenek584def72008-07-22 00:46:16 +0000333 const llvm::APSInt& Y) {
334 RVal V = GetRVal(state, Ex);
335
336 if (lval::ConcreteInt* X = dyn_cast<lval::ConcreteInt>(&V))
337 return X->getValue() == Y;
338
339 if (nonlval::ConcreteInt* X = dyn_cast<nonlval::ConcreteInt>(&V))
340 return X->getValue() == Y;
341
342 if (nonlval::SymbolVal* X = dyn_cast<nonlval::SymbolVal>(&V))
343 return state->isEqual(X->getSymbol(), Y);
344
345 if (lval::SymbolVal* X = dyn_cast<lval::SymbolVal>(&V))
346 return state->isEqual(X->getSymbol(), Y);
347
348 return false;
349}
350
Ted Kremenek4adc81e2008-08-13 04:27:00 +0000351bool GRStateManager::isEqual(const GRState* state, Expr* Ex,
Ted Kremenek584def72008-07-22 00:46:16 +0000352 uint64_t x) {
353 return isEqual(state, Ex, BasicVals.getValue(x, Ex->getType()));
354}
355
Ted Kremenek729a9a22008-07-17 23:15:45 +0000356//===----------------------------------------------------------------------===//
357// "Assume" logic.
358//===----------------------------------------------------------------------===//
359
Ted Kremenek4adc81e2008-08-13 04:27:00 +0000360const GRState* GRStateManager::Assume(const GRState* St, LVal Cond,
Ted Kremenek729a9a22008-07-17 23:15:45 +0000361 bool Assumption, bool& isFeasible) {
362
363 St = AssumeAux(St, Cond, Assumption, isFeasible);
364
365 return isFeasible ? TF->EvalAssume(*this, St, Cond, Assumption, isFeasible)
366 : St;
367}
368
Ted Kremenek4adc81e2008-08-13 04:27:00 +0000369const GRState* GRStateManager::AssumeAux(const GRState* St, LVal Cond,
Ted Kremenek729a9a22008-07-17 23:15:45 +0000370 bool Assumption, bool& isFeasible) {
371
372 switch (Cond.getSubKind()) {
373 default:
374 assert (false && "'Assume' not implemented for this LVal.");
375 return St;
376
377 case lval::SymbolValKind:
378 if (Assumption)
379 return AssumeSymNE(St, cast<lval::SymbolVal>(Cond).getSymbol(),
380 BasicVals.getZeroWithPtrWidth(), isFeasible);
381 else
382 return AssumeSymEQ(St, cast<lval::SymbolVal>(Cond).getSymbol(),
383 BasicVals.getZeroWithPtrWidth(), isFeasible);
384
385
386 case lval::DeclValKind:
387 case lval::FuncValKind:
388 case lval::GotoLabelKind:
389 case lval::StringLiteralValKind:
390 isFeasible = Assumption;
391 return St;
392
393 case lval::FieldOffsetKind:
394 return AssumeAux(St, cast<lval::FieldOffset>(Cond).getBase(),
395 Assumption, isFeasible);
396
397 case lval::ArrayOffsetKind:
398 return AssumeAux(St, cast<lval::ArrayOffset>(Cond).getBase(),
399 Assumption, isFeasible);
400
401 case lval::ConcreteIntKind: {
402 bool b = cast<lval::ConcreteInt>(Cond).getValue() != 0;
403 isFeasible = b ? Assumption : !Assumption;
404 return St;
405 }
406 }
407}
408
Ted Kremenek4adc81e2008-08-13 04:27:00 +0000409const GRState* GRStateManager::Assume(const GRState* St, NonLVal Cond,
Ted Kremenek729a9a22008-07-17 23:15:45 +0000410 bool Assumption, bool& isFeasible) {
411
412 St = AssumeAux(St, Cond, Assumption, isFeasible);
413
414 return isFeasible ? TF->EvalAssume(*this, St, Cond, Assumption, isFeasible)
415 : St;
416}
417
Ted Kremenek4adc81e2008-08-13 04:27:00 +0000418const GRState* GRStateManager::AssumeAux(const GRState* St, NonLVal Cond,
Ted Kremenek729a9a22008-07-17 23:15:45 +0000419 bool Assumption, bool& isFeasible) {
420 switch (Cond.getSubKind()) {
421 default:
422 assert (false && "'Assume' not implemented for this NonLVal.");
423 return St;
424
425
426 case nonlval::SymbolValKind: {
427 nonlval::SymbolVal& SV = cast<nonlval::SymbolVal>(Cond);
428 SymbolID sym = SV.getSymbol();
429
430 if (Assumption)
431 return AssumeSymNE(St, sym, BasicVals.getValue(0, SymMgr.getType(sym)),
432 isFeasible);
433 else
434 return AssumeSymEQ(St, sym, BasicVals.getValue(0, SymMgr.getType(sym)),
435 isFeasible);
436 }
437
438 case nonlval::SymIntConstraintValKind:
439 return
440 AssumeSymInt(St, Assumption,
441 cast<nonlval::SymIntConstraintVal>(Cond).getConstraint(),
442 isFeasible);
443
444 case nonlval::ConcreteIntKind: {
445 bool b = cast<nonlval::ConcreteInt>(Cond).getValue() != 0;
446 isFeasible = b ? Assumption : !Assumption;
447 return St;
448 }
449
450 case nonlval::LValAsIntegerKind: {
451 return AssumeAux(St, cast<nonlval::LValAsInteger>(Cond).getLVal(),
452 Assumption, isFeasible);
453 }
454 }
455}
456
Ted Kremenek729a9a22008-07-17 23:15:45 +0000457
Ted Kremenek729a9a22008-07-17 23:15:45 +0000458
Ted Kremenek4adc81e2008-08-13 04:27:00 +0000459const GRState* GRStateManager::AssumeSymInt(const GRState* St,
Ted Kremenek729a9a22008-07-17 23:15:45 +0000460 bool Assumption,
461 const SymIntConstraint& C,
462 bool& isFeasible) {
463
464 switch (C.getOpcode()) {
465 default:
466 // No logic yet for other operators.
467 isFeasible = true;
468 return St;
469
470 case BinaryOperator::EQ:
471 if (Assumption)
472 return AssumeSymEQ(St, C.getSymbol(), C.getInt(), isFeasible);
473 else
474 return AssumeSymNE(St, C.getSymbol(), C.getInt(), isFeasible);
475
476 case BinaryOperator::NE:
477 if (Assumption)
478 return AssumeSymNE(St, C.getSymbol(), C.getInt(), isFeasible);
479 else
480 return AssumeSymEQ(St, C.getSymbol(), C.getInt(), isFeasible);
Ted Kremenek2619be02008-08-07 22:30:22 +0000481
482 case BinaryOperator::GE:
483 if (Assumption)
484 return AssumeSymGE(St, C.getSymbol(), C.getInt(), isFeasible);
485 else
486 return AssumeSymLT(St, C.getSymbol(), C.getInt(), isFeasible);
487
488 case BinaryOperator::LE:
489 if (Assumption)
490 return AssumeSymLE(St, C.getSymbol(), C.getInt(), isFeasible);
491 else
492 return AssumeSymGT(St, C.getSymbol(), C.getInt(), isFeasible);
Ted Kremenek729a9a22008-07-17 23:15:45 +0000493 }
494}
Ted Kremenek2619be02008-08-07 22:30:22 +0000495
496//===----------------------------------------------------------------------===//
497// FIXME: This should go into a plug-in constraint engine.
498//===----------------------------------------------------------------------===//
499
Ted Kremenek4adc81e2008-08-13 04:27:00 +0000500const GRState*
501GRStateManager::AssumeSymNE(const GRState* St, SymbolID sym,
Ted Kremenek2619be02008-08-07 22:30:22 +0000502 const llvm::APSInt& V, bool& isFeasible) {
503
504 // First, determine if sym == X, where X != V.
505 if (const llvm::APSInt* X = St->getSymVal(sym)) {
506 isFeasible = *X != V;
507 return St;
508 }
509
510 // Second, determine if sym != V.
511 if (St->isNotEqual(sym, V)) {
512 isFeasible = true;
513 return St;
514 }
515
516 // If we reach here, sym is not a constant and we don't know if it is != V.
517 // Make that assumption.
518
519 isFeasible = true;
520 return AddNE(St, sym, V);
521}
522
Ted Kremenek4adc81e2008-08-13 04:27:00 +0000523const GRState*
524GRStateManager::AssumeSymEQ(const GRState* St, SymbolID sym,
Ted Kremenek2619be02008-08-07 22:30:22 +0000525 const llvm::APSInt& V, bool& isFeasible) {
526
527 // First, determine if sym == X, where X != V.
528 if (const llvm::APSInt* X = St->getSymVal(sym)) {
529 isFeasible = *X == V;
530 return St;
531 }
532
533 // Second, determine if sym != V.
534 if (St->isNotEqual(sym, V)) {
535 isFeasible = false;
536 return St;
537 }
538
539 // If we reach here, sym is not a constant and we don't know if it is == V.
540 // Make that assumption.
541
542 isFeasible = true;
543 return AddEQ(St, sym, V);
544}
545
Ted Kremenek4adc81e2008-08-13 04:27:00 +0000546const GRState*
547GRStateManager::AssumeSymLT(const GRState* St, SymbolID sym,
Ted Kremenek2619be02008-08-07 22:30:22 +0000548 const llvm::APSInt& V, bool& isFeasible) {
549
550 // FIXME: For now have assuming x < y be the same as assuming sym != V;
551 return AssumeSymNE(St, sym, V, isFeasible);
552}
553
Ted Kremenek4adc81e2008-08-13 04:27:00 +0000554const GRState*
555GRStateManager::AssumeSymGT(const GRState* St, SymbolID sym,
Ted Kremenek2619be02008-08-07 22:30:22 +0000556 const llvm::APSInt& V, bool& isFeasible) {
557
558 // FIXME: For now have assuming x > y be the same as assuming sym != V;
559 return AssumeSymNE(St, sym, V, isFeasible);
560}
561
Ted Kremenek4adc81e2008-08-13 04:27:00 +0000562const GRState*
563GRStateManager::AssumeSymGE(const GRState* St, SymbolID sym,
Ted Kremenek2619be02008-08-07 22:30:22 +0000564 const llvm::APSInt& V, bool& isFeasible) {
565
566 // FIXME: Primitive logic for now. Only reject a path if the value of
567 // sym is a constant X and !(X >= V).
568
569 if (const llvm::APSInt* X = St->getSymVal(sym)) {
570 isFeasible = *X >= V;
571 return St;
572 }
573
574 isFeasible = true;
575 return St;
576}
577
Ted Kremenek4adc81e2008-08-13 04:27:00 +0000578const GRState*
579GRStateManager::AssumeSymLE(const GRState* St, SymbolID sym,
Ted Kremenek2619be02008-08-07 22:30:22 +0000580 const llvm::APSInt& V, bool& isFeasible) {
581
582 // FIXME: Primitive logic for now. Only reject a path if the value of
583 // sym is a constant X and !(X <= V).
584
585 if (const llvm::APSInt* X = St->getSymVal(sym)) {
586 isFeasible = *X <= V;
587 return St;
588 }
589
590 isFeasible = true;
591 return St;
592}
593