blob: 7c303b2ac3ce227c786133b2fe1a5ed8fd904a27 [file] [log] [blame]
Zhongxing Xud19e21b2008-08-29 15:09:12 +00001//== BasicConstraintManager.cpp - Manage basic 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 BasicConstraintManager, a class that tracks simple
11// equality and inequality constraints on symbolic values of GRState.
12//
13//===----------------------------------------------------------------------===//
14
Zhongxing Xu30ad1672008-08-27 14:03:33 +000015#include "clang/Analysis/PathSensitive/ConstraintManager.h"
16#include "clang/Analysis/PathSensitive/GRState.h"
Zhongxing Xu39cfed32008-08-29 14:52:36 +000017#include "clang/Analysis/PathSensitive/GRStateTrait.h"
Zhongxing Xu30ad1672008-08-27 14:03:33 +000018#include "llvm/Support/Compiler.h"
Zhongxing Xu39cfed32008-08-29 14:52:36 +000019#include "llvm/Support/raw_ostream.h"
Zhongxing Xu30ad1672008-08-27 14:03:33 +000020
21using namespace clang;
22
23namespace {
24
Ted Kremenek2dabd432008-12-05 02:27:51 +000025typedef llvm::ImmutableMap<SymbolRef,GRState::IntSetTy> ConstNotEqTy;
26typedef llvm::ImmutableMap<SymbolRef,const llvm::APSInt*> ConstEqTy;
Zhongxing Xu39cfed32008-08-29 14:52:36 +000027
Zhongxing Xu30ad1672008-08-27 14:03:33 +000028// BasicConstraintManager only tracks equality and inequality constraints of
29// constants and integer variables.
30class VISIBILITY_HIDDEN BasicConstraintManager : public ConstraintManager {
Zhongxing Xu30ad1672008-08-27 14:03:33 +000031 GRStateManager& StateMgr;
Zhongxing Xuf0bc50e2008-11-27 06:08:40 +000032 GRState::IntSetTy::Factory ISetFactory;
Zhongxing Xu30ad1672008-08-27 14:03:33 +000033public:
Zhongxing Xuf0bc50e2008-11-27 06:08:40 +000034 BasicConstraintManager(GRStateManager& statemgr)
35 : StateMgr(statemgr), ISetFactory(statemgr.getAllocator()) {}
Zhongxing Xu30ad1672008-08-27 14:03:33 +000036
Zhongxing Xu1c96b242008-10-17 05:57:07 +000037 virtual const GRState* Assume(const GRState* St, SVal Cond,
Zhongxing Xu30ad1672008-08-27 14:03:33 +000038 bool Assumption, bool& isFeasible);
39
Zhongxing Xu1c96b242008-10-17 05:57:07 +000040 const GRState* Assume(const GRState* St, Loc Cond, bool Assumption,
Zhongxing Xu30ad1672008-08-27 14:03:33 +000041 bool& isFeasible);
42
Zhongxing Xu1c96b242008-10-17 05:57:07 +000043 const GRState* AssumeAux(const GRState* St, Loc Cond,bool Assumption,
Zhongxing Xu30ad1672008-08-27 14:03:33 +000044 bool& isFeasible);
45
Zhongxing Xu1c96b242008-10-17 05:57:07 +000046 const GRState* Assume(const GRState* St, NonLoc Cond, bool Assumption,
Zhongxing Xu30ad1672008-08-27 14:03:33 +000047 bool& isFeasible);
48
Zhongxing Xu1c96b242008-10-17 05:57:07 +000049 const GRState* AssumeAux(const GRState* St, NonLoc Cond, bool Assumption,
Zhongxing Xu30ad1672008-08-27 14:03:33 +000050 bool& isFeasible);
51
52 const GRState* AssumeSymInt(const GRState* St, bool Assumption,
53 const SymIntConstraint& C, bool& isFeasible);
54
Ted Kremenek2dabd432008-12-05 02:27:51 +000055 const GRState* AssumeSymNE(const GRState* St, SymbolRef sym,
Zhongxing Xu30ad1672008-08-27 14:03:33 +000056 const llvm::APSInt& V, bool& isFeasible);
57
Ted Kremenek2dabd432008-12-05 02:27:51 +000058 const GRState* AssumeSymEQ(const GRState* St, SymbolRef sym,
Zhongxing Xu30ad1672008-08-27 14:03:33 +000059 const llvm::APSInt& V, bool& isFeasible);
60
Ted Kremenek2dabd432008-12-05 02:27:51 +000061 const GRState* AssumeSymLT(const GRState* St, SymbolRef sym,
Zhongxing Xu30ad1672008-08-27 14:03:33 +000062 const llvm::APSInt& V, bool& isFeasible);
63
Ted Kremenek2dabd432008-12-05 02:27:51 +000064 const GRState* AssumeSymGT(const GRState* St, SymbolRef sym,
Zhongxing Xu30ad1672008-08-27 14:03:33 +000065 const llvm::APSInt& V, bool& isFeasible);
66
Ted Kremenek2dabd432008-12-05 02:27:51 +000067 const GRState* AssumeSymGE(const GRState* St, SymbolRef sym,
Zhongxing Xu30ad1672008-08-27 14:03:33 +000068 const llvm::APSInt& V, bool& isFeasible);
69
Ted Kremenek2dabd432008-12-05 02:27:51 +000070 const GRState* AssumeSymLE(const GRState* St, SymbolRef sym,
Zhongxing Xu30ad1672008-08-27 14:03:33 +000071 const llvm::APSInt& V, bool& isFeasible);
Zhongxing Xu39cfed32008-08-29 14:52:36 +000072
Zhongxing Xue8a964b2008-11-22 13:21:46 +000073 const GRState* AssumeInBound(const GRState* St, SVal Idx, SVal UpperBound,
74 bool Assumption, bool& isFeasible);
75
Ted Kremenek2dabd432008-12-05 02:27:51 +000076 const GRState* AddEQ(const GRState* St, SymbolRef sym, const llvm::APSInt& V);
Zhongxing Xu39cfed32008-08-29 14:52:36 +000077
Ted Kremenek2dabd432008-12-05 02:27:51 +000078 const GRState* AddNE(const GRState* St, SymbolRef sym, const llvm::APSInt& V);
Zhongxing Xu39cfed32008-08-29 14:52:36 +000079
Ted Kremenek2dabd432008-12-05 02:27:51 +000080 const llvm::APSInt* getSymVal(const GRState* St, SymbolRef sym);
81 bool isNotEqual(const GRState* St, SymbolRef sym, const llvm::APSInt& V) const;
82 bool isEqual(const GRState* St, SymbolRef sym, const llvm::APSInt& V) const;
Zhongxing Xu39cfed32008-08-29 14:52:36 +000083
84 const GRState* RemoveDeadBindings(const GRState* St,
85 StoreManager::LiveSymbolsTy& LSymbols,
86 StoreManager::DeadSymbolsTy& DSymbols);
87
88 void print(const GRState* St, std::ostream& Out,
89 const char* nl, const char *sep);
Zhongxing Xue8a964b2008-11-22 13:21:46 +000090
91private:
92 BasicValueFactory& getBasicVals() { return StateMgr.getBasicVals(); }
Zhongxing Xu39cfed32008-08-29 14:52:36 +000093};
Zhongxing Xu30ad1672008-08-27 14:03:33 +000094
95} // end anonymous namespace
96
97ConstraintManager* clang::CreateBasicConstraintManager(GRStateManager& StateMgr)
98{
99 return new BasicConstraintManager(StateMgr);
100}
101
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000102const GRState* BasicConstraintManager::Assume(const GRState* St, SVal Cond,
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000103 bool Assumption, bool& isFeasible) {
104 if (Cond.isUnknown()) {
105 isFeasible = true;
106 return St;
107 }
108
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000109 if (isa<NonLoc>(Cond))
110 return Assume(St, cast<NonLoc>(Cond), Assumption, isFeasible);
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000111 else
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000112 return Assume(St, cast<Loc>(Cond), Assumption, isFeasible);
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000113}
114
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000115const GRState* BasicConstraintManager::Assume(const GRState* St, Loc Cond,
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000116 bool Assumption, bool& isFeasible) {
117 St = AssumeAux(St, Cond, Assumption, isFeasible);
118 // TF->EvalAssume(*this, St, Cond, Assumption, isFeasible)
119 return St;
120}
121
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000122const GRState* BasicConstraintManager::AssumeAux(const GRState* St, Loc Cond,
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000123 bool Assumption, bool& isFeasible) {
124 BasicValueFactory& BasicVals = StateMgr.getBasicVals();
125
126 switch (Cond.getSubKind()) {
127 default:
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000128 assert (false && "'Assume' not implemented for this Loc.");
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000129 return St;
130
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000131 case loc::SymbolValKind:
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000132 if (Assumption)
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000133 return AssumeSymNE(St, cast<loc::SymbolVal>(Cond).getSymbol(),
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000134 BasicVals.getZeroWithPtrWidth(), isFeasible);
135 else
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000136 return AssumeSymEQ(St, cast<loc::SymbolVal>(Cond).getSymbol(),
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000137 BasicVals.getZeroWithPtrWidth(), isFeasible);
138
Ted Kremenekc5234712008-10-17 21:22:20 +0000139 case loc::MemRegionKind: {
140 // FIXME: Should this go into the storemanager?
141
142 const MemRegion* R = cast<loc::MemRegionVal>(Cond).getRegion();
143
144 while (R) {
145 if (const SubRegion* SubR = dyn_cast<SubRegion>(R)) {
146 R = SubR->getSuperRegion();
147 continue;
148 }
149 else if (const SymbolicRegion* SymR = dyn_cast<SymbolicRegion>(R))
150 return AssumeAux(St, loc::SymbolVal(SymR->getSymbol()), Assumption,
151 isFeasible);
152
153 break;
154 }
155
156 // FALL-THROUGH.
157 }
158
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000159 case loc::FuncValKind:
160 case loc::GotoLabelKind:
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000161 isFeasible = Assumption;
162 return St;
163
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000164 case loc::ConcreteIntKind: {
165 bool b = cast<loc::ConcreteInt>(Cond).getValue() != 0;
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000166 isFeasible = b ? Assumption : !Assumption;
167 return St;
168 }
169 } // end switch
170}
171
172const GRState*
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000173BasicConstraintManager::Assume(const GRState* St, NonLoc Cond, bool Assumption,
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000174 bool& isFeasible) {
175 St = AssumeAux(St, Cond, Assumption, isFeasible);
176 // TF->EvalAssume() does nothing now.
177 return St;
178}
179
180const GRState*
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000181BasicConstraintManager::AssumeAux(const GRState* St,NonLoc Cond,
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000182 bool Assumption, bool& isFeasible) {
183 BasicValueFactory& BasicVals = StateMgr.getBasicVals();
184 SymbolManager& SymMgr = StateMgr.getSymbolManager();
185
186 switch (Cond.getSubKind()) {
187 default:
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000188 assert(false && "'Assume' not implemented for this NonLoc");
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000189
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000190 case nonloc::SymbolValKind: {
191 nonloc::SymbolVal& SV = cast<nonloc::SymbolVal>(Cond);
Ted Kremenek2dabd432008-12-05 02:27:51 +0000192 SymbolRef sym = SV.getSymbol();
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000193
194 if (Assumption)
195 return AssumeSymNE(St, sym, BasicVals.getValue(0, SymMgr.getType(sym)),
196 isFeasible);
197 else
198 return AssumeSymEQ(St, sym, BasicVals.getValue(0, SymMgr.getType(sym)),
199 isFeasible);
200 }
201
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000202 case nonloc::SymIntConstraintValKind:
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000203 return
204 AssumeSymInt(St, Assumption,
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000205 cast<nonloc::SymIntConstraintVal>(Cond).getConstraint(),
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000206 isFeasible);
207
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000208 case nonloc::ConcreteIntKind: {
209 bool b = cast<nonloc::ConcreteInt>(Cond).getValue() != 0;
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000210 isFeasible = b ? Assumption : !Assumption;
211 return St;
212 }
213
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000214 case nonloc::LocAsIntegerKind:
215 return AssumeAux(St, cast<nonloc::LocAsInteger>(Cond).getLoc(),
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000216 Assumption, isFeasible);
217 } // end switch
218}
219
220const GRState*
221BasicConstraintManager::AssumeSymInt(const GRState* St, bool Assumption,
222 const SymIntConstraint& C, bool& isFeasible) {
223
224 switch (C.getOpcode()) {
225 default:
226 // No logic yet for other operators.
227 isFeasible = true;
228 return St;
229
230 case BinaryOperator::EQ:
231 if (Assumption)
232 return AssumeSymEQ(St, C.getSymbol(), C.getInt(), isFeasible);
233 else
234 return AssumeSymNE(St, C.getSymbol(), C.getInt(), isFeasible);
235
236 case BinaryOperator::NE:
237 if (Assumption)
238 return AssumeSymNE(St, C.getSymbol(), C.getInt(), isFeasible);
239 else
240 return AssumeSymEQ(St, C.getSymbol(), C.getInt(), isFeasible);
241
Zhongxing Xu94b83122008-09-19 06:07:59 +0000242 case BinaryOperator::GT:
243 if (Assumption)
244 return AssumeSymGT(St, C.getSymbol(), C.getInt(), isFeasible);
245 else
246 return AssumeSymLE(St, C.getSymbol(), C.getInt(), isFeasible);
247
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000248 case BinaryOperator::GE:
249 if (Assumption)
250 return AssumeSymGE(St, C.getSymbol(), C.getInt(), isFeasible);
251 else
252 return AssumeSymLT(St, C.getSymbol(), C.getInt(), isFeasible);
253
Ted Kremenek8c3e7fb2008-09-16 23:24:45 +0000254 case BinaryOperator::LT:
255 if (Assumption)
256 return AssumeSymLT(St, C.getSymbol(), C.getInt(), isFeasible);
257 else
258 return AssumeSymGE(St, C.getSymbol(), C.getInt(), isFeasible);
259
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000260 case BinaryOperator::LE:
261 if (Assumption)
262 return AssumeSymLE(St, C.getSymbol(), C.getInt(), isFeasible);
263 else
264 return AssumeSymGT(St, C.getSymbol(), C.getInt(), isFeasible);
265 } // end switch
266}
267
268const GRState*
Ted Kremenek2dabd432008-12-05 02:27:51 +0000269BasicConstraintManager::AssumeSymNE(const GRState* St, SymbolRef sym,
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000270 const llvm::APSInt& V, bool& isFeasible) {
271 // First, determine if sym == X, where X != V.
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000272 if (const llvm::APSInt* X = getSymVal(St, sym)) {
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000273 isFeasible = (*X != V);
274 return St;
275 }
276
277 // Second, determine if sym != V.
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000278 if (isNotEqual(St, sym, V)) {
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000279 isFeasible = true;
280 return St;
281 }
282
283 // If we reach here, sym is not a constant and we don't know if it is != V.
284 // Make that assumption.
285 isFeasible = true;
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000286 return AddNE(St, sym, V);
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000287}
288
289const GRState*
Ted Kremenek2dabd432008-12-05 02:27:51 +0000290BasicConstraintManager::AssumeSymEQ(const GRState* St, SymbolRef sym,
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000291 const llvm::APSInt& V, bool& isFeasible) {
292 // First, determine if sym == X, where X != V.
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000293 if (const llvm::APSInt* X = getSymVal(St, sym)) {
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000294 isFeasible = *X == V;
295 return St;
296 }
297
298 // Second, determine if sym != V.
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000299 if (isNotEqual(St, sym, V)) {
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000300 isFeasible = false;
301 return St;
302 }
303
304 // If we reach here, sym is not a constant and we don't know if it is == V.
305 // Make that assumption.
306
307 isFeasible = true;
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000308 return AddEQ(St, sym, V);
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000309}
310
311// These logic will be handled in another ConstraintManager.
312const GRState*
Ted Kremenek2dabd432008-12-05 02:27:51 +0000313BasicConstraintManager::AssumeSymLT(const GRState* St, SymbolRef sym,
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000314 const llvm::APSInt& V, bool& isFeasible) {
Ted Kremenek73abd132008-12-03 18:56:12 +0000315
316 // Is 'V' the smallest possible value?
317 if (V == llvm::APSInt::getMinValue(V.getBitWidth(), V.isSigned())) {
318 // sym cannot be any value less than 'V'. This path is infeasible.
319 isFeasible = false;
320 return St;
321 }
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000322
323 // FIXME: For now have assuming x < y be the same as assuming sym != V;
324 return AssumeSymNE(St, sym, V, isFeasible);
325}
326
327const GRState*
Ted Kremenek2dabd432008-12-05 02:27:51 +0000328BasicConstraintManager::AssumeSymGT(const GRState* St, SymbolRef sym,
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000329 const llvm::APSInt& V, bool& isFeasible) {
330
Ted Kremenekd7ff4872008-12-03 19:06:30 +0000331 // Is 'V' the largest possible value?
332 if (V == llvm::APSInt::getMaxValue(V.getBitWidth(), V.isSigned())) {
333 // sym cannot be any value greater than 'V'. This path is infeasible.
334 isFeasible = false;
335 return St;
336 }
337
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000338 // FIXME: For now have assuming x > y be the same as assuming sym != V;
339 return AssumeSymNE(St, sym, V, isFeasible);
340}
341
342const GRState*
Ted Kremenek2dabd432008-12-05 02:27:51 +0000343BasicConstraintManager::AssumeSymGE(const GRState* St, SymbolRef sym,
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000344 const llvm::APSInt& V, bool& isFeasible) {
345
Ted Kremenek8c3e7fb2008-09-16 23:24:45 +0000346 // Reject a path if the value of sym is a constant X and !(X >= V).
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000347 if (const llvm::APSInt* X = getSymVal(St, sym)) {
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000348 isFeasible = *X >= V;
349 return St;
350 }
Ted Kremenekd7ff4872008-12-03 19:06:30 +0000351
352 // Sym is not a constant, but it is worth looking to see if V is the
353 // maximum integer value.
354 if (V == llvm::APSInt::getMaxValue(V.getBitWidth(), V.isSigned())) {
355 // If we know that sym != V, then this condition is infeasible since
356 // there is no other value greater than V.
357 isFeasible = !isNotEqual(St, sym, V);
358
359 // If the path is still feasible then as a consequence we know that
360 // 'sym == V' because we cannot have 'sym > V' (no larger values).
361 // Add this constraint.
362 if (isFeasible)
363 return AddEQ(St, sym, V);
364 }
365 else
366 isFeasible = true;
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000367
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000368 return St;
369}
370
371const GRState*
Ted Kremenek2dabd432008-12-05 02:27:51 +0000372BasicConstraintManager::AssumeSymLE(const GRState* St, SymbolRef sym,
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000373 const llvm::APSInt& V, bool& isFeasible) {
374
Ted Kremenek73abd132008-12-03 18:56:12 +0000375 // Reject a path if the value of sym is a constant X and !(X <= V).
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000376 if (const llvm::APSInt* X = getSymVal(St, sym)) {
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000377 isFeasible = *X <= V;
378 return St;
379 }
Ted Kremenek0a41e5a2008-09-19 18:00:36 +0000380
Ted Kremenek73abd132008-12-03 18:56:12 +0000381 // Sym is not a constant, but it is worth looking to see if V is the
382 // minimum integer value.
383 if (V == llvm::APSInt::getMinValue(V.getBitWidth(), V.isSigned())) {
384 // If we know that sym != V, then this condition is infeasible since
385 // there is no other value less than V.
386 isFeasible = !isNotEqual(St, sym, V);
387
388 // If the path is still feasible then as a consequence we know that
389 // 'sym == V' because we cannot have 'sym < V' (no smaller values).
390 // Add this constraint.
391 if (isFeasible)
392 return AddEQ(St, sym, V);
393 }
394 else
395 isFeasible = true;
396
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000397 return St;
398}
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000399
Zhongxing Xue8a964b2008-11-22 13:21:46 +0000400const GRState*
401BasicConstraintManager::AssumeInBound(const GRState* St, SVal Idx,
402 SVal UpperBound, bool Assumption,
403 bool& isFeasible) {
404 // Only support ConcreteInt for now.
405 if (!(isa<nonloc::ConcreteInt>(Idx) && isa<nonloc::ConcreteInt>(UpperBound))){
406 isFeasible = true;
407 return St;
408 }
409
410 const llvm::APSInt& Zero = getBasicVals().getZeroWithPtrWidth(false);
Sebastian Redle95db4f2008-11-24 19:35:33 +0000411 llvm::APSInt IdxV = cast<nonloc::ConcreteInt>(Idx).getValue();
412 // IdxV might be too narrow.
413 if (IdxV.getBitWidth() < Zero.getBitWidth())
414 IdxV.extend(Zero.getBitWidth());
415 // UBV might be too narrow, too.
416 llvm::APSInt UBV = cast<nonloc::ConcreteInt>(UpperBound).getValue();
417 if (UBV.getBitWidth() < Zero.getBitWidth())
418 UBV.extend(Zero.getBitWidth());
Zhongxing Xue8a964b2008-11-22 13:21:46 +0000419
420 bool InBound = (Zero <= IdxV) && (IdxV < UBV);
421
422 isFeasible = Assumption ? InBound : !InBound;
423
424 return St;
425}
426
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000427static int ConstEqTyIndex = 0;
428static int ConstNotEqTyIndex = 0;
429
430namespace clang {
431 template<>
432 struct GRStateTrait<ConstNotEqTy> : public GRStatePartialTrait<ConstNotEqTy> {
433 static inline void* GDMIndex() { return &ConstNotEqTyIndex; }
434 };
435
436 template<>
437 struct GRStateTrait<ConstEqTy> : public GRStatePartialTrait<ConstEqTy> {
438 static inline void* GDMIndex() { return &ConstEqTyIndex; }
439 };
440}
441
Ted Kremenek2dabd432008-12-05 02:27:51 +0000442const GRState* BasicConstraintManager::AddEQ(const GRState* St, SymbolRef sym,
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000443 const llvm::APSInt& V) {
444 // Create a new state with the old binding replaced.
445 GRStateRef state(St, StateMgr);
446 return state.set<ConstEqTy>(sym, &V);
447}
448
Ted Kremenek2dabd432008-12-05 02:27:51 +0000449const GRState* BasicConstraintManager::AddNE(const GRState* St, SymbolRef sym,
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000450 const llvm::APSInt& V) {
Zhongxing Xuf0bc50e2008-11-27 06:08:40 +0000451
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000452 GRStateRef state(St, StateMgr);
453
454 // First, retrieve the NE-set associated with the given symbol.
455 ConstNotEqTy::data_type* T = state.get<ConstNotEqTy>(sym);
456 GRState::IntSetTy S = T ? *T : ISetFactory.GetEmptySet();
457
458
459 // Now add V to the NE set.
460 S = ISetFactory.Add(S, &V);
461
462 // Create a new state with the old binding replaced.
463 return state.set<ConstNotEqTy>(sym, S);
464}
465
466const llvm::APSInt* BasicConstraintManager::getSymVal(const GRState* St,
Ted Kremenek2dabd432008-12-05 02:27:51 +0000467 SymbolRef sym) {
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000468 const ConstEqTy::data_type* T = St->get<ConstEqTy>(sym);
469 return T ? *T : NULL;
470}
471
Ted Kremenek2dabd432008-12-05 02:27:51 +0000472bool BasicConstraintManager::isNotEqual(const GRState* St, SymbolRef sym,
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000473 const llvm::APSInt& V) const {
474
475 // Retrieve the NE-set associated with the given symbol.
476 const ConstNotEqTy::data_type* T = St->get<ConstNotEqTy>(sym);
477
478 // See if V is present in the NE-set.
479 return T ? T->contains(&V) : false;
480}
481
Ted Kremenek2dabd432008-12-05 02:27:51 +0000482bool BasicConstraintManager::isEqual(const GRState* St, SymbolRef sym,
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000483 const llvm::APSInt& V) const {
484 // Retrieve the EQ-set associated with the given symbol.
485 const ConstEqTy::data_type* T = St->get<ConstEqTy>(sym);
486 // See if V is present in the EQ-set.
487 return T ? **T == V : false;
488}
489
Zhongxing Xu8fd9b352008-11-27 02:39:34 +0000490/// Scan all symbols referenced by the constraints. If the symbol is not alive
491/// as marked in LSymbols, mark it as dead in DSymbols.
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000492const GRState* BasicConstraintManager::RemoveDeadBindings(const GRState* St,
493 StoreManager::LiveSymbolsTy& LSymbols,
494 StoreManager::DeadSymbolsTy& DSymbols) {
495 GRStateRef state(St, StateMgr);
496 ConstEqTy CE = state.get<ConstEqTy>();
497 ConstEqTy::Factory& CEFactory = state.get_context<ConstEqTy>();
498
499 for (ConstEqTy::iterator I = CE.begin(), E = CE.end(); I!=E; ++I) {
Ted Kremenek2dabd432008-12-05 02:27:51 +0000500 SymbolRef sym = I.getKey();
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000501 if (!LSymbols.count(sym)) {
502 DSymbols.insert(sym);
503 CE = CEFactory.Remove(CE, sym);
504 }
505 }
506 state = state.set<ConstEqTy>(CE);
507
508 ConstNotEqTy CNE = state.get<ConstNotEqTy>();
509 ConstNotEqTy::Factory& CNEFactory = state.get_context<ConstNotEqTy>();
510
511 for (ConstNotEqTy::iterator I = CNE.begin(), E = CNE.end(); I != E; ++I) {
Ted Kremenek2dabd432008-12-05 02:27:51 +0000512 SymbolRef sym = I.getKey();
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000513 if (!LSymbols.count(sym)) {
514 DSymbols.insert(sym);
515 CNE = CNEFactory.Remove(CNE, sym);
516 }
517 }
518
519 return state.set<ConstNotEqTy>(CNE);
520}
521
522void BasicConstraintManager::print(const GRState* St, std::ostream& Out,
523 const char* nl, const char *sep) {
524 // Print equality constraints.
525
526 ConstEqTy CE = St->get<ConstEqTy>();
527
528 if (!CE.isEmpty()) {
529 Out << nl << sep << "'==' constraints:";
530
531 for (ConstEqTy::iterator I = CE.begin(), E = CE.end(); I!=E; ++I) {
532 Out << nl << " $" << I.getKey();
533 llvm::raw_os_ostream OS(Out);
534 OS << " : " << *I.getData();
535 }
536 }
537
538 // Print != constraints.
539
540 ConstNotEqTy CNE = St->get<ConstNotEqTy>();
541
542 if (!CNE.isEmpty()) {
543 Out << nl << sep << "'!=' constraints:";
544
545 for (ConstNotEqTy::iterator I = CNE.begin(), EI = CNE.end(); I!=EI; ++I) {
546 Out << nl << " $" << I.getKey() << " : ";
547 bool isFirst = true;
548
549 GRState::IntSetTy::iterator J = I.getData().begin(),
550 EJ = I.getData().end();
551
552 for ( ; J != EJ; ++J) {
553 if (isFirst) isFirst = false;
554 else Out << ", ";
555
Zhongxing Xu7d94e262008-11-10 05:00:06 +0000556 Out << (*J)->getSExtValue(); // Hack: should print to raw_ostream.
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000557 }
558 }
559 }
Daniel Dunbar0e194dd2008-08-30 02:06:22 +0000560}