blob: 06f26ceb1c7fdde8fd7d280339450badf3506aab [file] [log] [blame]
Ted Kremenekdd984832009-02-14 17:08:39 +00001//== RangeConstraintManager.cpp - Manage range constraints.------*- C++ -*--==//
2//
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 defines RangeConstraintManager, a class that tracks simple
11// equality and inequality constraints on symbolic values of GRState.
12//
13//===----------------------------------------------------------------------===//
14
15#include "SimpleConstraintManager.h"
16#include "clang/Analysis/PathSensitive/GRState.h"
17#include "clang/Analysis/PathSensitive/GRStateTrait.h"
18#include "clang/Analysis/PathSensitive/GRTransferFuncs.h"
19#include "clang/Driver/ManagerRegistry.h"
20#include "llvm/Support/Compiler.h"
21#include "llvm/Support/Debug.h"
22#include "llvm/ADT/FoldingSet.h"
23#include "llvm/ADT/ImmutableSet.h"
24#include "llvm/Support/raw_ostream.h"
25
26using namespace clang;
27
28namespace { class VISIBILITY_HIDDEN ConstRange {}; }
29
30static int ConstRangeIndex = 0;
31
32// A Range represents the closed range [from, to]. The caller must
33// guarantee that from <= to. Note that Range is immutable, so as not
34// to subvert RangeSet's immutability.
35class Range : public std::pair<llvm::APSInt, llvm::APSInt> {
36public:
37 Range(const llvm::APSInt &from, const llvm::APSInt &to)
38 : std::pair<llvm::APSInt, llvm::APSInt>(from, to) {
39 assert(from <= to);
40 }
41 bool Includes(const llvm::APSInt &v) const {
42 return first <= v && v <= second;
43 }
44 const llvm::APSInt &From() const {
45 return first;
46 }
47 const llvm::APSInt &To() const {
48 return second;
49 }
50 const llvm::APSInt *HasConcreteValue() const {
51 return From() == To() ? &From() : NULL;
52 }
53
54 void Profile(llvm::FoldingSetNodeID &ID) const {
55 From().Profile(ID);
56 To().Profile(ID);
57 }
58};
59
60struct RangeCmp {
61 bool operator()(const Range &r1, const Range &r2) {
62 if (r1.From() < r2.From()) {
63 assert(!r1.Includes(r2.From()));
64 assert(!r2.Includes(r1.To()));
65 return true;
66 } else if (r1.From() > r2.From()) {
67 assert(!r1.Includes(r2.To()));
68 assert(!r2.Includes(r1.From()));
69 return false;
70 } else
71 assert(!"Ranges should never be equal in the same set");
72 }
73};
74
75typedef llvm::ImmutableSet<Range> PrimRangeSet;
76
77class RangeSet;
78std::ostream &operator<<(std::ostream &os, const RangeSet &r);
79
80
81// A RangeSet contains a set of ranges. If the set is empty, then
82// noValues -> Nothing matches.
83// !noValues -> Everything (in range of the bit representation) matches.
84class RangeSet {
85 PrimRangeSet ranges; // no need to make const, since it is an
86 // ImmutableSet - this allows default operator=
87 // to work.
88 bool noValues; // if true, no value is possible (should never happen)
89
90 static const llvm::APSInt Max(const llvm::APSInt &v) {
91 return llvm::APSInt::getMaxValue(v.getBitWidth(), v.isUnsigned());
92 }
93 static const llvm::APSInt Min(const llvm::APSInt &v) {
94 return llvm::APSInt::getMinValue(v.getBitWidth(), v.isUnsigned());
95 }
96 static const llvm::APSInt One(const llvm::APSInt &v) {
97 return llvm::APSInt(llvm::APInt(v.getBitWidth(), 1), v.isUnsigned());
98 }
99
100public:
101 // Create a RangeSet that allows all possible values.
102 RangeSet(PrimRangeSet::Factory *factory) : ranges(factory->GetEmptySet()),
103 noValues(false) {
104 }
105 // Note that if the empty set is passed, then there are no possible
106 // values. To create a RangeSet that covers all values when the
107 // empty set is passed, use RangeSet(r, false).
108 RangeSet(const PrimRangeSet &r) : ranges(r), noValues(r.isEmpty()) {
109 }
110 // Allow an empty set to be passed meaning "all values" instead of
111 // "no values".
112 RangeSet(const PrimRangeSet &r, bool n) : ranges(r), noValues(n) {
113 assert(!n);
114 }
115 void Profile(llvm::FoldingSetNodeID &ID) const {
116 ranges.Profile(ID);
117 ID.AddBoolean(noValues);
118 }
119
120 const llvm::APSInt *HasConcreteValue() const {
121 if (!ranges.isSingleton())
122 return NULL;
123 return ranges.begin()->HasConcreteValue();
124 }
125
126 bool CouldBeNE(const llvm::APSInt &ne) const {
127 DOUT << "CouldBeNE(" << ne.toString(10) << ") " << *this << std::endl;
128 assert(!noValues);
129 const llvm::APSInt *v = HasConcreteValue();
130 if (v && *v == ne)
131 return false;
132 return true;
133 }
134
135 bool CouldBeEQ(const llvm::APSInt &eq) const {
136 DOUT << "CouldBeEQ(" << eq.toString(10) << ") " << *this << std::endl;
137 assert(!noValues);
138 if (ranges.isEmpty())
139 return true;
140 for (PrimRangeSet::iterator i = ranges.begin() ; i != ranges.end() ; ++i)
141 if (i->Includes(eq))
142 return true;
143 return false;
144 }
145
146 bool CouldBeLT(const llvm::APSInt &lt) const {
147 DOUT << "CouldBeLT(" << lt.toString(10) << ") " << *this << std::endl;
148 assert(!noValues);
149 // FIXME: should test if lt == min -> false here, since that's
150 // impossible to meet.
151 if (ranges.isEmpty())
152 return true;
153 for (PrimRangeSet::iterator i = ranges.begin() ; i != ranges.end() ; ++i)
154 if (i->From() < lt)
155 return true;
156 return false;
157 }
158
159 bool CouldBeLE(const llvm::APSInt &le) const {
160 DOUT << "CouldBeLE(" << le.toString(10) << ") " << *this << std::endl;
161 assert(!noValues);
162 if (ranges.isEmpty())
163 return true;
164 for (PrimRangeSet::iterator i = ranges.begin() ; i != ranges.end() ; ++i)
165 if (i->From() <= le)
166 return true;
167 return false;
168 }
169
170 bool CouldBeGT(const llvm::APSInt &gt) const {
171 DOUT << "CouldBeGT(" << gt.toString(10) << ") " << *this << std::endl;
172 assert(!noValues);
173 // FIXME: should we test if gt == max -> false here, since that's
174 // impossible to meet.
175 if (ranges.isEmpty())
176 return true;
177 for (PrimRangeSet::iterator i = ranges.begin() ; i != ranges.end() ; ++i)
178 if (i->To() > gt)
179 return true;
180 return false;
181 }
182
183 bool CouldBeGE(const llvm::APSInt &ge) const {
184 DOUT << "CouldBeGE(" << ge.toString(10) << ") " << *this << std::endl;
185 assert(!noValues);
186 if (ranges.isEmpty())
187 return true;
188 for (PrimRangeSet::iterator i = ranges.begin() ; i != ranges.end() ; ++i)
189 if (i->To() >= ge)
190 return true;
191 return false;
192 }
193
194 // Make all existing ranges fall within this new range
195 RangeSet Restrict(PrimRangeSet::Factory *factory, const llvm::APSInt &from,
196 const llvm::APSInt &to) const {
197 if (ranges.isEmpty())
198 return factory->Add(ranges, Range(from, to));;
199
200 PrimRangeSet newRanges = factory->GetEmptySet();
201
202 for (PrimRangeSet::iterator i = ranges.begin() ; i != ranges.end() ; ++i) {
203 if (i->Includes(from)) {
204 if (i->Includes(to)) {
205 newRanges = factory->Add(newRanges, Range(from, to));
206 } else {
207 newRanges = factory->Add(newRanges, Range(from, i->To()));
208 }
209 } else if (i->Includes(to)) {
210 newRanges = factory->Add(newRanges, Range(i->From(), to));
211 }
212 }
213 return RangeSet(newRanges);
214 }
215
216 // Create a new RangeSet with the additional constraint that the
217 // range must be == eq. In other words the range becomes [eq,
218 // eq]. Note that this RangeSet must have included eq in the first
219 // place, or we shouldn't be here.
220 RangeSet AddEQ(PrimRangeSet::Factory *factory, const llvm::APSInt &eq) {
221 DOUT << "AddEQ(" << eq.toString(10) << ") " << *this << " -> ";
222 assert(CouldBeEQ(eq));
223 RangeSet r(factory->Add(factory->GetEmptySet(), Range(eq, eq)));
224 DOUT << r << std::endl;
225 return r;
226 }
227
228 RangeSet AddNE(PrimRangeSet::Factory *factory, const llvm::APSInt &ne) {
229 DOUT << "AddNE(" << ne.toString(10) << ") " << *this << " -> ";
230
231 const llvm::APSInt max = Max(ne);
232 const llvm::APSInt min = Min(ne);
233 const llvm::APSInt one = One(ne);
234
235 PrimRangeSet newRanges = factory->GetEmptySet();
236
237 if (ranges.isEmpty()) {
238 if (ne != max)
239 newRanges = factory->Add(newRanges, Range(ne + one, max));
240 if (ne != min)
241 newRanges = factory->Add(newRanges, Range(min, ne - one));
242 RangeSet r(newRanges);
243 DOUT << r << std::endl;
244 return r;
245 }
246
247 for (PrimRangeSet::iterator i = ranges.begin() ; i != ranges.end() ; ++i) {
248 if (i->Includes(ne)) {
249 if (ne != i->From())
250 newRanges = factory->Add(newRanges, Range(i->From(), ne - one));
251 if (ne != i->To())
252 newRanges = factory->Add(newRanges, Range(ne + one, i->To()));
253 } else {
254 newRanges = factory->Add(newRanges, *i);
255 }
256 }
257 RangeSet r(newRanges);
258 DOUT << r << std::endl;
259 return r;
260 }
261
262 RangeSet AddLT(PrimRangeSet::Factory *factory, const llvm::APSInt &lt) {
263 DOUT << "AddLT(" << lt.toString(10) << ") " << *this << " -> ";
264 const llvm::APSInt min = Min(lt);
265 const llvm::APSInt one = One(lt);
266
267 if (ranges.isEmpty()) {
268 PrimRangeSet pr = factory->GetEmptySet();
269 if (lt != min)
270 pr = factory->Add(pr, Range(min, lt - one));
271 RangeSet r(pr, false);
272 DOUT << r << std::endl;
273 return r;
274 }
275
276 PrimRangeSet newRanges = factory->GetEmptySet();
277
278 for (PrimRangeSet::iterator i = ranges.begin() ; i != ranges.end() ; ++i) {
279 if (i->Includes(lt) && i->From() < lt)
280 newRanges = factory->Add(newRanges, Range(i->From(), lt - one));
281 else if (i->To() < lt)
282 newRanges = factory->Add(newRanges, *i);
283 }
284 RangeSet r(newRanges);
285 DOUT << r << std::endl;
286 return r;
287 }
288
289 RangeSet AddLE(PrimRangeSet::Factory *factory, const llvm::APSInt &le) {
290 DOUT << "AddLE(" << le.toString(10) << ") " << *this << " -> ";
291 const llvm::APSInt min = Min(le);
292
293 if (ranges.isEmpty()) {
294 RangeSet r(factory->Add(ranges, Range(min, le)));
295 DOUT << r << std::endl;
296 return r;
297 }
298
299 PrimRangeSet newRanges = factory->GetEmptySet();
300
301 for (PrimRangeSet::iterator i = ranges.begin() ; i != ranges.end() ; ++i) {
302 // Strictly we should test for includes le + 1, but no harm is
303 // done by this formulation
304 if (i->Includes(le))
305 newRanges = factory->Add(newRanges, Range(i->From(), le));
306 else if (i->To() <= le)
307 newRanges = factory->Add(newRanges, *i);
308 }
309 RangeSet r(newRanges);
310 DOUT << r << std::endl;
311 return r;
312 }
313
314 RangeSet AddGT(PrimRangeSet::Factory *factory, const llvm::APSInt &gt) {
315 DOUT << "AddGT(" << gt.toString(10) << ") " << *this << " -> ";
316 const llvm::APSInt max = Max(gt);
317 const llvm::APSInt one = One(gt);
318
319 if (ranges.isEmpty()) {
320 RangeSet r(factory->Add(ranges, Range(gt + one, max)));
321 DOUT << r << std::endl;
322 return r;
323 }
324
325 PrimRangeSet newRanges = factory->GetEmptySet();
326
327 for (PrimRangeSet::iterator i = ranges.begin() ; i != ranges.end() ; ++i) {
328 if (i->Includes(gt) && i->To() > gt)
329 newRanges = factory->Add(newRanges, Range(gt + one, i->To()));
330 else if (i->From() > gt)
331 newRanges = factory->Add(newRanges, *i);
332 }
333 RangeSet r(newRanges);
334 DOUT << r << std::endl;
335 return r;
336 }
337
338 RangeSet AddGE(PrimRangeSet::Factory *factory, const llvm::APSInt &ge) {
339 DOUT << "AddGE(" << ge.toString(10) << ") " << *this << " -> ";
340 const llvm::APSInt max = Max(ge);
341
342 if (ranges.isEmpty()) {
343 RangeSet r(factory->Add(ranges, Range(ge, max)));
344 DOUT << r << std::endl;
345 return r;
346 }
347
348 PrimRangeSet newRanges = factory->GetEmptySet();
349
350 for (PrimRangeSet::iterator i = ranges.begin() ; i != ranges.end() ; ++i) {
351 // Strictly we should test for includes ge - 1, but no harm is
352 // done by this formulation
353 if (i->Includes(ge))
354 newRanges = factory->Add(newRanges, Range(ge, i->To()));
355 else if (i->From() >= ge)
356 newRanges = factory->Add(newRanges, *i);
357 }
358
359 RangeSet r(newRanges);
360 DOUT << r << std::endl;
361 return r;
362 }
363
364 void Print(std::ostream &os) const {
365 os << "{ ";
366 if (noValues) {
367 os << "**no values** }";
368 return;
369 }
370 for (PrimRangeSet::iterator i = ranges.begin() ; i != ranges.end() ; ++i) {
371 if (i != ranges.begin())
372 os << ", ";
373 os << '[' << i->From().toString(10) << ", " << i->To().toString(10)
374 << ']';
375 }
376 os << " }";
377
378}
379 bool operator==(const RangeSet &other) const {
380 return ranges == other.ranges;
381 }
382};
383
384std::ostream &operator<<(std::ostream &os, const RangeSet &r) {
385 r.Print(os);
386 return os;
387}
388
389typedef llvm::ImmutableMap<SymbolRef,RangeSet> ConstRangeTy;
390
391namespace clang {
392template<>
393struct GRStateTrait<ConstRange> : public GRStatePartialTrait<ConstRangeTy> {
394 static inline void* GDMIndex() { return &ConstRangeIndex; }
395};
396}
397
398namespace {
399class VISIBILITY_HIDDEN RangeConstraintManager
400 : public SimpleConstraintManager {
401public:
402 RangeConstraintManager(GRStateManager& statemgr)
403 : SimpleConstraintManager(statemgr) {}
404
405 const GRState* AssumeSymNE(const GRState* St, SymbolRef sym,
406 const llvm::APSInt& V, bool& isFeasible);
407
408 const GRState* AssumeSymEQ(const GRState* St, SymbolRef sym,
409 const llvm::APSInt& V, bool& isFeasible);
410
411 const GRState* AssumeSymLT(const GRState* St, SymbolRef sym,
412 const llvm::APSInt& V, bool& isFeasible);
413
414 const GRState* AssumeSymGT(const GRState* St, SymbolRef sym,
415 const llvm::APSInt& V, bool& isFeasible);
416
417 const GRState* AssumeSymGE(const GRState* St, SymbolRef sym,
418 const llvm::APSInt& V, bool& isFeasible);
419
420 const GRState* AssumeSymLE(const GRState* St, SymbolRef sym,
421 const llvm::APSInt& V, bool& isFeasible);
422
423 const GRState* AddEQ(const GRState* St, SymbolRef sym, const llvm::APSInt& V);
424
425 const GRState* AddNE(const GRState* St, SymbolRef sym, const llvm::APSInt& V);
426
427 const GRState* AddLT(const GRState* St, SymbolRef sym, const llvm::APSInt& V);
428
429 const GRState* AddLE(const GRState* St, SymbolRef sym, const llvm::APSInt& V);
430
431 const GRState* AddGT(const GRState* St, SymbolRef sym, const llvm::APSInt& V);
432
433 const GRState* AddGE(const GRState* St, SymbolRef sym, const llvm::APSInt& V);
434
435 // FIXME: these two are required because they are pure virtual, but
436 // are they useful with ranges? Neither is used in this file.
437 const llvm::APSInt* getSymVal(const GRState* St, SymbolRef sym) const;
438 bool isEqual(const GRState* St, SymbolRef sym, const llvm::APSInt& V) const;
439
440 bool CouldBeEQ(const GRState* St, SymbolRef sym, const llvm::APSInt& V) const;
441 bool CouldBeNE(const GRState* St, SymbolRef sym, const llvm::APSInt& V) const;
442
443 bool CouldBeLT(const GRState* St, SymbolRef sym, const llvm::APSInt& V) const;
444 bool CouldBeLE(const GRState* St, SymbolRef sym, const llvm::APSInt& V) const;
445 bool CouldBeGT(const GRState* St, SymbolRef sym, const llvm::APSInt& V) const;
446 bool CouldBeGE(const GRState* St, SymbolRef sym, const llvm::APSInt& V) const;
447 const GRState* RemoveDeadBindings(const GRState* St, SymbolReaper& SymReaper);
448
449 void print(const GRState* St, std::ostream& Out,
450 const char* nl, const char *sep);
451
452private:
453 PrimRangeSet::Factory factory;
454 BasicValueFactory& getBasicVals() { return StateMgr.getBasicVals(); }
455};
456
457} // end anonymous namespace
458
459ConstraintManager* clang::CreateRangeConstraintManager(GRStateManager& StateMgr)
460{
461 return new RangeConstraintManager(StateMgr);
462}
463
464RegisterConstraintManager X(CreateRangeConstraintManager);
465
466const GRState*
467RangeConstraintManager::AssumeSymNE(const GRState* St, SymbolRef sym,
468 const llvm::APSInt& V, bool& isFeasible) {
469 isFeasible = CouldBeNE(St, sym, V);
470 if (isFeasible)
471 return AddNE(St, sym, V);
472 return St;
473}
474
475const GRState*
476RangeConstraintManager::AssumeSymEQ(const GRState* St, SymbolRef sym,
477 const llvm::APSInt& V, bool& isFeasible) {
478 isFeasible = CouldBeEQ(St, sym, V);
479 if (isFeasible)
480 return AddEQ(St, sym, V);
481 return St;
482}
483
484const GRState*
485RangeConstraintManager::AssumeSymLT(const GRState* St, SymbolRef sym,
486 const llvm::APSInt& V, bool& isFeasible) {
487
488 // Is 'V' the smallest possible value?
489 if (V == llvm::APSInt::getMinValue(V.getBitWidth(), V.isUnsigned())) {
490 // sym cannot be any value less than 'V'. This path is infeasible.
491 isFeasible = false;
492 return St;
493 }
494
495 isFeasible = CouldBeLT(St, sym, V);
496 if (isFeasible)
497 return AddLT(St, sym, V);
498
499 return St;
500}
501
502const GRState*
503RangeConstraintManager::AssumeSymGT(const GRState* St, SymbolRef sym,
504 const llvm::APSInt& V, bool& isFeasible) {
505
506 // Is 'V' the largest possible value?
507 if (V == llvm::APSInt::getMaxValue(V.getBitWidth(), V.isUnsigned())) {
508 // sym cannot be any value greater than 'V'. This path is infeasible.
509 isFeasible = false;
510 return St;
511 }
512
513 isFeasible = CouldBeGT(St, sym, V);
514 if (isFeasible)
515 return AddGT(St, sym, V);
516
517 return St;
518}
519
520const GRState*
521RangeConstraintManager::AssumeSymGE(const GRState* St, SymbolRef sym,
522 const llvm::APSInt& V, bool& isFeasible) {
523
524 isFeasible = CouldBeGE(St, sym, V);
525 if (isFeasible)
526 return AddGE(St, sym, V);
527
528 return St;
529}
530
531const GRState*
532RangeConstraintManager::AssumeSymLE(const GRState* St, SymbolRef sym,
533 const llvm::APSInt& V, bool& isFeasible) {
534
535 isFeasible = CouldBeLT(St, sym, V);
536 if (isFeasible)
537 return AddLE(St, sym, V);
538
539 return St;
540}
541
542const GRState* RangeConstraintManager::AddEQ(const GRState* St, SymbolRef sym,
543 const llvm::APSInt& V) {
544 // Create a new state with the old binding replaced.
545 GRStateRef state(St, StateMgr);
546 RangeSet R(&factory);
547 R = R.AddEQ(&factory, V);
548 return state.set<ConstRange>(sym, R);
549}
550
551const GRState* RangeConstraintManager::AddNE(const GRState* St, SymbolRef sym,
552 const llvm::APSInt& V) {
553 GRStateRef state(St, StateMgr);
554
555 ConstRangeTy::data_type* T = state.get<ConstRange>(sym);
556 RangeSet R(&factory);
557 if (T)
558 R = *T;
559 R = R.AddNE(&factory, V);
560 return state.set<ConstRange>(sym, R);
561}
562
563const GRState* RangeConstraintManager::AddLT(const GRState* St, SymbolRef sym,
564 const llvm::APSInt& V) {
565 GRStateRef state(St, StateMgr);
566
567 ConstRangeTy::data_type* T = state.get<ConstRange>(sym);
568 RangeSet R(&factory);
569 if (T)
570 R = *T;
571 R = R.AddLT(&factory, V);
572 return state.set<ConstRange>(sym, R);
573}
574
575const GRState* RangeConstraintManager::AddLE(const GRState* St, SymbolRef sym,
576 const llvm::APSInt& V) {
577 GRStateRef state(St, StateMgr);
578
579 ConstRangeTy::data_type* T = state.get<ConstRange>(sym);
580 RangeSet R(&factory);
581 if (T)
582 R = *T;
583 R = R.AddLE(&factory, V);
584 return state.set<ConstRange>(sym, R);
585}
586
587const GRState* RangeConstraintManager::AddGT(const GRState* St, SymbolRef sym,
588 const llvm::APSInt& V) {
589 GRStateRef state(St, StateMgr);
590
591 ConstRangeTy::data_type* T = state.get<ConstRange>(sym);
592 RangeSet R(&factory);
593 if (T)
594 R = *T;
595 R = R.AddGT(&factory, V);
596 return state.set<ConstRange>(sym, R);
597}
598
599const GRState* RangeConstraintManager::AddGE(const GRState* St, SymbolRef sym,
600 const llvm::APSInt& V) {
601 GRStateRef state(St, StateMgr);
602
603 ConstRangeTy::data_type* T = state.get<ConstRange>(sym);
604 RangeSet R(&factory);
605 if (T)
606 R = *T;
607 R = R.AddGE(&factory, V);
608 return state.set<ConstRange>(sym, R);
609}
610
611const llvm::APSInt* RangeConstraintManager::getSymVal(const GRState* St,
612 SymbolRef sym) const {
613 const ConstRangeTy::data_type *T = St->get<ConstRange>(sym);
614 return T ? T->HasConcreteValue() : NULL;
615}
616
617bool RangeConstraintManager::CouldBeLT(const GRState* St, SymbolRef sym,
618 const llvm::APSInt& V) const {
619 const ConstRangeTy::data_type *T = St->get<ConstRange>(sym);
620 return T ? T->CouldBeLT(V) : true;
621}
622
623bool RangeConstraintManager::CouldBeLE(const GRState* St, SymbolRef sym,
624 const llvm::APSInt& V) const {
625 const ConstRangeTy::data_type *T = St->get<ConstRange>(sym);
626 return T ? T->CouldBeLE(V) : true;
627}
628
629bool RangeConstraintManager::CouldBeGT(const GRState* St, SymbolRef sym,
630 const llvm::APSInt& V) const {
631 const ConstRangeTy::data_type *T = St->get<ConstRange>(sym);
632 return T ? T->CouldBeGT(V) : true;
633}
634
635bool RangeConstraintManager::CouldBeGE(const GRState* St, SymbolRef sym,
636 const llvm::APSInt& V) const {
637 const ConstRangeTy::data_type *T = St->get<ConstRange>(sym);
638 return T ? T->CouldBeGE(V) : true;
639}
640
641bool RangeConstraintManager::CouldBeNE(const GRState* St, SymbolRef sym,
642 const llvm::APSInt& V) const {
643 const ConstRangeTy::data_type *T = St->get<ConstRange>(sym);
644 return T ? T->CouldBeNE(V) : true;
645}
646
647bool RangeConstraintManager::CouldBeEQ(const GRState* St, SymbolRef sym,
648 const llvm::APSInt& V) const {
649 const ConstRangeTy::data_type *T = St->get<ConstRange>(sym);
650 return T ? T->CouldBeEQ(V) : true;
651}
652
653bool RangeConstraintManager::isEqual(const GRState* St, SymbolRef sym,
654 const llvm::APSInt& V) const {
655 const llvm::APSInt *i = getSymVal(St, sym);
656 return i ? *i == V : false;
657}
658
659/// Scan all symbols referenced by the constraints. If the symbol is not alive
660/// as marked in LSymbols, mark it as dead in DSymbols.
661const GRState*
662RangeConstraintManager::RemoveDeadBindings(const GRState* St,
663 SymbolReaper& SymReaper) {
664 GRStateRef state(St, StateMgr);
665
666 ConstRangeTy CR = state.get<ConstRange>();
667 ConstRangeTy::Factory& CRFactory = state.get_context<ConstRange>();
668
669 for (ConstRangeTy::iterator I = CR.begin(), E = CR.end(); I != E; ++I) {
670 SymbolRef sym = I.getKey();
671 if (SymReaper.maybeDead(sym))
672 CR = CRFactory.Remove(CR, sym);
673 }
674
675 return state.set<ConstRange>(CR);
676}
677
678void RangeConstraintManager::print(const GRState* St, std::ostream& Out,
679 const char* nl, const char *sep) {
680#if 0
681 // Print equality constraints.
682
683 ConstEqTy CE = St->get<ConstEq>();
684
685 if (!CE.isEmpty()) {
686 Out << nl << sep << "'==' constraints:";
687
688 for (ConstEqTy::iterator I = CE.begin(), E = CE.end(); I!=E; ++I) {
689 Out << nl << " $" << I.getKey();
690 llvm::raw_os_ostream OS(Out);
691 OS << " : " << *I.getData();
692 }
693 }
694
695 // Print != constraints.
696
697 ConstNotEqTy CNE = St->get<ConstNotEq>();
698
699 if (!CNE.isEmpty()) {
700 Out << nl << sep << "'!=' constraints:";
701
702 for (ConstNotEqTy::iterator I = CNE.begin(), EI = CNE.end(); I!=EI; ++I) {
703 Out << nl << " $" << I.getKey() << " : ";
704 bool isFirst = true;
705
706 GRState::IntSetTy::iterator J = I.getData().begin(),
707 EJ = I.getData().end();
708
709 for ( ; J != EJ; ++J) {
710 if (isFirst) isFirst = false;
711 else Out << ", ";
712
713 Out << (*J)->getSExtValue(); // Hack: should print to raw_ostream.
714 }
715 }
716 }
717#endif // 0
718
719 Out << nl << "Implement range printing";
720}