blob: c875691167a5cc161aa77733ed7308b82d6e1d15 [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"
Ted Kremenek2fb78a72008-12-17 21:50:35 +000018#include "clang/Analysis/PathSensitive/GRTransferFuncs.h"
Zhongxing Xu30ad1672008-08-27 14:03:33 +000019#include "llvm/Support/Compiler.h"
Zhongxing Xu39cfed32008-08-29 14:52:36 +000020#include "llvm/Support/raw_ostream.h"
Zhongxing Xu30ad1672008-08-27 14:03:33 +000021
22using namespace clang;
23
24namespace {
25
Ted Kremenek2dabd432008-12-05 02:27:51 +000026typedef llvm::ImmutableMap<SymbolRef,GRState::IntSetTy> ConstNotEqTy;
27typedef llvm::ImmutableMap<SymbolRef,const llvm::APSInt*> ConstEqTy;
Zhongxing Xu39cfed32008-08-29 14:52:36 +000028
Zhongxing Xu30ad1672008-08-27 14:03:33 +000029// BasicConstraintManager only tracks equality and inequality constraints of
30// constants and integer variables.
31class VISIBILITY_HIDDEN BasicConstraintManager : public ConstraintManager {
Zhongxing Xu30ad1672008-08-27 14:03:33 +000032 GRStateManager& StateMgr;
Zhongxing Xuf0bc50e2008-11-27 06:08:40 +000033 GRState::IntSetTy::Factory ISetFactory;
Zhongxing Xu30ad1672008-08-27 14:03:33 +000034public:
Zhongxing Xuf0bc50e2008-11-27 06:08:40 +000035 BasicConstraintManager(GRStateManager& statemgr)
36 : StateMgr(statemgr), ISetFactory(statemgr.getAllocator()) {}
Zhongxing Xu30ad1672008-08-27 14:03:33 +000037
Zhongxing Xu1c96b242008-10-17 05:57:07 +000038 virtual const GRState* Assume(const GRState* St, SVal Cond,
Zhongxing Xu30ad1672008-08-27 14:03:33 +000039 bool Assumption, bool& isFeasible);
40
Zhongxing Xu1c96b242008-10-17 05:57:07 +000041 const GRState* Assume(const GRState* St, Loc Cond, bool Assumption,
Zhongxing Xu30ad1672008-08-27 14:03:33 +000042 bool& isFeasible);
43
Zhongxing Xu1c96b242008-10-17 05:57:07 +000044 const GRState* AssumeAux(const GRState* St, Loc Cond,bool Assumption,
Zhongxing Xu30ad1672008-08-27 14:03:33 +000045 bool& isFeasible);
46
Zhongxing Xu1c96b242008-10-17 05:57:07 +000047 const GRState* Assume(const GRState* St, NonLoc Cond, bool Assumption,
Zhongxing Xu30ad1672008-08-27 14:03:33 +000048 bool& isFeasible);
49
Zhongxing Xu1c96b242008-10-17 05:57:07 +000050 const GRState* AssumeAux(const GRState* St, NonLoc Cond, bool Assumption,
Zhongxing Xu30ad1672008-08-27 14:03:33 +000051 bool& isFeasible);
52
53 const GRState* AssumeSymInt(const GRState* St, bool Assumption,
54 const SymIntConstraint& C, bool& isFeasible);
55
Ted Kremenek2dabd432008-12-05 02:27:51 +000056 const GRState* AssumeSymNE(const GRState* St, SymbolRef sym,
Zhongxing Xu30ad1672008-08-27 14:03:33 +000057 const llvm::APSInt& V, bool& isFeasible);
58
Ted Kremenek2dabd432008-12-05 02:27:51 +000059 const GRState* AssumeSymEQ(const GRState* St, SymbolRef sym,
Zhongxing Xu30ad1672008-08-27 14:03:33 +000060 const llvm::APSInt& V, bool& isFeasible);
61
Ted Kremenek2dabd432008-12-05 02:27:51 +000062 const GRState* AssumeSymLT(const GRState* St, SymbolRef sym,
Zhongxing Xu30ad1672008-08-27 14:03:33 +000063 const llvm::APSInt& V, bool& isFeasible);
64
Ted Kremenek2dabd432008-12-05 02:27:51 +000065 const GRState* AssumeSymGT(const GRState* St, SymbolRef sym,
Zhongxing Xu30ad1672008-08-27 14:03:33 +000066 const llvm::APSInt& V, bool& isFeasible);
67
Ted Kremenek2dabd432008-12-05 02:27:51 +000068 const GRState* AssumeSymGE(const GRState* St, SymbolRef sym,
Zhongxing Xu30ad1672008-08-27 14:03:33 +000069 const llvm::APSInt& V, bool& isFeasible);
70
Ted Kremenek2dabd432008-12-05 02:27:51 +000071 const GRState* AssumeSymLE(const GRState* St, SymbolRef sym,
Zhongxing Xu30ad1672008-08-27 14:03:33 +000072 const llvm::APSInt& V, bool& isFeasible);
Zhongxing Xu39cfed32008-08-29 14:52:36 +000073
Zhongxing Xue8a964b2008-11-22 13:21:46 +000074 const GRState* AssumeInBound(const GRState* St, SVal Idx, SVal UpperBound,
75 bool Assumption, bool& isFeasible);
76
Ted Kremenek2dabd432008-12-05 02:27:51 +000077 const GRState* AddEQ(const GRState* St, SymbolRef sym, const llvm::APSInt& V);
Zhongxing Xu39cfed32008-08-29 14:52:36 +000078
Ted Kremenek2dabd432008-12-05 02:27:51 +000079 const GRState* AddNE(const GRState* St, SymbolRef sym, const llvm::APSInt& V);
Zhongxing Xu39cfed32008-08-29 14:52:36 +000080
Ted Kremenek2dabd432008-12-05 02:27:51 +000081 const llvm::APSInt* getSymVal(const GRState* St, SymbolRef sym);
82 bool isNotEqual(const GRState* St, SymbolRef sym, const llvm::APSInt& V) const;
83 bool isEqual(const GRState* St, SymbolRef sym, const llvm::APSInt& V) const;
Zhongxing Xu39cfed32008-08-29 14:52:36 +000084
Ted Kremenek241677a2009-01-21 22:26:05 +000085 const GRState* RemoveDeadBindings(const GRState* St, SymbolReaper& SymReaper);
86
Zhongxing Xu39cfed32008-08-29 14:52:36 +000087
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);
Ted Kremenek2fb78a72008-12-17 21:50:35 +0000118
119 if (!isFeasible)
120 return St;
121
122 // EvalAssume is used to call into the GRTransferFunction object to perform
123 // any checker-specific update of the state based on this assumption being
124 // true or false.
125 return StateMgr.getTransferFuncs().EvalAssume(StateMgr, St, Cond, Assumption,
126 isFeasible);
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000127}
128
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000129const GRState* BasicConstraintManager::AssumeAux(const GRState* St, Loc Cond,
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000130 bool Assumption, bool& isFeasible) {
131 BasicValueFactory& BasicVals = StateMgr.getBasicVals();
132
133 switch (Cond.getSubKind()) {
134 default:
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000135 assert (false && "'Assume' not implemented for this Loc.");
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000136 return St;
137
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000138 case loc::SymbolValKind:
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000139 if (Assumption)
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000140 return AssumeSymNE(St, cast<loc::SymbolVal>(Cond).getSymbol(),
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000141 BasicVals.getZeroWithPtrWidth(), isFeasible);
142 else
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000143 return AssumeSymEQ(St, cast<loc::SymbolVal>(Cond).getSymbol(),
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000144 BasicVals.getZeroWithPtrWidth(), isFeasible);
145
Ted Kremenekc5234712008-10-17 21:22:20 +0000146 case loc::MemRegionKind: {
147 // FIXME: Should this go into the storemanager?
148
149 const MemRegion* R = cast<loc::MemRegionVal>(Cond).getRegion();
150
151 while (R) {
152 if (const SubRegion* SubR = dyn_cast<SubRegion>(R)) {
153 R = SubR->getSuperRegion();
154 continue;
155 }
156 else if (const SymbolicRegion* SymR = dyn_cast<SymbolicRegion>(R))
157 return AssumeAux(St, loc::SymbolVal(SymR->getSymbol()), Assumption,
158 isFeasible);
159
160 break;
161 }
162
163 // FALL-THROUGH.
164 }
165
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000166 case loc::FuncValKind:
167 case loc::GotoLabelKind:
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000168 isFeasible = Assumption;
169 return St;
170
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000171 case loc::ConcreteIntKind: {
172 bool b = cast<loc::ConcreteInt>(Cond).getValue() != 0;
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000173 isFeasible = b ? Assumption : !Assumption;
174 return St;
175 }
176 } // end switch
177}
178
179const GRState*
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000180BasicConstraintManager::Assume(const GRState* St, NonLoc Cond, bool Assumption,
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000181 bool& isFeasible) {
182 St = AssumeAux(St, Cond, Assumption, isFeasible);
Ted Kremenek2fb78a72008-12-17 21:50:35 +0000183
184 if (!isFeasible)
185 return St;
186
187 // EvalAssume is used to call into the GRTransferFunction object to perform
188 // any checker-specific update of the state based on this assumption being
189 // true or false.
190 return StateMgr.getTransferFuncs().EvalAssume(StateMgr, St, Cond, Assumption,
191 isFeasible);
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000192}
193
194const GRState*
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000195BasicConstraintManager::AssumeAux(const GRState* St,NonLoc Cond,
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000196 bool Assumption, bool& isFeasible) {
197 BasicValueFactory& BasicVals = StateMgr.getBasicVals();
198 SymbolManager& SymMgr = StateMgr.getSymbolManager();
199
200 switch (Cond.getSubKind()) {
201 default:
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000202 assert(false && "'Assume' not implemented for this NonLoc");
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000203
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000204 case nonloc::SymbolValKind: {
205 nonloc::SymbolVal& SV = cast<nonloc::SymbolVal>(Cond);
Ted Kremenek2dabd432008-12-05 02:27:51 +0000206 SymbolRef sym = SV.getSymbol();
Ted Kremenek9ab6b9c2009-01-22 18:23:34 +0000207 QualType T = SymMgr.getType(sym);
208
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000209 if (Assumption)
Ted Kremenek9ab6b9c2009-01-22 18:23:34 +0000210 return AssumeSymNE(St, sym, BasicVals.getValue(0, T), isFeasible);
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000211 else
Ted Kremenek9ab6b9c2009-01-22 18:23:34 +0000212 return AssumeSymEQ(St, sym, BasicVals.getValue(0, T), isFeasible);
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000213 }
214
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000215 case nonloc::SymIntConstraintValKind:
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000216 return
217 AssumeSymInt(St, Assumption,
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000218 cast<nonloc::SymIntConstraintVal>(Cond).getConstraint(),
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000219 isFeasible);
220
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000221 case nonloc::ConcreteIntKind: {
222 bool b = cast<nonloc::ConcreteInt>(Cond).getValue() != 0;
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000223 isFeasible = b ? Assumption : !Assumption;
224 return St;
225 }
226
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000227 case nonloc::LocAsIntegerKind:
228 return AssumeAux(St, cast<nonloc::LocAsInteger>(Cond).getLoc(),
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000229 Assumption, isFeasible);
230 } // end switch
231}
232
233const GRState*
234BasicConstraintManager::AssumeSymInt(const GRState* St, bool Assumption,
235 const SymIntConstraint& C, bool& isFeasible) {
236
237 switch (C.getOpcode()) {
238 default:
239 // No logic yet for other operators.
240 isFeasible = true;
241 return St;
242
243 case BinaryOperator::EQ:
244 if (Assumption)
245 return AssumeSymEQ(St, C.getSymbol(), C.getInt(), isFeasible);
246 else
247 return AssumeSymNE(St, C.getSymbol(), C.getInt(), isFeasible);
248
249 case BinaryOperator::NE:
250 if (Assumption)
251 return AssumeSymNE(St, C.getSymbol(), C.getInt(), isFeasible);
252 else
253 return AssumeSymEQ(St, C.getSymbol(), C.getInt(), isFeasible);
254
Zhongxing Xu94b83122008-09-19 06:07:59 +0000255 case BinaryOperator::GT:
256 if (Assumption)
257 return AssumeSymGT(St, C.getSymbol(), C.getInt(), isFeasible);
258 else
259 return AssumeSymLE(St, C.getSymbol(), C.getInt(), isFeasible);
260
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000261 case BinaryOperator::GE:
262 if (Assumption)
263 return AssumeSymGE(St, C.getSymbol(), C.getInt(), isFeasible);
264 else
265 return AssumeSymLT(St, C.getSymbol(), C.getInt(), isFeasible);
266
Ted Kremenek8c3e7fb2008-09-16 23:24:45 +0000267 case BinaryOperator::LT:
268 if (Assumption)
269 return AssumeSymLT(St, C.getSymbol(), C.getInt(), isFeasible);
270 else
271 return AssumeSymGE(St, C.getSymbol(), C.getInt(), isFeasible);
272
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000273 case BinaryOperator::LE:
274 if (Assumption)
275 return AssumeSymLE(St, C.getSymbol(), C.getInt(), isFeasible);
276 else
277 return AssumeSymGT(St, C.getSymbol(), C.getInt(), isFeasible);
278 } // end switch
279}
280
281const GRState*
Ted Kremenek2dabd432008-12-05 02:27:51 +0000282BasicConstraintManager::AssumeSymNE(const GRState* St, SymbolRef sym,
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000283 const llvm::APSInt& V, bool& isFeasible) {
284 // First, determine if sym == X, where X != V.
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000285 if (const llvm::APSInt* X = getSymVal(St, sym)) {
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000286 isFeasible = (*X != V);
287 return St;
288 }
289
290 // Second, determine if sym != V.
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000291 if (isNotEqual(St, sym, V)) {
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000292 isFeasible = true;
293 return St;
294 }
295
296 // If we reach here, sym is not a constant and we don't know if it is != V.
297 // Make that assumption.
298 isFeasible = true;
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000299 return AddNE(St, sym, V);
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000300}
301
302const GRState*
Ted Kremenek2dabd432008-12-05 02:27:51 +0000303BasicConstraintManager::AssumeSymEQ(const GRState* St, SymbolRef sym,
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000304 const llvm::APSInt& V, bool& isFeasible) {
305 // First, determine if sym == X, where X != V.
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000306 if (const llvm::APSInt* X = getSymVal(St, sym)) {
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000307 isFeasible = *X == V;
308 return St;
309 }
310
311 // Second, determine if sym != V.
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000312 if (isNotEqual(St, sym, V)) {
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000313 isFeasible = false;
314 return St;
315 }
316
317 // If we reach here, sym is not a constant and we don't know if it is == V.
318 // Make that assumption.
319
320 isFeasible = true;
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000321 return AddEQ(St, sym, V);
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000322}
323
324// These logic will be handled in another ConstraintManager.
325const GRState*
Ted Kremenek2dabd432008-12-05 02:27:51 +0000326BasicConstraintManager::AssumeSymLT(const GRState* St, SymbolRef sym,
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000327 const llvm::APSInt& V, bool& isFeasible) {
Ted Kremenek73abd132008-12-03 18:56:12 +0000328
329 // Is 'V' the smallest possible value?
330 if (V == llvm::APSInt::getMinValue(V.getBitWidth(), V.isSigned())) {
331 // sym cannot be any value less than 'V'. This path is infeasible.
332 isFeasible = false;
333 return St;
334 }
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000335
336 // FIXME: For now have assuming x < y be the same as assuming sym != V;
337 return AssumeSymNE(St, sym, V, isFeasible);
338}
339
340const GRState*
Ted Kremenek2dabd432008-12-05 02:27:51 +0000341BasicConstraintManager::AssumeSymGT(const GRState* St, SymbolRef sym,
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000342 const llvm::APSInt& V, bool& isFeasible) {
343
Ted Kremenekd7ff4872008-12-03 19:06:30 +0000344 // Is 'V' the largest possible value?
345 if (V == llvm::APSInt::getMaxValue(V.getBitWidth(), V.isSigned())) {
346 // sym cannot be any value greater than 'V'. This path is infeasible.
347 isFeasible = false;
348 return St;
349 }
350
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000351 // FIXME: For now have assuming x > y be the same as assuming sym != V;
352 return AssumeSymNE(St, sym, V, isFeasible);
353}
354
355const GRState*
Ted Kremenek2dabd432008-12-05 02:27:51 +0000356BasicConstraintManager::AssumeSymGE(const GRState* St, SymbolRef sym,
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000357 const llvm::APSInt& V, bool& isFeasible) {
358
Ted Kremenek8c3e7fb2008-09-16 23:24:45 +0000359 // Reject a path if the value of sym is a constant X and !(X >= V).
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000360 if (const llvm::APSInt* X = getSymVal(St, sym)) {
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000361 isFeasible = *X >= V;
362 return St;
363 }
Ted Kremenekd7ff4872008-12-03 19:06:30 +0000364
365 // Sym is not a constant, but it is worth looking to see if V is the
366 // maximum integer value.
367 if (V == llvm::APSInt::getMaxValue(V.getBitWidth(), V.isSigned())) {
368 // If we know that sym != V, then this condition is infeasible since
369 // there is no other value greater than V.
370 isFeasible = !isNotEqual(St, sym, V);
371
372 // If the path is still feasible then as a consequence we know that
373 // 'sym == V' because we cannot have 'sym > V' (no larger values).
374 // Add this constraint.
375 if (isFeasible)
376 return AddEQ(St, sym, V);
377 }
378 else
379 isFeasible = true;
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000380
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000381 return St;
382}
383
384const GRState*
Ted Kremenek2dabd432008-12-05 02:27:51 +0000385BasicConstraintManager::AssumeSymLE(const GRState* St, SymbolRef sym,
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000386 const llvm::APSInt& V, bool& isFeasible) {
387
Ted Kremenek73abd132008-12-03 18:56:12 +0000388 // Reject a path if the value of sym is a constant X and !(X <= V).
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000389 if (const llvm::APSInt* X = getSymVal(St, sym)) {
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000390 isFeasible = *X <= V;
391 return St;
392 }
Ted Kremenek0a41e5a2008-09-19 18:00:36 +0000393
Ted Kremenek73abd132008-12-03 18:56:12 +0000394 // Sym is not a constant, but it is worth looking to see if V is the
395 // minimum integer value.
396 if (V == llvm::APSInt::getMinValue(V.getBitWidth(), V.isSigned())) {
397 // If we know that sym != V, then this condition is infeasible since
398 // there is no other value less than V.
399 isFeasible = !isNotEqual(St, sym, V);
400
401 // If the path is still feasible then as a consequence we know that
402 // 'sym == V' because we cannot have 'sym < V' (no smaller values).
403 // Add this constraint.
404 if (isFeasible)
405 return AddEQ(St, sym, V);
406 }
407 else
408 isFeasible = true;
409
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000410 return St;
411}
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000412
Zhongxing Xue8a964b2008-11-22 13:21:46 +0000413const GRState*
414BasicConstraintManager::AssumeInBound(const GRState* St, SVal Idx,
415 SVal UpperBound, bool Assumption,
416 bool& isFeasible) {
417 // Only support ConcreteInt for now.
418 if (!(isa<nonloc::ConcreteInt>(Idx) && isa<nonloc::ConcreteInt>(UpperBound))){
419 isFeasible = true;
420 return St;
421 }
422
423 const llvm::APSInt& Zero = getBasicVals().getZeroWithPtrWidth(false);
Sebastian Redle95db4f2008-11-24 19:35:33 +0000424 llvm::APSInt IdxV = cast<nonloc::ConcreteInt>(Idx).getValue();
425 // IdxV might be too narrow.
426 if (IdxV.getBitWidth() < Zero.getBitWidth())
427 IdxV.extend(Zero.getBitWidth());
428 // UBV might be too narrow, too.
429 llvm::APSInt UBV = cast<nonloc::ConcreteInt>(UpperBound).getValue();
430 if (UBV.getBitWidth() < Zero.getBitWidth())
431 UBV.extend(Zero.getBitWidth());
Zhongxing Xue8a964b2008-11-22 13:21:46 +0000432
433 bool InBound = (Zero <= IdxV) && (IdxV < UBV);
434
435 isFeasible = Assumption ? InBound : !InBound;
436
437 return St;
438}
439
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000440static int ConstEqTyIndex = 0;
441static int ConstNotEqTyIndex = 0;
442
443namespace clang {
444 template<>
445 struct GRStateTrait<ConstNotEqTy> : public GRStatePartialTrait<ConstNotEqTy> {
446 static inline void* GDMIndex() { return &ConstNotEqTyIndex; }
447 };
448
449 template<>
450 struct GRStateTrait<ConstEqTy> : public GRStatePartialTrait<ConstEqTy> {
451 static inline void* GDMIndex() { return &ConstEqTyIndex; }
452 };
453}
454
Ted Kremenek2dabd432008-12-05 02:27:51 +0000455const GRState* BasicConstraintManager::AddEQ(const GRState* St, SymbolRef sym,
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000456 const llvm::APSInt& V) {
457 // Create a new state with the old binding replaced.
458 GRStateRef state(St, StateMgr);
459 return state.set<ConstEqTy>(sym, &V);
460}
461
Ted Kremenek2dabd432008-12-05 02:27:51 +0000462const GRState* BasicConstraintManager::AddNE(const GRState* St, SymbolRef sym,
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000463 const llvm::APSInt& V) {
Zhongxing Xuf0bc50e2008-11-27 06:08:40 +0000464
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000465 GRStateRef state(St, StateMgr);
466
467 // First, retrieve the NE-set associated with the given symbol.
468 ConstNotEqTy::data_type* T = state.get<ConstNotEqTy>(sym);
469 GRState::IntSetTy S = T ? *T : ISetFactory.GetEmptySet();
470
471
472 // Now add V to the NE set.
473 S = ISetFactory.Add(S, &V);
474
475 // Create a new state with the old binding replaced.
476 return state.set<ConstNotEqTy>(sym, S);
477}
478
479const llvm::APSInt* BasicConstraintManager::getSymVal(const GRState* St,
Ted Kremenek2dabd432008-12-05 02:27:51 +0000480 SymbolRef sym) {
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000481 const ConstEqTy::data_type* T = St->get<ConstEqTy>(sym);
482 return T ? *T : NULL;
483}
484
Ted Kremenek2dabd432008-12-05 02:27:51 +0000485bool BasicConstraintManager::isNotEqual(const GRState* St, SymbolRef sym,
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000486 const llvm::APSInt& V) const {
487
488 // Retrieve the NE-set associated with the given symbol.
489 const ConstNotEqTy::data_type* T = St->get<ConstNotEqTy>(sym);
490
491 // See if V is present in the NE-set.
492 return T ? T->contains(&V) : false;
493}
494
Ted Kremenek2dabd432008-12-05 02:27:51 +0000495bool BasicConstraintManager::isEqual(const GRState* St, SymbolRef sym,
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000496 const llvm::APSInt& V) const {
497 // Retrieve the EQ-set associated with the given symbol.
498 const ConstEqTy::data_type* T = St->get<ConstEqTy>(sym);
499 // See if V is present in the EQ-set.
500 return T ? **T == V : false;
501}
502
Zhongxing Xu8fd9b352008-11-27 02:39:34 +0000503/// Scan all symbols referenced by the constraints. If the symbol is not alive
504/// as marked in LSymbols, mark it as dead in DSymbols.
Ted Kremenek241677a2009-01-21 22:26:05 +0000505const GRState*
506BasicConstraintManager::RemoveDeadBindings(const GRState* St,
507 SymbolReaper& SymReaper) {
508
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000509 GRStateRef state(St, StateMgr);
510 ConstEqTy CE = state.get<ConstEqTy>();
511 ConstEqTy::Factory& CEFactory = state.get_context<ConstEqTy>();
512
513 for (ConstEqTy::iterator I = CE.begin(), E = CE.end(); I!=E; ++I) {
Ted Kremenek241677a2009-01-21 22:26:05 +0000514 SymbolRef sym = I.getKey();
515 if (SymReaper.maybeDead(sym)) CE = CEFactory.Remove(CE, sym);
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000516 }
517 state = state.set<ConstEqTy>(CE);
518
519 ConstNotEqTy CNE = state.get<ConstNotEqTy>();
520 ConstNotEqTy::Factory& CNEFactory = state.get_context<ConstNotEqTy>();
521
522 for (ConstNotEqTy::iterator I = CNE.begin(), E = CNE.end(); I != E; ++I) {
Ted Kremenek2dabd432008-12-05 02:27:51 +0000523 SymbolRef sym = I.getKey();
Ted Kremenek241677a2009-01-21 22:26:05 +0000524 if (SymReaper.maybeDead(sym)) CNE = CNEFactory.Remove(CNE, sym);
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000525 }
526
527 return state.set<ConstNotEqTy>(CNE);
528}
529
530void BasicConstraintManager::print(const GRState* St, std::ostream& Out,
531 const char* nl, const char *sep) {
532 // Print equality constraints.
533
534 ConstEqTy CE = St->get<ConstEqTy>();
535
536 if (!CE.isEmpty()) {
537 Out << nl << sep << "'==' constraints:";
538
539 for (ConstEqTy::iterator I = CE.begin(), E = CE.end(); I!=E; ++I) {
540 Out << nl << " $" << I.getKey();
541 llvm::raw_os_ostream OS(Out);
542 OS << " : " << *I.getData();
543 }
544 }
545
546 // Print != constraints.
547
548 ConstNotEqTy CNE = St->get<ConstNotEqTy>();
549
550 if (!CNE.isEmpty()) {
551 Out << nl << sep << "'!=' constraints:";
552
553 for (ConstNotEqTy::iterator I = CNE.begin(), EI = CNE.end(); I!=EI; ++I) {
554 Out << nl << " $" << I.getKey() << " : ";
555 bool isFirst = true;
556
557 GRState::IntSetTy::iterator J = I.getData().begin(),
558 EJ = I.getData().end();
559
560 for ( ; J != EJ; ++J) {
561 if (isFirst) isFirst = false;
562 else Out << ", ";
563
Zhongxing Xu7d94e262008-11-10 05:00:06 +0000564 Out << (*J)->getSExtValue(); // Hack: should print to raw_ostream.
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000565 }
566 }
567 }
Daniel Dunbar0e194dd2008-08-30 02:06:22 +0000568}