blob: 2c3e6dabc66f7a790457f2431908de98d700c493 [file] [log] [blame]
Ted Kremenekaed9b6a2008-02-28 10:21:43 +00001//= ValueState*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//
Gabor Greif843e9342008-03-06 10:40:09 +000010// This file defines SymbolID, ExprBindKey, and ValueState*
Ted Kremenek9153f732008-02-05 07:17:49 +000011//
12//===----------------------------------------------------------------------===//
13
Ted Kremenek0f5f0592008-02-27 06:07:00 +000014#include "clang/Analysis/PathSensitive/ValueState.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 Kremenek862d5bb2008-02-06 00:54:14 +000020bool ValueState::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
29const llvm::APSInt* ValueState::getSymVal(SymbolID sym) const {
Ted Kremeneke8fdc832008-07-07 16:21:19 +000030 ConstEqTy::data_type* T = ConstEq.lookup(sym);
31 return T ? *T : NULL;
Ted Kremenek862d5bb2008-02-06 00:54:14 +000032}
33
Ted Kremenek4323a572008-07-10 22:03:41 +000034const ValueState*
35ValueStateManager::RemoveDeadBindings(const ValueState* St, Stmt* Loc,
Ted Kremenek77d7ef82008-04-24 18:31:42 +000036 const LiveVariables& Liveness,
Ted Kremenekf59bf482008-07-17 18:38:48 +000037 DeadSymbolsTy& DSymbols) {
Ted Kremenekb87d9092008-02-08 19:17:19 +000038
39 // This code essentially performs a "mark-and-sweep" of the VariableBindings.
40 // The roots are any Block-level exprs and Decls that our liveness algorithm
41 // tells us are live. We then see what Decls they may reference, and keep
42 // those around. This code more than likely can be made faster, and the
43 // frequency of which this method is called should be experimented with
Ted Kremenekf59bf482008-07-17 18:38:48 +000044 // for optimum performance.
45 DRoots.clear();
46 StoreManager::LiveSymbolsTy LSymbols;
Ted Kremeneke7d22112008-02-11 19:21:59 +000047
Ted Kremenekaed9b6a2008-02-28 10:21:43 +000048 ValueState NewSt = *St;
Ted Kremenekf59bf482008-07-17 18:38:48 +000049
50 // FIXME: Put this in environment.
51 // Clean up the environment.
Ted Kremeneke7d22112008-02-11 19:21:59 +000052
53 // Drop bindings for subexpressions.
Ted Kremenek8133a262008-07-08 21:46:56 +000054 NewSt.Env = EnvMgr.RemoveSubExprBindings(NewSt.Env);
Ted Kremeneke7d22112008-02-11 19:21:59 +000055
56 // Iterate over the block-expr bindings.
Ted Kremenekaa1c4e52008-02-21 18:02:17 +000057
Ted Kremenekaed9b6a2008-02-28 10:21:43 +000058 for (ValueState::beb_iterator I = St->beb_begin(), E = St->beb_end();
Ted Kremenekaa1c4e52008-02-21 18:02:17 +000059 I!=E ; ++I) {
Ted Kremeneke7d22112008-02-11 19:21:59 +000060 Expr* BlkExpr = I.getKey();
Ted Kremenekb87d9092008-02-08 19:17:19 +000061
Ted Kremeneke7d22112008-02-11 19:21:59 +000062 if (Liveness.isLive(Loc, BlkExpr)) {
Ted Kremenekaa1c4e52008-02-21 18:02:17 +000063 RVal X = I.getData();
Ted Kremenek90e14812008-02-14 23:25:54 +000064
65 if (isa<lval::DeclVal>(X)) {
66 lval::DeclVal LV = cast<lval::DeclVal>(X);
Ted Kremenekf59bf482008-07-17 18:38:48 +000067 DRoots.push_back(LV.getDecl());
Ted Kremenekb87d9092008-02-08 19:17:19 +000068 }
Ted Kremenek90e14812008-02-14 23:25:54 +000069
Ted Kremenekaa1c4e52008-02-21 18:02:17 +000070 for (RVal::symbol_iterator SI = X.symbol_begin(), SE = X.symbol_end();
71 SI != SE; ++SI) {
Ted Kremenekf59bf482008-07-17 18:38:48 +000072 LSymbols.insert(*SI);
Ted Kremenekaa1c4e52008-02-21 18:02:17 +000073 }
Ted Kremenekb87d9092008-02-08 19:17:19 +000074 }
Ted Kremenek05a23782008-02-26 19:05:15 +000075 else {
76 RVal X = I.getData();
77
Ted Kremenek4a4e5242008-02-28 09:25:22 +000078 if (X.isUndef() && cast<UndefinedVal>(X).getData())
Ted Kremenek05a23782008-02-26 19:05:15 +000079 continue;
80
Ted Kremenek8133a262008-07-08 21:46:56 +000081 NewSt.Env = EnvMgr.RemoveBlkExpr(NewSt.Env, BlkExpr);
Ted Kremenek05a23782008-02-26 19:05:15 +000082 }
Ted Kremenekb87d9092008-02-08 19:17:19 +000083 }
Ted Kremenek016f52f2008-02-08 21:10:02 +000084
Ted Kremenekf59bf482008-07-17 18:38:48 +000085 // Clean up the store.
86 DSymbols.clear();
87 NewSt.St = StMgr->RemoveDeadBindings(St->getStore(), Loc, Liveness, DRoots,
88 LSymbols, DSymbols);
Ted Kremenekb87d9092008-02-08 19:17:19 +000089
Ted Kremenekf59bf482008-07-17 18:38:48 +000090 // Remove the dead symbols from the symbol tracker.
Ted Kremenek77d7ef82008-04-24 18:31:42 +000091 for (ValueState::ce_iterator I = St->ce_begin(), E=St->ce_end(); I!=E; ++I) {
92
93 SymbolID sym = I.getKey();
94
Ted Kremenekf59bf482008-07-17 18:38:48 +000095 if (!LSymbols.count(sym)) {
96 DSymbols.insert(sym);
Ted Kremenek77d7ef82008-04-24 18:31:42 +000097 NewSt.ConstEq = CEFactory.Remove(NewSt.ConstEq, sym);
98 }
99 }
100
101 for (ValueState::cne_iterator I = St->cne_begin(), E=St->cne_end(); I!=E;++I){
102
103 SymbolID sym = I.getKey();
104
Ted Kremenekf59bf482008-07-17 18:38:48 +0000105 if (!LSymbols.count(sym)) {
106 DSymbols.insert(sym);
Ted Kremenek77d7ef82008-04-24 18:31:42 +0000107 NewSt.ConstNotEq = CNEFactory.Remove(NewSt.ConstNotEq, sym);
108 }
109 }
Ted Kremenek90e14812008-02-14 23:25:54 +0000110
Ted Kremeneke7d22112008-02-11 19:21:59 +0000111 return getPersistentState(NewSt);
Ted Kremenekb87d9092008-02-08 19:17:19 +0000112}
Ted Kremenek862d5bb2008-02-06 00:54:14 +0000113
Ted Kremenek4323a572008-07-10 22:03:41 +0000114const ValueState* ValueStateManager::SetRVal(const ValueState* St, LVal LV,
115 RVal V) {
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000116
Ted Kremenek4323a572008-07-10 22:03:41 +0000117 Store OldStore = St->getStore();
118 Store NewStore = StMgr->SetRVal(OldStore, LV, V);
Ted Kremenek3271f8d2008-02-07 04:16:04 +0000119
Ted Kremenek4323a572008-07-10 22:03:41 +0000120 if (NewStore == OldStore)
121 return St;
Ted Kremenek692416c2008-02-18 22:57:02 +0000122
Ted Kremenek4323a572008-07-10 22:03:41 +0000123 ValueState NewSt = *St;
124 NewSt.St = NewStore;
125 return getPersistentState(NewSt);
Ted Kremenekf66ea2cd2008-02-04 21:59:22 +0000126}
127
Ted Kremenek4323a572008-07-10 22:03:41 +0000128const ValueState* ValueStateManager::Unbind(const ValueState* St, LVal LV) {
129 Store OldStore = St->getStore();
130 Store NewStore = StMgr->Remove(OldStore, LV);
131
132 if (NewStore == OldStore)
133 return St;
134
135 ValueState NewSt = *St;
136 NewSt.St = NewStore;
137 return getPersistentState(NewSt);
138}
139
140
141const ValueState* ValueStateManager::AddNE(const ValueState* St, SymbolID sym,
142 const llvm::APSInt& V) {
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000143
Ted Kremenek862d5bb2008-02-06 00:54:14 +0000144 // First, retrieve the NE-set associated with the given symbol.
Ted Kremeneke8fdc832008-07-07 16:21:19 +0000145 ValueState::ConstNotEqTy::data_type* T = St->ConstNotEq.lookup(sym);
146 ValueState::IntSetTy S = T ? *T : ISetFactory.GetEmptySet();
Ted Kremenek862d5bb2008-02-06 00:54:14 +0000147
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000148 // Now add V to the NE set.
Ted Kremenek862d5bb2008-02-06 00:54:14 +0000149 S = ISetFactory.Add(S, &V);
150
151 // Create a new state with the old binding replaced.
Ted Kremenekaed9b6a2008-02-28 10:21:43 +0000152 ValueState NewSt = *St;
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000153 NewSt.ConstNotEq = CNEFactory.Add(NewSt.ConstNotEq, sym, S);
Ted Kremenek862d5bb2008-02-06 00:54:14 +0000154
155 // Get the persistent copy.
Ted Kremeneke7d22112008-02-11 19:21:59 +0000156 return getPersistentState(NewSt);
Ted Kremenek862d5bb2008-02-06 00:54:14 +0000157}
158
Ted Kremenek4323a572008-07-10 22:03:41 +0000159const ValueState* ValueStateManager::AddEQ(const ValueState* St, SymbolID sym,
160 const llvm::APSInt& V) {
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000161
Ted Kremenek862d5bb2008-02-06 00:54:14 +0000162 // Create a new state with the old binding replaced.
Ted Kremenekaed9b6a2008-02-28 10:21:43 +0000163 ValueState NewSt = *St;
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000164 NewSt.ConstEq = CEFactory.Add(NewSt.ConstEq, sym, &V);
Ted Kremenek862d5bb2008-02-06 00:54:14 +0000165
166 // Get the persistent copy.
Ted Kremeneke7d22112008-02-11 19:21:59 +0000167 return getPersistentState(NewSt);
Ted Kremenek862d5bb2008-02-06 00:54:14 +0000168}
169
Ted Kremenek4323a572008-07-10 22:03:41 +0000170const ValueState* ValueStateManager::getInitialState() {
Ted Kremenek5a7b3822008-02-26 23:37:01 +0000171
Ted Kremenek8133a262008-07-08 21:46:56 +0000172 ValueState StateImpl(EnvMgr.getInitialEnvironment(),
Ted Kremenek4323a572008-07-10 22:03:41 +0000173 StMgr->getInitialStore(),
Ted Kremenek8133a262008-07-08 21:46:56 +0000174 CNEFactory.GetEmptyMap(),
175 CEFactory.GetEmptyMap());
Ted Kremenek9153f732008-02-05 07:17:49 +0000176
177 return getPersistentState(StateImpl);
178}
179
Ted Kremenek4323a572008-07-10 22:03:41 +0000180const ValueState* ValueStateManager::getPersistentState(ValueState& State) {
Ted Kremenek9153f732008-02-05 07:17:49 +0000181
182 llvm::FoldingSetNodeID ID;
183 State.Profile(ID);
Ted Kremeneke7d22112008-02-11 19:21:59 +0000184 void* InsertPos;
Ted Kremenek9153f732008-02-05 07:17:49 +0000185
Ted Kremenekaed9b6a2008-02-28 10:21:43 +0000186 if (ValueState* I = StateSet.FindNodeOrInsertPos(ID, InsertPos))
Ted Kremenek9153f732008-02-05 07:17:49 +0000187 return I;
188
Ted Kremenekaed9b6a2008-02-28 10:21:43 +0000189 ValueState* I = (ValueState*) Alloc.Allocate<ValueState>();
190 new (I) ValueState(State);
Ted Kremenek9153f732008-02-05 07:17:49 +0000191 StateSet.InsertNode(I, InsertPos);
192 return I;
193}
Ted Kremeneke7d22112008-02-11 19:21:59 +0000194
Ted Kremenek461f9772008-03-11 18:57:24 +0000195void ValueState::printDOT(std::ostream& Out, CheckerStatePrinter* P) const {
196 print(Out, P, "\\l", "\\|");
Ted Kremenek59894f92008-03-04 18:30:35 +0000197}
198
Ted Kremenek461f9772008-03-11 18:57:24 +0000199void ValueState::printStdErr(CheckerStatePrinter* P) const {
200 print(*llvm::cerr, P);
201}
202
203void ValueState::print(std::ostream& Out, CheckerStatePrinter* P,
204 const char* nl, const char* sep) const {
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000205
Ted Kremeneke7d22112008-02-11 19:21:59 +0000206 // Print Variable Bindings
Ted Kremenek59894f92008-03-04 18:30:35 +0000207 Out << "Variables:" << nl;
Ted Kremeneke7d22112008-02-11 19:21:59 +0000208
209 bool isFirst = true;
210
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000211 for (vb_iterator I = vb_begin(), E = vb_end(); I != E; ++I) {
Ted Kremeneke7d22112008-02-11 19:21:59 +0000212
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000213 if (isFirst) isFirst = false;
Ted Kremenek59894f92008-03-04 18:30:35 +0000214 else Out << nl;
Ted Kremeneke7d22112008-02-11 19:21:59 +0000215
216 Out << ' ' << I.getKey()->getName() << " : ";
217 I.getData().print(Out);
218 }
219
220 // Print Subexpression bindings.
221
222 isFirst = true;
223
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000224 for (seb_iterator I = seb_begin(), E = seb_end(); I != E; ++I) {
Ted Kremeneke7d22112008-02-11 19:21:59 +0000225
226 if (isFirst) {
Ted Kremenek59894f92008-03-04 18:30:35 +0000227 Out << nl << nl << "Sub-Expressions:" << nl;
Ted Kremeneke7d22112008-02-11 19:21:59 +0000228 isFirst = false;
229 }
Ted Kremenek59894f92008-03-04 18:30:35 +0000230 else { Out << nl; }
Ted Kremeneke7d22112008-02-11 19:21:59 +0000231
232 Out << " (" << (void*) I.getKey() << ") ";
233 I.getKey()->printPretty(Out);
234 Out << " : ";
235 I.getData().print(Out);
236 }
237
238 // Print block-expression bindings.
239
240 isFirst = true;
241
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000242 for (beb_iterator I = beb_begin(), E = beb_end(); I != E; ++I) {
Ted Kremeneke7d22112008-02-11 19:21:59 +0000243
244 if (isFirst) {
Ted Kremenek59894f92008-03-04 18:30:35 +0000245 Out << nl << nl << "Block-level Expressions:" << nl;
Ted Kremeneke7d22112008-02-11 19:21:59 +0000246 isFirst = false;
247 }
Ted Kremenek59894f92008-03-04 18:30:35 +0000248 else { Out << nl; }
Ted Kremeneke7d22112008-02-11 19:21:59 +0000249
250 Out << " (" << (void*) I.getKey() << ") ";
251 I.getKey()->printPretty(Out);
252 Out << " : ";
253 I.getData().print(Out);
254 }
255
256 // Print equality constraints.
257
Ted Kremenekaed9b6a2008-02-28 10:21:43 +0000258 if (!ConstEq.isEmpty()) {
Ted Kremeneke7d22112008-02-11 19:21:59 +0000259
Ted Kremenek59894f92008-03-04 18:30:35 +0000260 Out << nl << sep << "'==' constraints:";
Ted Kremeneke7d22112008-02-11 19:21:59 +0000261
Ted Kremenekaed9b6a2008-02-28 10:21:43 +0000262 for (ConstEqTy::iterator I = ConstEq.begin(),
263 E = ConstEq.end(); I!=E; ++I) {
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000264
Ted Kremenek59894f92008-03-04 18:30:35 +0000265 Out << nl << " $" << I.getKey()
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000266 << " : " << I.getData()->toString();
267 }
Ted Kremeneke7d22112008-02-11 19:21:59 +0000268 }
Ted Kremeneke7d22112008-02-11 19:21:59 +0000269
270 // Print != constraints.
271
Ted Kremenekaed9b6a2008-02-28 10:21:43 +0000272 if (!ConstNotEq.isEmpty()) {
Ted Kremeneke7d22112008-02-11 19:21:59 +0000273
Ted Kremenek59894f92008-03-04 18:30:35 +0000274 Out << nl << sep << "'!=' constraints:";
Ted Kremeneke7d22112008-02-11 19:21:59 +0000275
Ted Kremenekaed9b6a2008-02-28 10:21:43 +0000276 for (ConstNotEqTy::iterator I = ConstNotEq.begin(),
277 EI = ConstNotEq.end(); I != EI; ++I) {
Ted Kremeneke7d22112008-02-11 19:21:59 +0000278
Ted Kremenek59894f92008-03-04 18:30:35 +0000279 Out << nl << " $" << I.getKey() << " : ";
Ted Kremeneke7d22112008-02-11 19:21:59 +0000280 isFirst = true;
281
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000282 IntSetTy::iterator J = I.getData().begin(), EJ = I.getData().end();
Ted Kremeneke7d22112008-02-11 19:21:59 +0000283
284 for ( ; J != EJ; ++J) {
285 if (isFirst) isFirst = false;
286 else Out << ", ";
287
288 Out << (*J)->toString();
289 }
290 }
291 }
Ted Kremenek461f9772008-03-11 18:57:24 +0000292
293 // Print checker-specific data.
294
295 if (P && CheckerState)
296 P->PrintCheckerState(Out, CheckerState, nl, sep);
Ted Kremeneke7d22112008-02-11 19:21:59 +0000297}
Ted Kremenek729a9a22008-07-17 23:15:45 +0000298
299//===----------------------------------------------------------------------===//
300// "Assume" logic.
301//===----------------------------------------------------------------------===//
302
303const ValueState* ValueStateManager::Assume(const ValueState* St, LVal Cond,
304 bool Assumption, bool& isFeasible) {
305
306 St = AssumeAux(St, Cond, Assumption, isFeasible);
307
308 return isFeasible ? TF->EvalAssume(*this, St, Cond, Assumption, isFeasible)
309 : St;
310}
311
312const ValueState* ValueStateManager::AssumeAux(const ValueState* St, LVal Cond,
313 bool Assumption, bool& isFeasible) {
314
315 switch (Cond.getSubKind()) {
316 default:
317 assert (false && "'Assume' not implemented for this LVal.");
318 return St;
319
320 case lval::SymbolValKind:
321 if (Assumption)
322 return AssumeSymNE(St, cast<lval::SymbolVal>(Cond).getSymbol(),
323 BasicVals.getZeroWithPtrWidth(), isFeasible);
324 else
325 return AssumeSymEQ(St, cast<lval::SymbolVal>(Cond).getSymbol(),
326 BasicVals.getZeroWithPtrWidth(), isFeasible);
327
328
329 case lval::DeclValKind:
330 case lval::FuncValKind:
331 case lval::GotoLabelKind:
332 case lval::StringLiteralValKind:
333 isFeasible = Assumption;
334 return St;
335
336 case lval::FieldOffsetKind:
337 return AssumeAux(St, cast<lval::FieldOffset>(Cond).getBase(),
338 Assumption, isFeasible);
339
340 case lval::ArrayOffsetKind:
341 return AssumeAux(St, cast<lval::ArrayOffset>(Cond).getBase(),
342 Assumption, isFeasible);
343
344 case lval::ConcreteIntKind: {
345 bool b = cast<lval::ConcreteInt>(Cond).getValue() != 0;
346 isFeasible = b ? Assumption : !Assumption;
347 return St;
348 }
349 }
350}
351
352const ValueState* ValueStateManager::Assume(const ValueState* St, NonLVal Cond,
353 bool Assumption, bool& isFeasible) {
354
355 St = AssumeAux(St, Cond, Assumption, isFeasible);
356
357 return isFeasible ? TF->EvalAssume(*this, St, Cond, Assumption, isFeasible)
358 : St;
359}
360
361const ValueState* ValueStateManager::AssumeAux(const ValueState* St, NonLVal Cond,
362 bool Assumption, bool& isFeasible) {
363 switch (Cond.getSubKind()) {
364 default:
365 assert (false && "'Assume' not implemented for this NonLVal.");
366 return St;
367
368
369 case nonlval::SymbolValKind: {
370 nonlval::SymbolVal& SV = cast<nonlval::SymbolVal>(Cond);
371 SymbolID sym = SV.getSymbol();
372
373 if (Assumption)
374 return AssumeSymNE(St, sym, BasicVals.getValue(0, SymMgr.getType(sym)),
375 isFeasible);
376 else
377 return AssumeSymEQ(St, sym, BasicVals.getValue(0, SymMgr.getType(sym)),
378 isFeasible);
379 }
380
381 case nonlval::SymIntConstraintValKind:
382 return
383 AssumeSymInt(St, Assumption,
384 cast<nonlval::SymIntConstraintVal>(Cond).getConstraint(),
385 isFeasible);
386
387 case nonlval::ConcreteIntKind: {
388 bool b = cast<nonlval::ConcreteInt>(Cond).getValue() != 0;
389 isFeasible = b ? Assumption : !Assumption;
390 return St;
391 }
392
393 case nonlval::LValAsIntegerKind: {
394 return AssumeAux(St, cast<nonlval::LValAsInteger>(Cond).getLVal(),
395 Assumption, isFeasible);
396 }
397 }
398}
399
400const ValueState* ValueStateManager::AssumeSymNE(const ValueState* St,
401 SymbolID sym, const llvm::APSInt& V,
402 bool& isFeasible) {
403
404 // First, determine if sym == X, where X != V.
405 if (const llvm::APSInt* X = St->getSymVal(sym)) {
406 isFeasible = *X != V;
407 return St;
408 }
409
410 // Second, determine if sym != V.
411 if (St->isNotEqual(sym, V)) {
412 isFeasible = true;
413 return St;
414 }
415
416 // If we reach here, sym is not a constant and we don't know if it is != V.
417 // Make that assumption.
418
419 isFeasible = true;
420 return AddNE(St, sym, V);
421}
422
423const ValueState* ValueStateManager::AssumeSymEQ(const ValueState* St, SymbolID sym,
424 const llvm::APSInt& V, bool& isFeasible) {
425
426 // First, determine if sym == X, where X != V.
427 if (const llvm::APSInt* X = St->getSymVal(sym)) {
428 isFeasible = *X == V;
429 return St;
430 }
431
432 // Second, determine if sym != V.
433 if (St->isNotEqual(sym, V)) {
434 isFeasible = false;
435 return St;
436 }
437
438 // If we reach here, sym is not a constant and we don't know if it is == V.
439 // Make that assumption.
440
441 isFeasible = true;
442 return AddEQ(St, sym, V);
443}
444
445const ValueState* ValueStateManager::AssumeSymInt(const ValueState* St,
446 bool Assumption,
447 const SymIntConstraint& C,
448 bool& isFeasible) {
449
450 switch (C.getOpcode()) {
451 default:
452 // No logic yet for other operators.
453 isFeasible = true;
454 return St;
455
456 case BinaryOperator::EQ:
457 if (Assumption)
458 return AssumeSymEQ(St, C.getSymbol(), C.getInt(), isFeasible);
459 else
460 return AssumeSymNE(St, C.getSymbol(), C.getInt(), isFeasible);
461
462 case BinaryOperator::NE:
463 if (Assumption)
464 return AssumeSymNE(St, C.getSymbol(), C.getInt(), isFeasible);
465 else
466 return AssumeSymEQ(St, C.getSymbol(), C.getInt(), isFeasible);
467 }
468}