blob: 8ea1191b7e2e21eaca1eb376b8307f198416b168 [file] [log] [blame]
Ted Kremenek4adc81e2008-08-13 04:27:00 +00001//= GRState*cpp - Path-Sens. "State" for tracking valuues -----*- C++ -*--=//
Ted Kremenek9153f732008-02-05 07:17:49 +00002//
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//
Ted Kremenek4adc81e2008-08-13 04:27:00 +000010// This file defines SymbolID, ExprBindKey, and GRState*
Ted Kremenek9153f732008-02-05 07:17:49 +000011//
12//===----------------------------------------------------------------------===//
13
Ted Kremeneke7aa9a12008-08-17 02:59:30 +000014#include "clang/Analysis/PathSensitive/GRStateTrait.h"
Ted Kremenek4adc81e2008-08-13 04:27:00 +000015#include "clang/Analysis/PathSensitive/GRState.h"
Ted Kremenek729a9a22008-07-17 23:15:45 +000016#include "clang/Analysis/PathSensitive/GRTransferFuncs.h"
Ted Kremenek05125f12008-08-27 23:13:01 +000017#include "llvm/ADT/SmallSet.h"
Chris Lattner405674c2008-08-23 22:23:37 +000018#include "llvm/Support/raw_ostream.h"
Ted Kremenek05125f12008-08-27 23:13:01 +000019
Ted Kremenekf66ea2cd2008-02-04 21:59:22 +000020using namespace clang;
21
Ted Kremenek05125f12008-08-27 23:13:01 +000022// Give the vtable for ConstraintManager somewhere to live.
23ConstraintManager::~ConstraintManager() {}
24
Ted Kremenek1c72ef02008-08-16 00:49:49 +000025GRStateManager::~GRStateManager() {
26 for (std::vector<GRState::Printer*>::iterator I=Printers.begin(),
27 E=Printers.end(); I!=E; ++I)
28 delete *I;
29
30 for (GDMContextsTy::iterator I=GDMContexts.begin(), E=GDMContexts.end();
31 I!=E; ++I)
32 I->second.second(I->second.first);
33}
34
35//===----------------------------------------------------------------------===//
36// Basic symbolic analysis. This will eventually be refactored into a
37// separate component.
38//===----------------------------------------------------------------------===//
39
40typedef llvm::ImmutableMap<SymbolID,GRState::IntSetTy> ConstNotEqTy;
Ted Kremenekffdbefd2008-08-17 03:10:22 +000041typedef llvm::ImmutableMap<SymbolID,const llvm::APSInt*> ConstEqTy;
Ted Kremenek1c72ef02008-08-16 00:49:49 +000042
Ted Kremenekffdbefd2008-08-17 03:10:22 +000043static int ConstEqTyIndex = 0;
Ted Kremenek1c72ef02008-08-16 00:49:49 +000044static int ConstNotEqTyIndex = 0;
45
46namespace clang {
Ted Kremeneke7aa9a12008-08-17 02:59:30 +000047 template<>
48 struct GRStateTrait<ConstNotEqTy> : public GRStatePartialTrait<ConstNotEqTy> {
49 static inline void* GDMIndex() { return &ConstNotEqTyIndex; }
Ted Kremenek1c72ef02008-08-16 00:49:49 +000050 };
Ted Kremenekffdbefd2008-08-17 03:10:22 +000051
52 template<>
53 struct GRStateTrait<ConstEqTy> : public GRStatePartialTrait<ConstEqTy> {
54 static inline void* GDMIndex() { return &ConstEqTyIndex; }
55 };
Ted Kremenek1c72ef02008-08-16 00:49:49 +000056}
57
Ted Kremenek4adc81e2008-08-13 04:27:00 +000058bool GRState::isNotEqual(SymbolID sym, const llvm::APSInt& V) const {
Ted Kremenekaa1c4e52008-02-21 18:02:17 +000059
60 // Retrieve the NE-set associated with the given symbol.
Ted Kremenek1c72ef02008-08-16 00:49:49 +000061 const ConstNotEqTy::data_type* T = get<ConstNotEqTy>(sym);
Ted Kremenekaa1c4e52008-02-21 18:02:17 +000062
63 // See if V is present in the NE-set.
Ted Kremeneke8fdc832008-07-07 16:21:19 +000064 return T ? T->contains(&V) : false;
Ted Kremenek862d5bb2008-02-06 00:54:14 +000065}
66
Ted Kremenek4adc81e2008-08-13 04:27:00 +000067bool GRState::isEqual(SymbolID sym, const llvm::APSInt& V) const {
Ted Kremenek584def72008-07-22 00:46:16 +000068 // Retrieve the EQ-set associated with the given symbol.
Ted Kremenekffdbefd2008-08-17 03:10:22 +000069 const ConstEqTy::data_type* T = get<ConstEqTy>(sym);
Ted Kremenek584def72008-07-22 00:46:16 +000070 // See if V is present in the EQ-set.
71 return T ? **T == V : false;
72}
73
Ted Kremenek4adc81e2008-08-13 04:27:00 +000074const llvm::APSInt* GRState::getSymVal(SymbolID sym) const {
Ted Kremenekffdbefd2008-08-17 03:10:22 +000075 const ConstEqTy::data_type* T = get<ConstEqTy>(sym);
Ted Kremeneke8fdc832008-07-07 16:21:19 +000076 return T ? *T : NULL;
Ted Kremenek862d5bb2008-02-06 00:54:14 +000077}
78
Ted Kremenek4adc81e2008-08-13 04:27:00 +000079const GRState*
80GRStateManager::RemoveDeadBindings(const GRState* St, Stmt* Loc,
Ted Kremenek1c72ef02008-08-16 00:49:49 +000081 const LiveVariables& Liveness,
82 DeadSymbolsTy& DSymbols) {
Ted Kremenekb87d9092008-02-08 19:17:19 +000083
84 // This code essentially performs a "mark-and-sweep" of the VariableBindings.
85 // The roots are any Block-level exprs and Decls that our liveness algorithm
86 // tells us are live. We then see what Decls they may reference, and keep
87 // those around. This code more than likely can be made faster, and the
88 // frequency of which this method is called should be experimented with
Ted Kremenekf59bf482008-07-17 18:38:48 +000089 // for optimum performance.
90 DRoots.clear();
91 StoreManager::LiveSymbolsTy LSymbols;
Ted Kremeneke7d22112008-02-11 19:21:59 +000092
Ted Kremenek4adc81e2008-08-13 04:27:00 +000093 GRState NewSt = *St;
Ted Kremenekf59bf482008-07-17 18:38:48 +000094
Ted Kremenekdf9cdf82008-08-20 17:08:29 +000095 NewSt.Env = EnvMgr.RemoveDeadBindings(NewSt.Env, Loc, Liveness,
96 DRoots, LSymbols);
Ted Kremenek016f52f2008-02-08 21:10:02 +000097
Ted Kremenekf59bf482008-07-17 18:38:48 +000098 // Clean up the store.
99 DSymbols.clear();
100 NewSt.St = StMgr->RemoveDeadBindings(St->getStore(), Loc, Liveness, DRoots,
101 LSymbols, DSymbols);
Ted Kremenekb87d9092008-02-08 19:17:19 +0000102
Ted Kremenekffdbefd2008-08-17 03:10:22 +0000103
104 GRStateRef state(getPersistentState(NewSt), *this);
105
Ted Kremenekf59bf482008-07-17 18:38:48 +0000106 // Remove the dead symbols from the symbol tracker.
Ted Kremenek1c72ef02008-08-16 00:49:49 +0000107 // FIXME: Refactor into something else that manages symbol values.
Ted Kremenek77d7ef82008-04-24 18:31:42 +0000108
Ted Kremenekffdbefd2008-08-17 03:10:22 +0000109 ConstEqTy CE = state.get<ConstEqTy>();
110 ConstEqTy::Factory& CEFactory = state.get_context<ConstEqTy>();
111
112 for (ConstEqTy::iterator I = CE.begin(), E = CE.end(); I!=E; ++I) {
113 SymbolID sym = I.getKey();
Ted Kremenekf59bf482008-07-17 18:38:48 +0000114 if (!LSymbols.count(sym)) {
115 DSymbols.insert(sym);
Ted Kremenekffdbefd2008-08-17 03:10:22 +0000116 CE = CEFactory.Remove(CE, sym);
Ted Kremenek77d7ef82008-04-24 18:31:42 +0000117 }
118 }
Ted Kremenek4f7b4832008-08-20 16:59:15 +0000119 state = state.set<ConstEqTy>(CE);
120
Ted Kremenek1c72ef02008-08-16 00:49:49 +0000121 ConstNotEqTy CNE = state.get<ConstNotEqTy>();
122 ConstNotEqTy::Factory& CNEFactory = state.get_context<ConstNotEqTy>();
123
124 for (ConstNotEqTy::iterator I = CNE.begin(), E = CNE.end(); I != E; ++I) {
125 SymbolID sym = I.getKey();
Ted Kremenekf59bf482008-07-17 18:38:48 +0000126 if (!LSymbols.count(sym)) {
127 DSymbols.insert(sym);
Ted Kremenek1c72ef02008-08-16 00:49:49 +0000128 CNE = CNEFactory.Remove(CNE, sym);
Ted Kremenek77d7ef82008-04-24 18:31:42 +0000129 }
130 }
Ted Kremenek90e14812008-02-14 23:25:54 +0000131
Ted Kremenek1c72ef02008-08-16 00:49:49 +0000132 return state.set<ConstNotEqTy>(CNE);
Ted Kremenekb87d9092008-02-08 19:17:19 +0000133}
Ted Kremenek862d5bb2008-02-06 00:54:14 +0000134
Ted Kremenek4adc81e2008-08-13 04:27:00 +0000135const GRState* GRStateManager::SetRVal(const GRState* St, LVal LV,
Ted Kremenek4323a572008-07-10 22:03:41 +0000136 RVal V) {
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000137
Ted Kremenek4323a572008-07-10 22:03:41 +0000138 Store OldStore = St->getStore();
139 Store NewStore = StMgr->SetRVal(OldStore, LV, V);
Ted Kremenek3271f8d2008-02-07 04:16:04 +0000140
Ted Kremenek4323a572008-07-10 22:03:41 +0000141 if (NewStore == OldStore)
142 return St;
Ted Kremenek692416c2008-02-18 22:57:02 +0000143
Ted Kremenek4adc81e2008-08-13 04:27:00 +0000144 GRState NewSt = *St;
Ted Kremenek4323a572008-07-10 22:03:41 +0000145 NewSt.St = NewStore;
146 return getPersistentState(NewSt);
Ted Kremenekf66ea2cd2008-02-04 21:59:22 +0000147}
148
Zhongxing Xubbe8ff42008-08-21 22:34:01 +0000149const GRState* GRStateManager::AddDecl(const GRState* St, const VarDecl* VD,
150 Expr* Ex, unsigned Count) {
151 Store OldStore = St->getStore();
152 Store NewStore;
153
154 if (Ex)
Ted Kremeneke53c0692008-08-23 00:50:55 +0000155 NewStore = StMgr->AddDecl(OldStore, *this, VD, Ex,
Zhongxing Xubbe8ff42008-08-21 22:34:01 +0000156 GetRVal(St, Ex), Count);
157 else
Ted Kremeneke53c0692008-08-23 00:50:55 +0000158 NewStore = StMgr->AddDecl(OldStore, *this, VD, Ex);
Zhongxing Xubbe8ff42008-08-21 22:34:01 +0000159
160 if (NewStore == OldStore)
161 return St;
Ted Kremeneke53c0692008-08-23 00:50:55 +0000162
Zhongxing Xubbe8ff42008-08-21 22:34:01 +0000163 GRState NewSt = *St;
164 NewSt.St = NewStore;
165 return getPersistentState(NewSt);
166}
167
Ted Kremenek4adc81e2008-08-13 04:27:00 +0000168const GRState* GRStateManager::Unbind(const GRState* St, LVal LV) {
Ted Kremenek4323a572008-07-10 22:03:41 +0000169 Store OldStore = St->getStore();
170 Store NewStore = StMgr->Remove(OldStore, LV);
171
172 if (NewStore == OldStore)
173 return St;
174
Ted Kremenek4adc81e2008-08-13 04:27:00 +0000175 GRState NewSt = *St;
Ted Kremenek4323a572008-07-10 22:03:41 +0000176 NewSt.St = NewStore;
177 return getPersistentState(NewSt);
178}
179
180
Ted Kremenek4adc81e2008-08-13 04:27:00 +0000181const GRState* GRStateManager::AddNE(const GRState* St, SymbolID sym,
Ted Kremenek1c72ef02008-08-16 00:49:49 +0000182 const llvm::APSInt& V) {
183
184 GRStateRef state(St, *this);
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000185
Ted Kremenek862d5bb2008-02-06 00:54:14 +0000186 // First, retrieve the NE-set associated with the given symbol.
Ted Kremenek1c72ef02008-08-16 00:49:49 +0000187 ConstNotEqTy::data_type* T = state.get<ConstNotEqTy>(sym);
Ted Kremenek4adc81e2008-08-13 04:27:00 +0000188 GRState::IntSetTy S = T ? *T : ISetFactory.GetEmptySet();
Ted Kremenek862d5bb2008-02-06 00:54:14 +0000189
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000190 // Now add V to the NE set.
Ted Kremenek862d5bb2008-02-06 00:54:14 +0000191 S = ISetFactory.Add(S, &V);
192
193 // Create a new state with the old binding replaced.
Ted Kremenek1c72ef02008-08-16 00:49:49 +0000194 return state.set<ConstNotEqTy>(sym, S);
Ted Kremenek862d5bb2008-02-06 00:54:14 +0000195}
196
Ted Kremenek4adc81e2008-08-13 04:27:00 +0000197const GRState* GRStateManager::AddEQ(const GRState* St, SymbolID sym,
Ted Kremenek4323a572008-07-10 22:03:41 +0000198 const llvm::APSInt& V) {
Ted Kremenek862d5bb2008-02-06 00:54:14 +0000199 // Create a new state with the old binding replaced.
Ted Kremenekffdbefd2008-08-17 03:10:22 +0000200 GRStateRef state(St, *this);
201 return state.set<ConstEqTy>(sym, &V);
Ted Kremenek862d5bb2008-02-06 00:54:14 +0000202}
203
Ted Kremenek4adc81e2008-08-13 04:27:00 +0000204const GRState* GRStateManager::getInitialState() {
Ted Kremenek5a7b3822008-02-26 23:37:01 +0000205
Ted Kremenekcaa37242008-08-19 16:51:45 +0000206 GRState StateImpl(EnvMgr.getInitialEnvironment(),
207 StMgr->getInitialStore(*this),
Ted Kremenekffdbefd2008-08-17 03:10:22 +0000208 GDMFactory.GetEmptyMap());
Ted Kremenekcaa37242008-08-19 16:51:45 +0000209
Ted Kremenek9153f732008-02-05 07:17:49 +0000210 return getPersistentState(StateImpl);
211}
212
Ted Kremenek4adc81e2008-08-13 04:27:00 +0000213const GRState* GRStateManager::getPersistentState(GRState& State) {
Ted Kremenek9153f732008-02-05 07:17:49 +0000214
215 llvm::FoldingSetNodeID ID;
216 State.Profile(ID);
Ted Kremeneke7d22112008-02-11 19:21:59 +0000217 void* InsertPos;
Ted Kremenek9153f732008-02-05 07:17:49 +0000218
Ted Kremenek4adc81e2008-08-13 04:27:00 +0000219 if (GRState* I = StateSet.FindNodeOrInsertPos(ID, InsertPos))
Ted Kremenek9153f732008-02-05 07:17:49 +0000220 return I;
221
Ted Kremenek4adc81e2008-08-13 04:27:00 +0000222 GRState* I = (GRState*) Alloc.Allocate<GRState>();
223 new (I) GRState(State);
Ted Kremenek9153f732008-02-05 07:17:49 +0000224 StateSet.InsertNode(I, InsertPos);
225 return I;
226}
Ted Kremeneke7d22112008-02-11 19:21:59 +0000227
Ted Kremenek59894f92008-03-04 18:30:35 +0000228
Ted Kremenek1c72ef02008-08-16 00:49:49 +0000229//===----------------------------------------------------------------------===//
230// State pretty-printing.
231//===----------------------------------------------------------------------===//
Ted Kremenek461f9772008-03-11 18:57:24 +0000232
Ted Kremeneka622d8c2008-08-19 22:24:03 +0000233void GRState::print(std::ostream& Out, StoreManager& StoreMgr,
234 Printer** Beg, Printer** End,
Ted Kremenekae6814e2008-08-13 21:24:49 +0000235 const char* nl, const char* sep) const {
Ted Kremeneke7d22112008-02-11 19:21:59 +0000236
Ted Kremeneka622d8c2008-08-19 22:24:03 +0000237 // Print the store.
238 StoreMgr.print(getStore(), Out, nl, sep);
Ted Kremeneke7d22112008-02-11 19:21:59 +0000239
240 // Print Subexpression bindings.
Ted Kremeneka622d8c2008-08-19 22:24:03 +0000241 bool isFirst = true;
Ted Kremeneke7d22112008-02-11 19:21:59 +0000242
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000243 for (seb_iterator I = seb_begin(), E = seb_end(); I != E; ++I) {
Ted Kremeneke7d22112008-02-11 19:21:59 +0000244
245 if (isFirst) {
Ted Kremenek59894f92008-03-04 18:30:35 +0000246 Out << nl << nl << "Sub-Expressions:" << nl;
Ted Kremeneke7d22112008-02-11 19:21:59 +0000247 isFirst = false;
248 }
Ted Kremenek59894f92008-03-04 18:30:35 +0000249 else { Out << nl; }
Ted Kremeneke7d22112008-02-11 19:21:59 +0000250
251 Out << " (" << (void*) I.getKey() << ") ";
252 I.getKey()->printPretty(Out);
253 Out << " : ";
254 I.getData().print(Out);
255 }
256
257 // Print block-expression bindings.
Ted Kremeneke7d22112008-02-11 19:21:59 +0000258 isFirst = true;
259
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000260 for (beb_iterator I = beb_begin(), E = beb_end(); I != E; ++I) {
Ted Kremeneke7d22112008-02-11 19:21:59 +0000261
262 if (isFirst) {
Ted Kremenek59894f92008-03-04 18:30:35 +0000263 Out << nl << nl << "Block-level Expressions:" << nl;
Ted Kremeneke7d22112008-02-11 19:21:59 +0000264 isFirst = false;
265 }
Ted Kremenek59894f92008-03-04 18:30:35 +0000266 else { Out << nl; }
Ted Kremeneke7d22112008-02-11 19:21:59 +0000267
268 Out << " (" << (void*) I.getKey() << ") ";
269 I.getKey()->printPretty(Out);
270 Out << " : ";
271 I.getData().print(Out);
272 }
273
274 // Print equality constraints.
Ted Kremenekae6814e2008-08-13 21:24:49 +0000275 // FIXME: Make just another printer do this.
Ted Kremenekffdbefd2008-08-17 03:10:22 +0000276 ConstEqTy CE = get<ConstEqTy>();
277
278 if (!CE.isEmpty()) {
Ted Kremenek59894f92008-03-04 18:30:35 +0000279 Out << nl << sep << "'==' constraints:";
Ted Kremenekffdbefd2008-08-17 03:10:22 +0000280
Chris Lattner405674c2008-08-23 22:23:37 +0000281 for (ConstEqTy::iterator I = CE.begin(), E = CE.end(); I!=E; ++I) {
282 Out << nl << " $" << I.getKey();
283 llvm::raw_os_ostream OS(Out);
284 OS << " : " << *I.getData();
285 }
Ted Kremeneke7d22112008-02-11 19:21:59 +0000286 }
Ted Kremeneke7d22112008-02-11 19:21:59 +0000287
288 // Print != constraints.
Ted Kremenekae6814e2008-08-13 21:24:49 +0000289 // FIXME: Make just another printer do this.
Ted Kremenek1c72ef02008-08-16 00:49:49 +0000290
291 ConstNotEqTy CNE = get<ConstNotEqTy>();
292
293 if (!CNE.isEmpty()) {
Ted Kremenek59894f92008-03-04 18:30:35 +0000294 Out << nl << sep << "'!=' constraints:";
Ted Kremeneke7d22112008-02-11 19:21:59 +0000295
Ted Kremenek1c72ef02008-08-16 00:49:49 +0000296 for (ConstNotEqTy::iterator I = CNE.begin(), EI = CNE.end(); I!=EI; ++I) {
Ted Kremenek59894f92008-03-04 18:30:35 +0000297 Out << nl << " $" << I.getKey() << " : ";
Ted Kremeneke7d22112008-02-11 19:21:59 +0000298 isFirst = true;
299
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000300 IntSetTy::iterator J = I.getData().begin(), EJ = I.getData().end();
Ted Kremeneke7d22112008-02-11 19:21:59 +0000301
302 for ( ; J != EJ; ++J) {
303 if (isFirst) isFirst = false;
304 else Out << ", ";
305
Chris Lattner9aa77f12008-08-17 07:19:51 +0000306 Out << *J;
Ted Kremeneke7d22112008-02-11 19:21:59 +0000307 }
308 }
309 }
Ted Kremenek461f9772008-03-11 18:57:24 +0000310
Ted Kremenekae6814e2008-08-13 21:24:49 +0000311 // Print checker-specific data.
312 for ( ; Beg != End ; ++Beg) (*Beg)->Print(Out, this, nl, sep);
Ted Kremeneke7d22112008-02-11 19:21:59 +0000313}
Ted Kremenek729a9a22008-07-17 23:15:45 +0000314
Ted Kremenek1c72ef02008-08-16 00:49:49 +0000315void GRStateRef::printDOT(std::ostream& Out) const {
316 print(Out, "\\l", "\\|");
317}
318
319void GRStateRef::printStdErr() const {
320 print(*llvm::cerr);
321}
322
323void GRStateRef::print(std::ostream& Out, const char* nl, const char* sep)const{
324 GRState::Printer **beg = Mgr->Printers.empty() ? 0 : &Mgr->Printers[0];
325 GRState::Printer **end = !beg ? 0 : beg + Mgr->Printers.size();
Ted Kremeneka622d8c2008-08-19 22:24:03 +0000326 St->print(Out, *Mgr->StMgr, beg, end, nl, sep);
Ted Kremenek1c72ef02008-08-16 00:49:49 +0000327}
328
Ted Kremenek72cd17f2008-08-14 21:16:54 +0000329//===----------------------------------------------------------------------===//
330// Generic Data Map.
331//===----------------------------------------------------------------------===//
332
333void* const* GRState::FindGDM(void* K) const {
334 return GDM.lookup(K);
335}
336
Ted Kremenek1c72ef02008-08-16 00:49:49 +0000337void*
338GRStateManager::FindGDMContext(void* K,
339 void* (*CreateContext)(llvm::BumpPtrAllocator&),
340 void (*DeleteContext)(void*)) {
341
342 std::pair<void*, void (*)(void*)>& p = GDMContexts[K];
343 if (!p.first) {
344 p.first = CreateContext(Alloc);
345 p.second = DeleteContext;
346 }
347
348 return p.first;
349}
350
Ted Kremenek72cd17f2008-08-14 21:16:54 +0000351const GRState* GRStateManager::addGDM(const GRState* St, void* Key, void* Data){
352 GRState::GenericDataMap M1 = St->getGDM();
353 GRState::GenericDataMap M2 = GDMFactory.Add(M1, Key, Data);
354
355 if (M1 == M2)
356 return St;
357
358 GRState NewSt = *St;
359 NewSt.GDM = M2;
360 return getPersistentState(NewSt);
361}
Ted Kremenek584def72008-07-22 00:46:16 +0000362
363//===----------------------------------------------------------------------===//
364// Queries.
365//===----------------------------------------------------------------------===//
366
Ted Kremenek4adc81e2008-08-13 04:27:00 +0000367bool GRStateManager::isEqual(const GRState* state, Expr* Ex,
Ted Kremenek1c72ef02008-08-16 00:49:49 +0000368 const llvm::APSInt& Y) {
369
Ted Kremenek584def72008-07-22 00:46:16 +0000370 RVal V = GetRVal(state, Ex);
371
372 if (lval::ConcreteInt* X = dyn_cast<lval::ConcreteInt>(&V))
373 return X->getValue() == Y;
374
375 if (nonlval::ConcreteInt* X = dyn_cast<nonlval::ConcreteInt>(&V))
376 return X->getValue() == Y;
377
378 if (nonlval::SymbolVal* X = dyn_cast<nonlval::SymbolVal>(&V))
379 return state->isEqual(X->getSymbol(), Y);
380
381 if (lval::SymbolVal* X = dyn_cast<lval::SymbolVal>(&V))
382 return state->isEqual(X->getSymbol(), Y);
383
384 return false;
385}
386
Ted Kremenek1c72ef02008-08-16 00:49:49 +0000387bool GRStateManager::isEqual(const GRState* state, Expr* Ex, uint64_t x) {
Ted Kremenek584def72008-07-22 00:46:16 +0000388 return isEqual(state, Ex, BasicVals.getValue(x, Ex->getType()));
389}