blob: 58c4727d51eca548a9b74361b6bde317c3290d9f [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
Ted Kremenek8ee74d52009-01-26 06:04:53 +000024
25namespace { class VISIBILITY_HIDDEN ConstNotEq {}; }
26namespace { class VISIBILITY_HIDDEN ConstEq {}; }
Zhongxing Xu30ad1672008-08-27 14:03:33 +000027
Ted Kremenek2dabd432008-12-05 02:27:51 +000028typedef llvm::ImmutableMap<SymbolRef,GRState::IntSetTy> ConstNotEqTy;
29typedef llvm::ImmutableMap<SymbolRef,const llvm::APSInt*> ConstEqTy;
Ted Kremenek8ee74d52009-01-26 06:04:53 +000030
31static int ConstEqIndex = 0;
32static int ConstNotEqIndex = 0;
Zhongxing Xu39cfed32008-08-29 14:52:36 +000033
Ted Kremenek8ee74d52009-01-26 06:04:53 +000034namespace clang {
35template<>
36struct GRStateTrait<ConstNotEq> : public GRStatePartialTrait<ConstNotEqTy> {
37 static inline void* GDMIndex() { return &ConstNotEqIndex; }
38};
39
40template<>
41struct GRStateTrait<ConstEq> : public GRStatePartialTrait<ConstEqTy> {
42 static inline void* GDMIndex() { return &ConstEqIndex; }
43};
44}
45
46namespace {
Zhongxing Xu30ad1672008-08-27 14:03:33 +000047// BasicConstraintManager only tracks equality and inequality constraints of
48// constants and integer variables.
49class VISIBILITY_HIDDEN BasicConstraintManager : public ConstraintManager {
Zhongxing Xu30ad1672008-08-27 14:03:33 +000050 GRStateManager& StateMgr;
Zhongxing Xuf0bc50e2008-11-27 06:08:40 +000051 GRState::IntSetTy::Factory ISetFactory;
Zhongxing Xu30ad1672008-08-27 14:03:33 +000052public:
Zhongxing Xuf0bc50e2008-11-27 06:08:40 +000053 BasicConstraintManager(GRStateManager& statemgr)
54 : StateMgr(statemgr), ISetFactory(statemgr.getAllocator()) {}
Zhongxing Xu30ad1672008-08-27 14:03:33 +000055
Zhongxing Xu1c96b242008-10-17 05:57:07 +000056 virtual const GRState* Assume(const GRState* St, SVal Cond,
Zhongxing Xu30ad1672008-08-27 14:03:33 +000057 bool Assumption, bool& isFeasible);
58
Zhongxing Xu1c96b242008-10-17 05:57:07 +000059 const GRState* Assume(const GRState* St, Loc Cond, bool Assumption,
Zhongxing Xu30ad1672008-08-27 14:03:33 +000060 bool& isFeasible);
61
Zhongxing Xu1c96b242008-10-17 05:57:07 +000062 const GRState* AssumeAux(const GRState* St, Loc Cond,bool Assumption,
Zhongxing Xu30ad1672008-08-27 14:03:33 +000063 bool& isFeasible);
64
Zhongxing Xu1c96b242008-10-17 05:57:07 +000065 const GRState* Assume(const GRState* St, NonLoc Cond, bool Assumption,
Zhongxing Xu30ad1672008-08-27 14:03:33 +000066 bool& isFeasible);
67
Zhongxing Xu1c96b242008-10-17 05:57:07 +000068 const GRState* AssumeAux(const GRState* St, NonLoc Cond, bool Assumption,
Zhongxing Xu30ad1672008-08-27 14:03:33 +000069 bool& isFeasible);
70
71 const GRState* AssumeSymInt(const GRState* St, bool Assumption,
72 const SymIntConstraint& C, bool& isFeasible);
73
Ted Kremenek2dabd432008-12-05 02:27:51 +000074 const GRState* AssumeSymNE(const GRState* St, SymbolRef sym,
Ted Kremenekb2bf7cd2009-01-28 22:27:59 +000075 const llvm::APSInt& V, bool& isFeasible);
Zhongxing Xu30ad1672008-08-27 14:03:33 +000076
Ted Kremenek2dabd432008-12-05 02:27:51 +000077 const GRState* AssumeSymEQ(const GRState* St, SymbolRef sym,
Zhongxing Xu30ad1672008-08-27 14:03:33 +000078 const llvm::APSInt& V, bool& isFeasible);
79
Ted Kremenek2dabd432008-12-05 02:27:51 +000080 const GRState* AssumeSymLT(const GRState* St, SymbolRef sym,
Zhongxing Xu30ad1672008-08-27 14:03:33 +000081 const llvm::APSInt& V, bool& isFeasible);
82
Ted Kremenek2dabd432008-12-05 02:27:51 +000083 const GRState* AssumeSymGT(const GRState* St, SymbolRef sym,
Zhongxing Xu30ad1672008-08-27 14:03:33 +000084 const llvm::APSInt& V, bool& isFeasible);
85
Ted Kremenek2dabd432008-12-05 02:27:51 +000086 const GRState* AssumeSymGE(const GRState* St, SymbolRef sym,
Zhongxing Xu30ad1672008-08-27 14:03:33 +000087 const llvm::APSInt& V, bool& isFeasible);
88
Ted Kremenek2dabd432008-12-05 02:27:51 +000089 const GRState* AssumeSymLE(const GRState* St, SymbolRef sym,
Zhongxing Xu30ad1672008-08-27 14:03:33 +000090 const llvm::APSInt& V, bool& isFeasible);
Zhongxing Xu39cfed32008-08-29 14:52:36 +000091
Zhongxing Xue8a964b2008-11-22 13:21:46 +000092 const GRState* AssumeInBound(const GRState* St, SVal Idx, SVal UpperBound,
93 bool Assumption, bool& isFeasible);
94
Ted Kremenek2dabd432008-12-05 02:27:51 +000095 const GRState* AddEQ(const GRState* St, SymbolRef sym, const llvm::APSInt& V);
Zhongxing Xu39cfed32008-08-29 14:52:36 +000096
Ted Kremenek2dabd432008-12-05 02:27:51 +000097 const GRState* AddNE(const GRState* St, SymbolRef sym, const llvm::APSInt& V);
Zhongxing Xu39cfed32008-08-29 14:52:36 +000098
Ted Kremenek2dabd432008-12-05 02:27:51 +000099 const llvm::APSInt* getSymVal(const GRState* St, SymbolRef sym);
100 bool isNotEqual(const GRState* St, SymbolRef sym, const llvm::APSInt& V) const;
101 bool isEqual(const GRState* St, SymbolRef sym, const llvm::APSInt& V) const;
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000102
Ted Kremenek241677a2009-01-21 22:26:05 +0000103 const GRState* RemoveDeadBindings(const GRState* St, SymbolReaper& SymReaper);
104
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000105
106 void print(const GRState* St, std::ostream& Out,
107 const char* nl, const char *sep);
Zhongxing Xue8a964b2008-11-22 13:21:46 +0000108
109private:
110 BasicValueFactory& getBasicVals() { return StateMgr.getBasicVals(); }
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000111};
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000112
113} // end anonymous namespace
114
115ConstraintManager* clang::CreateBasicConstraintManager(GRStateManager& StateMgr)
116{
117 return new BasicConstraintManager(StateMgr);
118}
119
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000120const GRState* BasicConstraintManager::Assume(const GRState* St, SVal Cond,
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000121 bool Assumption, bool& isFeasible) {
122 if (Cond.isUnknown()) {
123 isFeasible = true;
124 return St;
125 }
126
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000127 if (isa<NonLoc>(Cond))
128 return Assume(St, cast<NonLoc>(Cond), Assumption, isFeasible);
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000129 else
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000130 return Assume(St, cast<Loc>(Cond), Assumption, isFeasible);
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000131}
132
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000133const GRState* BasicConstraintManager::Assume(const GRState* St, Loc Cond,
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000134 bool Assumption, bool& isFeasible) {
135 St = AssumeAux(St, Cond, Assumption, isFeasible);
Ted Kremenek2fb78a72008-12-17 21:50:35 +0000136
137 if (!isFeasible)
138 return St;
139
140 // EvalAssume is used to call into the GRTransferFunction object to perform
141 // any checker-specific update of the state based on this assumption being
142 // true or false.
143 return StateMgr.getTransferFuncs().EvalAssume(StateMgr, St, Cond, Assumption,
144 isFeasible);
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000145}
146
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000147const GRState* BasicConstraintManager::AssumeAux(const GRState* St, Loc Cond,
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000148 bool Assumption, bool& isFeasible) {
149 BasicValueFactory& BasicVals = StateMgr.getBasicVals();
150
151 switch (Cond.getSubKind()) {
152 default:
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000153 assert (false && "'Assume' not implemented for this Loc.");
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000154 return St;
155
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000156 case loc::SymbolValKind:
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000157 if (Assumption)
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000158 return AssumeSymNE(St, cast<loc::SymbolVal>(Cond).getSymbol(),
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000159 BasicVals.getZeroWithPtrWidth(), isFeasible);
160 else
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000161 return AssumeSymEQ(St, cast<loc::SymbolVal>(Cond).getSymbol(),
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000162 BasicVals.getZeroWithPtrWidth(), isFeasible);
163
Ted Kremenekc5234712008-10-17 21:22:20 +0000164 case loc::MemRegionKind: {
165 // FIXME: Should this go into the storemanager?
166
167 const MemRegion* R = cast<loc::MemRegionVal>(Cond).getRegion();
Zhongxing Xu026c6632009-02-05 06:57:29 +0000168 const SubRegion* SubR = dyn_cast<SubRegion>(R);
169
170 while (SubR) {
171 // FIXME: now we only find the first symbolic region.
172 if (const SymbolicRegion* SymR = dyn_cast<SymbolicRegion>(SubR))
Ted Kremenekc5234712008-10-17 21:22:20 +0000173 return AssumeAux(St, loc::SymbolVal(SymR->getSymbol()), Assumption,
174 isFeasible);
Zhongxing Xu026c6632009-02-05 06:57:29 +0000175 SubR = dyn_cast<SubRegion>(SubR->getSuperRegion());
Ted Kremenekc5234712008-10-17 21:22:20 +0000176 }
177
178 // FALL-THROUGH.
179 }
180
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000181 case loc::FuncValKind:
182 case loc::GotoLabelKind:
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000183 isFeasible = Assumption;
184 return St;
185
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000186 case loc::ConcreteIntKind: {
187 bool b = cast<loc::ConcreteInt>(Cond).getValue() != 0;
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000188 isFeasible = b ? Assumption : !Assumption;
189 return St;
190 }
191 } // end switch
192}
193
194const GRState*
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000195BasicConstraintManager::Assume(const GRState* St, NonLoc Cond, bool Assumption,
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000196 bool& isFeasible) {
197 St = AssumeAux(St, Cond, Assumption, isFeasible);
Ted Kremenek2fb78a72008-12-17 21:50:35 +0000198
199 if (!isFeasible)
200 return St;
201
202 // EvalAssume is used to call into the GRTransferFunction object to perform
203 // any checker-specific update of the state based on this assumption being
204 // true or false.
205 return StateMgr.getTransferFuncs().EvalAssume(StateMgr, St, Cond, Assumption,
206 isFeasible);
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000207}
208
209const GRState*
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000210BasicConstraintManager::AssumeAux(const GRState* St,NonLoc Cond,
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000211 bool Assumption, bool& isFeasible) {
212 BasicValueFactory& BasicVals = StateMgr.getBasicVals();
213 SymbolManager& SymMgr = StateMgr.getSymbolManager();
214
215 switch (Cond.getSubKind()) {
216 default:
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000217 assert(false && "'Assume' not implemented for this NonLoc");
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000218
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000219 case nonloc::SymbolValKind: {
220 nonloc::SymbolVal& SV = cast<nonloc::SymbolVal>(Cond);
Ted Kremenek2dabd432008-12-05 02:27:51 +0000221 SymbolRef sym = SV.getSymbol();
Ted Kremenek9ab6b9c2009-01-22 18:23:34 +0000222 QualType T = SymMgr.getType(sym);
223
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000224 if (Assumption)
Ted Kremenek9ab6b9c2009-01-22 18:23:34 +0000225 return AssumeSymNE(St, sym, BasicVals.getValue(0, T), isFeasible);
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000226 else
Ted Kremenek9ab6b9c2009-01-22 18:23:34 +0000227 return AssumeSymEQ(St, sym, BasicVals.getValue(0, T), isFeasible);
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000228 }
229
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000230 case nonloc::SymIntConstraintValKind:
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000231 return
232 AssumeSymInt(St, Assumption,
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000233 cast<nonloc::SymIntConstraintVal>(Cond).getConstraint(),
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000234 isFeasible);
235
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000236 case nonloc::ConcreteIntKind: {
237 bool b = cast<nonloc::ConcreteInt>(Cond).getValue() != 0;
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000238 isFeasible = b ? Assumption : !Assumption;
239 return St;
240 }
241
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000242 case nonloc::LocAsIntegerKind:
243 return AssumeAux(St, cast<nonloc::LocAsInteger>(Cond).getLoc(),
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000244 Assumption, isFeasible);
245 } // end switch
246}
247
248const GRState*
249BasicConstraintManager::AssumeSymInt(const GRState* St, bool Assumption,
250 const SymIntConstraint& C, bool& isFeasible) {
251
252 switch (C.getOpcode()) {
253 default:
254 // No logic yet for other operators.
255 isFeasible = true;
256 return St;
257
258 case BinaryOperator::EQ:
259 if (Assumption)
260 return AssumeSymEQ(St, C.getSymbol(), C.getInt(), isFeasible);
261 else
262 return AssumeSymNE(St, C.getSymbol(), C.getInt(), isFeasible);
263
264 case BinaryOperator::NE:
265 if (Assumption)
266 return AssumeSymNE(St, C.getSymbol(), C.getInt(), isFeasible);
267 else
268 return AssumeSymEQ(St, C.getSymbol(), C.getInt(), isFeasible);
269
Zhongxing Xu94b83122008-09-19 06:07:59 +0000270 case BinaryOperator::GT:
271 if (Assumption)
272 return AssumeSymGT(St, C.getSymbol(), C.getInt(), isFeasible);
273 else
274 return AssumeSymLE(St, C.getSymbol(), C.getInt(), isFeasible);
275
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000276 case BinaryOperator::GE:
277 if (Assumption)
278 return AssumeSymGE(St, C.getSymbol(), C.getInt(), isFeasible);
279 else
280 return AssumeSymLT(St, C.getSymbol(), C.getInt(), isFeasible);
281
Ted Kremenek8c3e7fb2008-09-16 23:24:45 +0000282 case BinaryOperator::LT:
283 if (Assumption)
284 return AssumeSymLT(St, C.getSymbol(), C.getInt(), isFeasible);
285 else
286 return AssumeSymGE(St, C.getSymbol(), C.getInt(), isFeasible);
287
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000288 case BinaryOperator::LE:
289 if (Assumption)
290 return AssumeSymLE(St, C.getSymbol(), C.getInt(), isFeasible);
291 else
292 return AssumeSymGT(St, C.getSymbol(), C.getInt(), isFeasible);
293 } // end switch
294}
295
296const GRState*
Ted Kremenek2dabd432008-12-05 02:27:51 +0000297BasicConstraintManager::AssumeSymNE(const GRState* St, SymbolRef sym,
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000298 const llvm::APSInt& V, bool& isFeasible) {
299 // First, determine if sym == X, where X != V.
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000300 if (const llvm::APSInt* X = getSymVal(St, sym)) {
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000301 isFeasible = (*X != V);
302 return St;
303 }
304
305 // Second, determine if sym != V.
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000306 if (isNotEqual(St, sym, V)) {
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000307 isFeasible = true;
308 return St;
309 }
310
311 // If we reach here, sym is not a constant and we don't know if it is != V.
312 // Make that assumption.
313 isFeasible = true;
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000314 return AddNE(St, sym, V);
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000315}
316
317const GRState*
Ted Kremenek2dabd432008-12-05 02:27:51 +0000318BasicConstraintManager::AssumeSymEQ(const GRState* St, SymbolRef sym,
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000319 const llvm::APSInt& V, bool& isFeasible) {
320 // First, determine if sym == X, where X != V.
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000321 if (const llvm::APSInt* X = getSymVal(St, sym)) {
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000322 isFeasible = *X == V;
323 return St;
324 }
325
326 // Second, determine if sym != V.
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000327 if (isNotEqual(St, sym, V)) {
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000328 isFeasible = false;
329 return St;
330 }
331
332 // If we reach here, sym is not a constant and we don't know if it is == V.
333 // Make that assumption.
334
335 isFeasible = true;
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000336 return AddEQ(St, sym, V);
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000337}
338
339// These logic will be handled in another ConstraintManager.
340const GRState*
Ted Kremenek2dabd432008-12-05 02:27:51 +0000341BasicConstraintManager::AssumeSymLT(const GRState* St, SymbolRef sym,
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000342 const llvm::APSInt& V, bool& isFeasible) {
Ted Kremenek73abd132008-12-03 18:56:12 +0000343
344 // Is 'V' the smallest possible value?
Chris Lattner071e04e2009-01-30 01:58:33 +0000345 if (V == llvm::APSInt::getMinValue(V.getBitWidth(), V.isUnsigned())) {
Ted Kremenek73abd132008-12-03 18:56:12 +0000346 // sym cannot be any value less than 'V'. This path is infeasible.
347 isFeasible = false;
348 return St;
349 }
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000350
351 // 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::AssumeSymGT(const GRState* St, SymbolRef sym,
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000357 const llvm::APSInt& V, bool& isFeasible) {
358
Ted Kremenekd7ff4872008-12-03 19:06:30 +0000359 // Is 'V' the largest possible value?
Chris Lattner071e04e2009-01-30 01:58:33 +0000360 if (V == llvm::APSInt::getMaxValue(V.getBitWidth(), V.isUnsigned())) {
Ted Kremenekd7ff4872008-12-03 19:06:30 +0000361 // sym cannot be any value greater than 'V'. This path is infeasible.
362 isFeasible = false;
363 return St;
364 }
365
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000366 // FIXME: For now have assuming x > y be the same as assuming sym != V;
367 return AssumeSymNE(St, sym, V, isFeasible);
368}
369
370const GRState*
Ted Kremenek2dabd432008-12-05 02:27:51 +0000371BasicConstraintManager::AssumeSymGE(const GRState* St, SymbolRef sym,
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000372 const llvm::APSInt& V, bool& isFeasible) {
373
Ted Kremenek8c3e7fb2008-09-16 23:24:45 +0000374 // Reject a path if the value of sym is a constant X and !(X >= V).
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000375 if (const llvm::APSInt* X = getSymVal(St, sym)) {
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000376 isFeasible = *X >= V;
377 return St;
378 }
Ted Kremenekd7ff4872008-12-03 19:06:30 +0000379
380 // Sym is not a constant, but it is worth looking to see if V is the
381 // maximum integer value.
Chris Lattner071e04e2009-01-30 01:58:33 +0000382 if (V == llvm::APSInt::getMaxValue(V.getBitWidth(), V.isUnsigned())) {
Ted Kremenekd7ff4872008-12-03 19:06:30 +0000383 // If we know that sym != V, then this condition is infeasible since
384 // there is no other value greater than V.
385 isFeasible = !isNotEqual(St, sym, V);
386
387 // If the path is still feasible then as a consequence we know that
388 // 'sym == V' because we cannot have 'sym > V' (no larger values).
389 // Add this constraint.
390 if (isFeasible)
391 return AddEQ(St, sym, V);
392 }
393 else
394 isFeasible = true;
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000395
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000396 return St;
397}
398
399const GRState*
Ted Kremenek2dabd432008-12-05 02:27:51 +0000400BasicConstraintManager::AssumeSymLE(const GRState* St, SymbolRef sym,
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000401 const llvm::APSInt& V, bool& isFeasible) {
402
Ted Kremenek73abd132008-12-03 18:56:12 +0000403 // Reject a path if the value of sym is a constant X and !(X <= V).
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000404 if (const llvm::APSInt* X = getSymVal(St, sym)) {
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000405 isFeasible = *X <= V;
406 return St;
407 }
Ted Kremenek0a41e5a2008-09-19 18:00:36 +0000408
Ted Kremenek73abd132008-12-03 18:56:12 +0000409 // Sym is not a constant, but it is worth looking to see if V is the
410 // minimum integer value.
Chris Lattner071e04e2009-01-30 01:58:33 +0000411 if (V == llvm::APSInt::getMinValue(V.getBitWidth(), V.isUnsigned())) {
Ted Kremenek73abd132008-12-03 18:56:12 +0000412 // If we know that sym != V, then this condition is infeasible since
413 // there is no other value less than V.
414 isFeasible = !isNotEqual(St, sym, V);
415
416 // If the path is still feasible then as a consequence we know that
417 // 'sym == V' because we cannot have 'sym < V' (no smaller values).
418 // Add this constraint.
419 if (isFeasible)
420 return AddEQ(St, sym, V);
421 }
422 else
423 isFeasible = true;
424
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000425 return St;
426}
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000427
Zhongxing Xue8a964b2008-11-22 13:21:46 +0000428const GRState*
429BasicConstraintManager::AssumeInBound(const GRState* St, SVal Idx,
430 SVal UpperBound, bool Assumption,
431 bool& isFeasible) {
432 // Only support ConcreteInt for now.
433 if (!(isa<nonloc::ConcreteInt>(Idx) && isa<nonloc::ConcreteInt>(UpperBound))){
434 isFeasible = true;
435 return St;
436 }
437
438 const llvm::APSInt& Zero = getBasicVals().getZeroWithPtrWidth(false);
Sebastian Redle95db4f2008-11-24 19:35:33 +0000439 llvm::APSInt IdxV = cast<nonloc::ConcreteInt>(Idx).getValue();
440 // IdxV might be too narrow.
441 if (IdxV.getBitWidth() < Zero.getBitWidth())
442 IdxV.extend(Zero.getBitWidth());
443 // UBV might be too narrow, too.
444 llvm::APSInt UBV = cast<nonloc::ConcreteInt>(UpperBound).getValue();
445 if (UBV.getBitWidth() < Zero.getBitWidth())
446 UBV.extend(Zero.getBitWidth());
Zhongxing Xue8a964b2008-11-22 13:21:46 +0000447
448 bool InBound = (Zero <= IdxV) && (IdxV < UBV);
449
450 isFeasible = Assumption ? InBound : !InBound;
451
452 return St;
453}
454
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000455
Ted Kremenek2dabd432008-12-05 02:27:51 +0000456const GRState* BasicConstraintManager::AddEQ(const GRState* St, SymbolRef sym,
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000457 const llvm::APSInt& V) {
458 // Create a new state with the old binding replaced.
459 GRStateRef state(St, StateMgr);
Ted Kremenek8ee74d52009-01-26 06:04:53 +0000460 return state.set<ConstEq>(sym, &V);
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000461}
462
Ted Kremenek2dabd432008-12-05 02:27:51 +0000463const GRState* BasicConstraintManager::AddNE(const GRState* St, SymbolRef sym,
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000464 const llvm::APSInt& V) {
Zhongxing Xuf0bc50e2008-11-27 06:08:40 +0000465
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000466 GRStateRef state(St, StateMgr);
467
468 // First, retrieve the NE-set associated with the given symbol.
Ted Kremenek8ee74d52009-01-26 06:04:53 +0000469 ConstNotEqTy::data_type* T = state.get<ConstNotEq>(sym);
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000470 GRState::IntSetTy S = T ? *T : ISetFactory.GetEmptySet();
471
472
473 // Now add V to the NE set.
474 S = ISetFactory.Add(S, &V);
475
476 // Create a new state with the old binding replaced.
Ted Kremenek8ee74d52009-01-26 06:04:53 +0000477 return state.set<ConstNotEq>(sym, S);
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000478}
479
480const llvm::APSInt* BasicConstraintManager::getSymVal(const GRState* St,
Ted Kremenek2dabd432008-12-05 02:27:51 +0000481 SymbolRef sym) {
Ted Kremenek8ee74d52009-01-26 06:04:53 +0000482 const ConstEqTy::data_type* T = St->get<ConstEq>(sym);
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000483 return T ? *T : NULL;
484}
485
Ted Kremenek2dabd432008-12-05 02:27:51 +0000486bool BasicConstraintManager::isNotEqual(const GRState* St, SymbolRef sym,
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000487 const llvm::APSInt& V) const {
488
489 // Retrieve the NE-set associated with the given symbol.
Ted Kremenek8ee74d52009-01-26 06:04:53 +0000490 const ConstNotEqTy::data_type* T = St->get<ConstNotEq>(sym);
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000491
492 // See if V is present in the NE-set.
493 return T ? T->contains(&V) : false;
494}
495
Ted Kremenek2dabd432008-12-05 02:27:51 +0000496bool BasicConstraintManager::isEqual(const GRState* St, SymbolRef sym,
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000497 const llvm::APSInt& V) const {
498 // Retrieve the EQ-set associated with the given symbol.
Ted Kremenek8ee74d52009-01-26 06:04:53 +0000499 const ConstEqTy::data_type* T = St->get<ConstEq>(sym);
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000500 // See if V is present in the EQ-set.
501 return T ? **T == V : false;
502}
503
Zhongxing Xu8fd9b352008-11-27 02:39:34 +0000504/// Scan all symbols referenced by the constraints. If the symbol is not alive
505/// as marked in LSymbols, mark it as dead in DSymbols.
Ted Kremenek241677a2009-01-21 22:26:05 +0000506const GRState*
507BasicConstraintManager::RemoveDeadBindings(const GRState* St,
508 SymbolReaper& SymReaper) {
509
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000510 GRStateRef state(St, StateMgr);
Ted Kremenek8ee74d52009-01-26 06:04:53 +0000511 ConstEqTy CE = state.get<ConstEq>();
512 ConstEqTy::Factory& CEFactory = state.get_context<ConstEq>();
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000513
514 for (ConstEqTy::iterator I = CE.begin(), E = CE.end(); I!=E; ++I) {
Ted Kremenek241677a2009-01-21 22:26:05 +0000515 SymbolRef sym = I.getKey();
516 if (SymReaper.maybeDead(sym)) CE = CEFactory.Remove(CE, sym);
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000517 }
Ted Kremenek8ee74d52009-01-26 06:04:53 +0000518 state = state.set<ConstEq>(CE);
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000519
Ted Kremenek8ee74d52009-01-26 06:04:53 +0000520 ConstNotEqTy CNE = state.get<ConstNotEq>();
521 ConstNotEqTy::Factory& CNEFactory = state.get_context<ConstNotEq>();
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000522
523 for (ConstNotEqTy::iterator I = CNE.begin(), E = CNE.end(); I != E; ++I) {
Ted Kremenek2dabd432008-12-05 02:27:51 +0000524 SymbolRef sym = I.getKey();
Ted Kremenek241677a2009-01-21 22:26:05 +0000525 if (SymReaper.maybeDead(sym)) CNE = CNEFactory.Remove(CNE, sym);
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000526 }
527
Ted Kremenek8ee74d52009-01-26 06:04:53 +0000528 return state.set<ConstNotEq>(CNE);
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000529}
530
531void BasicConstraintManager::print(const GRState* St, std::ostream& Out,
532 const char* nl, const char *sep) {
533 // Print equality constraints.
534
Ted Kremenek8ee74d52009-01-26 06:04:53 +0000535 ConstEqTy CE = St->get<ConstEq>();
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000536
537 if (!CE.isEmpty()) {
538 Out << nl << sep << "'==' constraints:";
539
540 for (ConstEqTy::iterator I = CE.begin(), E = CE.end(); I!=E; ++I) {
541 Out << nl << " $" << I.getKey();
542 llvm::raw_os_ostream OS(Out);
543 OS << " : " << *I.getData();
544 }
545 }
546
547 // Print != constraints.
548
Ted Kremenek8ee74d52009-01-26 06:04:53 +0000549 ConstNotEqTy CNE = St->get<ConstNotEq>();
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000550
551 if (!CNE.isEmpty()) {
552 Out << nl << sep << "'!=' constraints:";
553
554 for (ConstNotEqTy::iterator I = CNE.begin(), EI = CNE.end(); I!=EI; ++I) {
555 Out << nl << " $" << I.getKey() << " : ";
556 bool isFirst = true;
557
558 GRState::IntSetTy::iterator J = I.getData().begin(),
559 EJ = I.getData().end();
560
561 for ( ; J != EJ; ++J) {
562 if (isFirst) isFirst = false;
563 else Out << ", ";
564
Zhongxing Xu7d94e262008-11-10 05:00:06 +0000565 Out << (*J)->getSExtValue(); // Hack: should print to raw_ostream.
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000566 }
567 }
568 }
Daniel Dunbar0e194dd2008-08-30 02:06:22 +0000569}