blob: f14ada7aed63a3e87ae4511289c7b3473cb05149 [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();
168
169 while (R) {
170 if (const SubRegion* SubR = dyn_cast<SubRegion>(R)) {
171 R = SubR->getSuperRegion();
172 continue;
173 }
174 else if (const SymbolicRegion* SymR = dyn_cast<SymbolicRegion>(R))
175 return AssumeAux(St, loc::SymbolVal(SymR->getSymbol()), Assumption,
176 isFeasible);
177
178 break;
179 }
180
181 // FALL-THROUGH.
182 }
183
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000184 case loc::FuncValKind:
185 case loc::GotoLabelKind:
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000186 isFeasible = Assumption;
187 return St;
188
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000189 case loc::ConcreteIntKind: {
190 bool b = cast<loc::ConcreteInt>(Cond).getValue() != 0;
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000191 isFeasible = b ? Assumption : !Assumption;
192 return St;
193 }
194 } // end switch
195}
196
197const GRState*
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000198BasicConstraintManager::Assume(const GRState* St, NonLoc Cond, bool Assumption,
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000199 bool& isFeasible) {
200 St = AssumeAux(St, Cond, Assumption, isFeasible);
Ted Kremenek2fb78a72008-12-17 21:50:35 +0000201
202 if (!isFeasible)
203 return St;
204
205 // EvalAssume is used to call into the GRTransferFunction object to perform
206 // any checker-specific update of the state based on this assumption being
207 // true or false.
208 return StateMgr.getTransferFuncs().EvalAssume(StateMgr, St, Cond, Assumption,
209 isFeasible);
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000210}
211
212const GRState*
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000213BasicConstraintManager::AssumeAux(const GRState* St,NonLoc Cond,
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000214 bool Assumption, bool& isFeasible) {
215 BasicValueFactory& BasicVals = StateMgr.getBasicVals();
216 SymbolManager& SymMgr = StateMgr.getSymbolManager();
217
218 switch (Cond.getSubKind()) {
219 default:
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000220 assert(false && "'Assume' not implemented for this NonLoc");
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000221
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000222 case nonloc::SymbolValKind: {
223 nonloc::SymbolVal& SV = cast<nonloc::SymbolVal>(Cond);
Ted Kremenek2dabd432008-12-05 02:27:51 +0000224 SymbolRef sym = SV.getSymbol();
Ted Kremenek9ab6b9c2009-01-22 18:23:34 +0000225 QualType T = SymMgr.getType(sym);
226
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000227 if (Assumption)
Ted Kremenek9ab6b9c2009-01-22 18:23:34 +0000228 return AssumeSymNE(St, sym, BasicVals.getValue(0, T), isFeasible);
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000229 else
Ted Kremenek9ab6b9c2009-01-22 18:23:34 +0000230 return AssumeSymEQ(St, sym, BasicVals.getValue(0, T), isFeasible);
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000231 }
232
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000233 case nonloc::SymIntConstraintValKind:
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000234 return
235 AssumeSymInt(St, Assumption,
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000236 cast<nonloc::SymIntConstraintVal>(Cond).getConstraint(),
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000237 isFeasible);
238
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000239 case nonloc::ConcreteIntKind: {
240 bool b = cast<nonloc::ConcreteInt>(Cond).getValue() != 0;
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000241 isFeasible = b ? Assumption : !Assumption;
242 return St;
243 }
244
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000245 case nonloc::LocAsIntegerKind:
246 return AssumeAux(St, cast<nonloc::LocAsInteger>(Cond).getLoc(),
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000247 Assumption, isFeasible);
248 } // end switch
249}
250
251const GRState*
252BasicConstraintManager::AssumeSymInt(const GRState* St, bool Assumption,
253 const SymIntConstraint& C, bool& isFeasible) {
254
255 switch (C.getOpcode()) {
256 default:
257 // No logic yet for other operators.
258 isFeasible = true;
259 return St;
260
261 case BinaryOperator::EQ:
262 if (Assumption)
263 return AssumeSymEQ(St, C.getSymbol(), C.getInt(), isFeasible);
264 else
265 return AssumeSymNE(St, C.getSymbol(), C.getInt(), isFeasible);
266
267 case BinaryOperator::NE:
268 if (Assumption)
269 return AssumeSymNE(St, C.getSymbol(), C.getInt(), isFeasible);
270 else
271 return AssumeSymEQ(St, C.getSymbol(), C.getInt(), isFeasible);
272
Zhongxing Xu94b83122008-09-19 06:07:59 +0000273 case BinaryOperator::GT:
274 if (Assumption)
275 return AssumeSymGT(St, C.getSymbol(), C.getInt(), isFeasible);
276 else
277 return AssumeSymLE(St, C.getSymbol(), C.getInt(), isFeasible);
278
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000279 case BinaryOperator::GE:
280 if (Assumption)
281 return AssumeSymGE(St, C.getSymbol(), C.getInt(), isFeasible);
282 else
283 return AssumeSymLT(St, C.getSymbol(), C.getInt(), isFeasible);
284
Ted Kremenek8c3e7fb2008-09-16 23:24:45 +0000285 case BinaryOperator::LT:
286 if (Assumption)
287 return AssumeSymLT(St, C.getSymbol(), C.getInt(), isFeasible);
288 else
289 return AssumeSymGE(St, C.getSymbol(), C.getInt(), isFeasible);
290
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000291 case BinaryOperator::LE:
292 if (Assumption)
293 return AssumeSymLE(St, C.getSymbol(), C.getInt(), isFeasible);
294 else
295 return AssumeSymGT(St, C.getSymbol(), C.getInt(), isFeasible);
296 } // end switch
297}
298
299const GRState*
Ted Kremenek2dabd432008-12-05 02:27:51 +0000300BasicConstraintManager::AssumeSymNE(const GRState* St, SymbolRef sym,
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000301 const llvm::APSInt& V, bool& isFeasible) {
302 // First, determine if sym == X, where X != V.
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000303 if (const llvm::APSInt* X = getSymVal(St, sym)) {
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000304 isFeasible = (*X != V);
305 return St;
306 }
307
308 // Second, determine if sym != V.
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000309 if (isNotEqual(St, sym, V)) {
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000310 isFeasible = true;
311 return St;
312 }
313
314 // If we reach here, sym is not a constant and we don't know if it is != V.
315 // Make that assumption.
316 isFeasible = true;
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000317 return AddNE(St, sym, V);
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000318}
319
320const GRState*
Ted Kremenek2dabd432008-12-05 02:27:51 +0000321BasicConstraintManager::AssumeSymEQ(const GRState* St, SymbolRef sym,
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000322 const llvm::APSInt& V, bool& isFeasible) {
323 // First, determine if sym == X, where X != V.
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000324 if (const llvm::APSInt* X = getSymVal(St, sym)) {
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000325 isFeasible = *X == V;
326 return St;
327 }
328
329 // Second, determine if sym != V.
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000330 if (isNotEqual(St, sym, V)) {
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000331 isFeasible = false;
332 return St;
333 }
334
335 // If we reach here, sym is not a constant and we don't know if it is == V.
336 // Make that assumption.
337
338 isFeasible = true;
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000339 return AddEQ(St, sym, V);
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000340}
341
342// These logic will be handled in another ConstraintManager.
343const GRState*
Ted Kremenek2dabd432008-12-05 02:27:51 +0000344BasicConstraintManager::AssumeSymLT(const GRState* St, SymbolRef sym,
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000345 const llvm::APSInt& V, bool& isFeasible) {
Ted Kremenek73abd132008-12-03 18:56:12 +0000346
347 // Is 'V' the smallest possible value?
348 if (V == llvm::APSInt::getMinValue(V.getBitWidth(), V.isSigned())) {
349 // sym cannot be any value less than 'V'. This path is infeasible.
350 isFeasible = false;
351 return St;
352 }
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000353
354 // FIXME: For now have assuming x < y be the same as assuming sym != V;
355 return AssumeSymNE(St, sym, V, isFeasible);
356}
357
358const GRState*
Ted Kremenek2dabd432008-12-05 02:27:51 +0000359BasicConstraintManager::AssumeSymGT(const GRState* St, SymbolRef sym,
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000360 const llvm::APSInt& V, bool& isFeasible) {
361
Ted Kremenekd7ff4872008-12-03 19:06:30 +0000362 // Is 'V' the largest possible value?
363 if (V == llvm::APSInt::getMaxValue(V.getBitWidth(), V.isSigned())) {
364 // sym cannot be any value greater than 'V'. This path is infeasible.
365 isFeasible = false;
366 return St;
367 }
368
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000369 // FIXME: For now have assuming x > y be the same as assuming sym != V;
370 return AssumeSymNE(St, sym, V, isFeasible);
371}
372
373const GRState*
Ted Kremenek2dabd432008-12-05 02:27:51 +0000374BasicConstraintManager::AssumeSymGE(const GRState* St, SymbolRef sym,
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000375 const llvm::APSInt& V, bool& isFeasible) {
376
Ted Kremenek8c3e7fb2008-09-16 23:24:45 +0000377 // Reject a path if the value of sym is a constant X and !(X >= V).
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000378 if (const llvm::APSInt* X = getSymVal(St, sym)) {
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000379 isFeasible = *X >= V;
380 return St;
381 }
Ted Kremenekd7ff4872008-12-03 19:06:30 +0000382
383 // Sym is not a constant, but it is worth looking to see if V is the
384 // maximum integer value.
385 if (V == llvm::APSInt::getMaxValue(V.getBitWidth(), V.isSigned())) {
386 // If we know that sym != V, then this condition is infeasible since
387 // there is no other value greater than V.
388 isFeasible = !isNotEqual(St, sym, V);
389
390 // If the path is still feasible then as a consequence we know that
391 // 'sym == V' because we cannot have 'sym > V' (no larger values).
392 // Add this constraint.
393 if (isFeasible)
394 return AddEQ(St, sym, V);
395 }
396 else
397 isFeasible = true;
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000398
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000399 return St;
400}
401
402const GRState*
Ted Kremenek2dabd432008-12-05 02:27:51 +0000403BasicConstraintManager::AssumeSymLE(const GRState* St, SymbolRef sym,
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000404 const llvm::APSInt& V, bool& isFeasible) {
405
Ted Kremenek73abd132008-12-03 18:56:12 +0000406 // Reject a path if the value of sym is a constant X and !(X <= V).
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000407 if (const llvm::APSInt* X = getSymVal(St, sym)) {
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000408 isFeasible = *X <= V;
409 return St;
410 }
Ted Kremenek0a41e5a2008-09-19 18:00:36 +0000411
Ted Kremenek73abd132008-12-03 18:56:12 +0000412 // Sym is not a constant, but it is worth looking to see if V is the
413 // minimum integer value.
414 if (V == llvm::APSInt::getMinValue(V.getBitWidth(), V.isSigned())) {
415 // If we know that sym != V, then this condition is infeasible since
416 // there is no other value less than V.
417 isFeasible = !isNotEqual(St, sym, V);
418
419 // If the path is still feasible then as a consequence we know that
420 // 'sym == V' because we cannot have 'sym < V' (no smaller values).
421 // Add this constraint.
422 if (isFeasible)
423 return AddEQ(St, sym, V);
424 }
425 else
426 isFeasible = true;
427
Zhongxing Xu30ad1672008-08-27 14:03:33 +0000428 return St;
429}
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000430
Zhongxing Xue8a964b2008-11-22 13:21:46 +0000431const GRState*
432BasicConstraintManager::AssumeInBound(const GRState* St, SVal Idx,
433 SVal UpperBound, bool Assumption,
434 bool& isFeasible) {
435 // Only support ConcreteInt for now.
436 if (!(isa<nonloc::ConcreteInt>(Idx) && isa<nonloc::ConcreteInt>(UpperBound))){
437 isFeasible = true;
438 return St;
439 }
440
441 const llvm::APSInt& Zero = getBasicVals().getZeroWithPtrWidth(false);
Sebastian Redle95db4f2008-11-24 19:35:33 +0000442 llvm::APSInt IdxV = cast<nonloc::ConcreteInt>(Idx).getValue();
443 // IdxV might be too narrow.
444 if (IdxV.getBitWidth() < Zero.getBitWidth())
445 IdxV.extend(Zero.getBitWidth());
446 // UBV might be too narrow, too.
447 llvm::APSInt UBV = cast<nonloc::ConcreteInt>(UpperBound).getValue();
448 if (UBV.getBitWidth() < Zero.getBitWidth())
449 UBV.extend(Zero.getBitWidth());
Zhongxing Xue8a964b2008-11-22 13:21:46 +0000450
451 bool InBound = (Zero <= IdxV) && (IdxV < UBV);
452
453 isFeasible = Assumption ? InBound : !InBound;
454
455 return St;
456}
457
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000458
Ted Kremenek2dabd432008-12-05 02:27:51 +0000459const GRState* BasicConstraintManager::AddEQ(const GRState* St, SymbolRef sym,
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000460 const llvm::APSInt& V) {
461 // Create a new state with the old binding replaced.
462 GRStateRef state(St, StateMgr);
Ted Kremenek8ee74d52009-01-26 06:04:53 +0000463 return state.set<ConstEq>(sym, &V);
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000464}
465
Ted Kremenek2dabd432008-12-05 02:27:51 +0000466const GRState* BasicConstraintManager::AddNE(const GRState* St, SymbolRef sym,
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000467 const llvm::APSInt& V) {
Zhongxing Xuf0bc50e2008-11-27 06:08:40 +0000468
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000469 GRStateRef state(St, StateMgr);
470
471 // First, retrieve the NE-set associated with the given symbol.
Ted Kremenek8ee74d52009-01-26 06:04:53 +0000472 ConstNotEqTy::data_type* T = state.get<ConstNotEq>(sym);
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000473 GRState::IntSetTy S = T ? *T : ISetFactory.GetEmptySet();
474
475
476 // Now add V to the NE set.
477 S = ISetFactory.Add(S, &V);
478
479 // Create a new state with the old binding replaced.
Ted Kremenek8ee74d52009-01-26 06:04:53 +0000480 return state.set<ConstNotEq>(sym, S);
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000481}
482
483const llvm::APSInt* BasicConstraintManager::getSymVal(const GRState* St,
Ted Kremenek2dabd432008-12-05 02:27:51 +0000484 SymbolRef sym) {
Ted Kremenek8ee74d52009-01-26 06:04:53 +0000485 const ConstEqTy::data_type* T = St->get<ConstEq>(sym);
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000486 return T ? *T : NULL;
487}
488
Ted Kremenek2dabd432008-12-05 02:27:51 +0000489bool BasicConstraintManager::isNotEqual(const GRState* St, SymbolRef sym,
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000490 const llvm::APSInt& V) const {
491
492 // Retrieve the NE-set associated with the given symbol.
Ted Kremenek8ee74d52009-01-26 06:04:53 +0000493 const ConstNotEqTy::data_type* T = St->get<ConstNotEq>(sym);
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000494
495 // See if V is present in the NE-set.
496 return T ? T->contains(&V) : false;
497}
498
Ted Kremenek2dabd432008-12-05 02:27:51 +0000499bool BasicConstraintManager::isEqual(const GRState* St, SymbolRef sym,
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000500 const llvm::APSInt& V) const {
501 // Retrieve the EQ-set associated with the given symbol.
Ted Kremenek8ee74d52009-01-26 06:04:53 +0000502 const ConstEqTy::data_type* T = St->get<ConstEq>(sym);
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000503 // See if V is present in the EQ-set.
504 return T ? **T == V : false;
505}
506
Zhongxing Xu8fd9b352008-11-27 02:39:34 +0000507/// Scan all symbols referenced by the constraints. If the symbol is not alive
508/// as marked in LSymbols, mark it as dead in DSymbols.
Ted Kremenek241677a2009-01-21 22:26:05 +0000509const GRState*
510BasicConstraintManager::RemoveDeadBindings(const GRState* St,
511 SymbolReaper& SymReaper) {
512
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000513 GRStateRef state(St, StateMgr);
Ted Kremenek8ee74d52009-01-26 06:04:53 +0000514 ConstEqTy CE = state.get<ConstEq>();
515 ConstEqTy::Factory& CEFactory = state.get_context<ConstEq>();
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000516
517 for (ConstEqTy::iterator I = CE.begin(), E = CE.end(); I!=E; ++I) {
Ted Kremenek241677a2009-01-21 22:26:05 +0000518 SymbolRef sym = I.getKey();
519 if (SymReaper.maybeDead(sym)) CE = CEFactory.Remove(CE, sym);
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000520 }
Ted Kremenek8ee74d52009-01-26 06:04:53 +0000521 state = state.set<ConstEq>(CE);
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000522
Ted Kremenek8ee74d52009-01-26 06:04:53 +0000523 ConstNotEqTy CNE = state.get<ConstNotEq>();
524 ConstNotEqTy::Factory& CNEFactory = state.get_context<ConstNotEq>();
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000525
526 for (ConstNotEqTy::iterator I = CNE.begin(), E = CNE.end(); I != E; ++I) {
Ted Kremenek2dabd432008-12-05 02:27:51 +0000527 SymbolRef sym = I.getKey();
Ted Kremenek241677a2009-01-21 22:26:05 +0000528 if (SymReaper.maybeDead(sym)) CNE = CNEFactory.Remove(CNE, sym);
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000529 }
530
Ted Kremenek8ee74d52009-01-26 06:04:53 +0000531 return state.set<ConstNotEq>(CNE);
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000532}
533
534void BasicConstraintManager::print(const GRState* St, std::ostream& Out,
535 const char* nl, const char *sep) {
536 // Print equality constraints.
537
Ted Kremenek8ee74d52009-01-26 06:04:53 +0000538 ConstEqTy CE = St->get<ConstEq>();
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000539
540 if (!CE.isEmpty()) {
541 Out << nl << sep << "'==' constraints:";
542
543 for (ConstEqTy::iterator I = CE.begin(), E = CE.end(); I!=E; ++I) {
544 Out << nl << " $" << I.getKey();
545 llvm::raw_os_ostream OS(Out);
546 OS << " : " << *I.getData();
547 }
548 }
549
550 // Print != constraints.
551
Ted Kremenek8ee74d52009-01-26 06:04:53 +0000552 ConstNotEqTy CNE = St->get<ConstNotEq>();
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000553
554 if (!CNE.isEmpty()) {
555 Out << nl << sep << "'!=' constraints:";
556
557 for (ConstNotEqTy::iterator I = CNE.begin(), EI = CNE.end(); I!=EI; ++I) {
558 Out << nl << " $" << I.getKey() << " : ";
559 bool isFirst = true;
560
561 GRState::IntSetTy::iterator J = I.getData().begin(),
562 EJ = I.getData().end();
563
564 for ( ; J != EJ; ++J) {
565 if (isFirst) isFirst = false;
566 else Out << ", ";
567
Zhongxing Xu7d94e262008-11-10 05:00:06 +0000568 Out << (*J)->getSExtValue(); // Hack: should print to raw_ostream.
Zhongxing Xu39cfed32008-08-29 14:52:36 +0000569 }
570 }
571 }
Daniel Dunbar0e194dd2008-08-30 02:06:22 +0000572}