[analyzer] Refactoring: Move stuff into namespace 'GR'.
[clang.git] / lib / GR / GRState.cpp
blob993fa1a9cb4978b4e3852feb87396d3012648872
1 //= GRState.cpp - Path-Sensitive "State" for tracking values -----*- 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 implements GRState and GRStateManager.
12 //===----------------------------------------------------------------------===//
14 #include "clang/Analysis/CFG.h"
15 #include "clang/GR/PathSensitive/GRStateTrait.h"
16 #include "clang/GR/PathSensitive/GRState.h"
17 #include "clang/GR/PathSensitive/GRSubEngine.h"
18 #include "clang/GR/PathSensitive/GRTransferFuncs.h"
19 #include "llvm/Support/raw_ostream.h"
21 using namespace clang;
22 using namespace GR;
24 // Give the vtable for ConstraintManager somewhere to live.
25 // FIXME: Move this elsewhere.
26 ConstraintManager::~ConstraintManager() {}
28 GRStateManager::~GRStateManager() {
29 for (std::vector<GRState::Printer*>::iterator I=Printers.begin(),
30 E=Printers.end(); I!=E; ++I)
31 delete *I;
33 for (GDMContextsTy::iterator I=GDMContexts.begin(), E=GDMContexts.end();
34 I!=E; ++I)
35 I->second.second(I->second.first);
38 const GRState*
39 GRStateManager::RemoveDeadBindings(const GRState* state,
40 const StackFrameContext *LCtx,
41 SymbolReaper& SymReaper) {
43 // This code essentially performs a "mark-and-sweep" of the VariableBindings.
44 // The roots are any Block-level exprs and Decls that our liveness algorithm
45 // tells us are live. We then see what Decls they may reference, and keep
46 // those around. This code more than likely can be made faster, and the
47 // frequency of which this method is called should be experimented with
48 // for optimum performance.
49 llvm::SmallVector<const MemRegion*, 10> RegionRoots;
50 GRState NewState = *state;
52 NewState.Env = EnvMgr.RemoveDeadBindings(NewState.Env, SymReaper,
53 state, RegionRoots);
55 // Clean up the store.
56 NewState.St = StoreMgr->RemoveDeadBindings(NewState.St, LCtx,
57 SymReaper, RegionRoots);
58 state = getPersistentState(NewState);
59 return ConstraintMgr->RemoveDeadBindings(state, SymReaper);
62 const GRState *GRStateManager::MarshalState(const GRState *state,
63 const StackFrameContext *InitLoc) {
64 // make up an empty state for now.
65 GRState State(this,
66 EnvMgr.getInitialEnvironment(),
67 StoreMgr->getInitialStore(InitLoc),
68 GDMFactory.getEmptyMap());
70 return getPersistentState(State);
73 const GRState *GRState::bindCompoundLiteral(const CompoundLiteralExpr* CL,
74 const LocationContext *LC,
75 SVal V) const {
76 Store new_store =
77 getStateManager().StoreMgr->BindCompoundLiteral(St, CL, LC, V);
78 return makeWithStore(new_store);
81 const GRState *GRState::bindDecl(const VarRegion* VR, SVal IVal) const {
82 Store new_store = getStateManager().StoreMgr->BindDecl(St, VR, IVal);
83 return makeWithStore(new_store);
86 const GRState *GRState::bindDeclWithNoInit(const VarRegion* VR) const {
87 Store new_store = getStateManager().StoreMgr->BindDeclWithNoInit(St, VR);
88 return makeWithStore(new_store);
91 const GRState *GRState::bindLoc(Loc LV, SVal V) const {
92 GRStateManager &Mgr = getStateManager();
93 Store new_store = Mgr.StoreMgr->Bind(St, LV, V);
94 const GRState *new_state = makeWithStore(new_store);
96 const MemRegion *MR = LV.getAsRegion();
97 if (MR)
98 return Mgr.getOwningEngine().ProcessRegionChange(new_state, MR);
100 return new_state;
103 const GRState *GRState::bindDefault(SVal loc, SVal V) const {
104 GRStateManager &Mgr = getStateManager();
105 const MemRegion *R = cast<loc::MemRegionVal>(loc).getRegion();
106 Store new_store = Mgr.StoreMgr->BindDefault(St, R, V);
107 const GRState *new_state = makeWithStore(new_store);
108 return Mgr.getOwningEngine().ProcessRegionChange(new_state, R);
111 const GRState *GRState::InvalidateRegions(const MemRegion * const *Begin,
112 const MemRegion * const *End,
113 const Expr *E, unsigned Count,
114 StoreManager::InvalidatedSymbols *IS,
115 bool invalidateGlobals) const {
116 GRStateManager &Mgr = getStateManager();
117 GRSubEngine &Eng = Mgr.getOwningEngine();
119 if (Eng.WantsRegionChangeUpdate(this)) {
120 StoreManager::InvalidatedRegions Regions;
122 Store new_store = Mgr.StoreMgr->InvalidateRegions(St, Begin, End,
123 E, Count, IS,
124 invalidateGlobals,
125 &Regions);
126 const GRState *new_state = makeWithStore(new_store);
128 return Eng.ProcessRegionChanges(new_state,
129 &Regions.front(),
130 &Regions.back()+1);
133 Store new_store = Mgr.StoreMgr->InvalidateRegions(St, Begin, End,
134 E, Count, IS,
135 invalidateGlobals,
136 NULL);
137 return makeWithStore(new_store);
140 const GRState *GRState::unbindLoc(Loc LV) const {
141 assert(!isa<loc::MemRegionVal>(LV) && "Use InvalidateRegion instead.");
143 Store OldStore = getStore();
144 Store NewStore = getStateManager().StoreMgr->Remove(OldStore, LV);
146 if (NewStore == OldStore)
147 return this;
149 return makeWithStore(NewStore);
152 const GRState *GRState::EnterStackFrame(const StackFrameContext *frame) const {
153 Store new_store = getStateManager().StoreMgr->EnterStackFrame(this, frame);
154 return makeWithStore(new_store);
157 SVal GRState::getSValAsScalarOrLoc(const MemRegion *R) const {
158 // We only want to do fetches from regions that we can actually bind
159 // values. For example, SymbolicRegions of type 'id<...>' cannot
160 // have direct bindings (but their can be bindings on their subregions).
161 if (!R->isBoundable())
162 return UnknownVal();
164 if (const TypedRegion *TR = dyn_cast<TypedRegion>(R)) {
165 QualType T = TR->getValueType();
166 if (Loc::IsLocType(T) || T->isIntegerType())
167 return getSVal(R);
170 return UnknownVal();
173 SVal GRState::getSVal(Loc location, QualType T) const {
174 SVal V = getRawSVal(cast<Loc>(location), T);
176 // If 'V' is a symbolic value that is *perfectly* constrained to
177 // be a constant value, use that value instead to lessen the burden
178 // on later analysis stages (so we have less symbolic values to reason
179 // about).
180 if (!T.isNull()) {
181 if (SymbolRef sym = V.getAsSymbol()) {
182 if (const llvm::APSInt *Int = getSymVal(sym)) {
183 // FIXME: Because we don't correctly model (yet) sign-extension
184 // and truncation of symbolic values, we need to convert
185 // the integer value to the correct signedness and bitwidth.
187 // This shows up in the following:
189 // char foo();
190 // unsigned x = foo();
191 // if (x == 54)
192 // ...
194 // The symbolic value stored to 'x' is actually the conjured
195 // symbol for the call to foo(); the type of that symbol is 'char',
196 // not unsigned.
197 const llvm::APSInt &NewV = getBasicVals().Convert(T, *Int);
199 if (isa<Loc>(V))
200 return loc::ConcreteInt(NewV);
201 else
202 return nonloc::ConcreteInt(NewV);
207 return V;
210 const GRState *GRState::BindExpr(const Stmt* S, SVal V, bool Invalidate) const{
211 Environment NewEnv = getStateManager().EnvMgr.bindExpr(Env, S, V,
212 Invalidate);
213 if (NewEnv == Env)
214 return this;
216 GRState NewSt = *this;
217 NewSt.Env = NewEnv;
218 return getStateManager().getPersistentState(NewSt);
221 const GRState *GRState::bindExprAndLocation(const Stmt *S, SVal location,
222 SVal V) const {
223 Environment NewEnv =
224 getStateManager().EnvMgr.bindExprAndLocation(Env, S, location, V);
226 if (NewEnv == Env)
227 return this;
229 GRState NewSt = *this;
230 NewSt.Env = NewEnv;
231 return getStateManager().getPersistentState(NewSt);
234 const GRState *GRState::assumeInBound(DefinedOrUnknownSVal Idx,
235 DefinedOrUnknownSVal UpperBound,
236 bool Assumption) const {
237 if (Idx.isUnknown() || UpperBound.isUnknown())
238 return this;
240 // Build an expression for 0 <= Idx < UpperBound.
241 // This is the same as Idx + MIN < UpperBound + MIN, if overflow is allowed.
242 // FIXME: This should probably be part of SValBuilder.
243 GRStateManager &SM = getStateManager();
244 SValBuilder &svalBuilder = SM.getSValBuilder();
245 ASTContext &Ctx = svalBuilder.getContext();
247 // Get the offset: the minimum value of the array index type.
248 BasicValueFactory &BVF = svalBuilder.getBasicValueFactory();
249 // FIXME: This should be using ValueManager::ArrayindexTy...somehow.
250 QualType indexTy = Ctx.IntTy;
251 nonloc::ConcreteInt Min(BVF.getMinValue(indexTy));
253 // Adjust the index.
254 SVal newIdx = svalBuilder.evalBinOpNN(this, BO_Add,
255 cast<NonLoc>(Idx), Min, indexTy);
256 if (newIdx.isUnknownOrUndef())
257 return this;
259 // Adjust the upper bound.
260 SVal newBound =
261 svalBuilder.evalBinOpNN(this, BO_Add, cast<NonLoc>(UpperBound),
262 Min, indexTy);
264 if (newBound.isUnknownOrUndef())
265 return this;
267 // Build the actual comparison.
268 SVal inBound = svalBuilder.evalBinOpNN(this, BO_LT,
269 cast<NonLoc>(newIdx), cast<NonLoc>(newBound),
270 Ctx.IntTy);
271 if (inBound.isUnknownOrUndef())
272 return this;
274 // Finally, let the constraint manager take care of it.
275 ConstraintManager &CM = SM.getConstraintManager();
276 return CM.assume(this, cast<DefinedSVal>(inBound), Assumption);
279 const GRState* GRStateManager::getInitialState(const LocationContext *InitLoc) {
280 GRState State(this,
281 EnvMgr.getInitialEnvironment(),
282 StoreMgr->getInitialStore(InitLoc),
283 GDMFactory.getEmptyMap());
285 return getPersistentState(State);
288 const GRState* GRStateManager::getPersistentState(GRState& State) {
290 llvm::FoldingSetNodeID ID;
291 State.Profile(ID);
292 void* InsertPos;
294 if (GRState* I = StateSet.FindNodeOrInsertPos(ID, InsertPos))
295 return I;
297 GRState* I = (GRState*) Alloc.Allocate<GRState>();
298 new (I) GRState(State);
299 StateSet.InsertNode(I, InsertPos);
300 return I;
303 const GRState* GRState::makeWithStore(Store store) const {
304 GRState NewSt = *this;
305 NewSt.St = store;
306 return getStateManager().getPersistentState(NewSt);
309 //===----------------------------------------------------------------------===//
310 // State pretty-printing.
311 //===----------------------------------------------------------------------===//
313 static bool IsEnvLoc(const Stmt *S) {
314 // FIXME: This is a layering violation. Should be in environment.
315 return (bool) (((uintptr_t) S) & 0x1);
318 void GRState::print(llvm::raw_ostream& Out, CFG &C, const char* nl,
319 const char* sep) const {
320 // Print the store.
321 GRStateManager &Mgr = getStateManager();
322 Mgr.getStoreManager().print(getStore(), Out, nl, sep);
324 // Print Subexpression bindings.
325 bool isFirst = true;
327 // FIXME: All environment printing should be moved inside Environment.
328 for (Environment::iterator I = Env.begin(), E = Env.end(); I != E; ++I) {
329 if (C.isBlkExpr(I.getKey()) || IsEnvLoc(I.getKey()))
330 continue;
332 if (isFirst) {
333 Out << nl << nl << "Sub-Expressions:" << nl;
334 isFirst = false;
336 else { Out << nl; }
338 Out << " (" << (void*) I.getKey() << ") ";
339 LangOptions LO; // FIXME.
340 I.getKey()->printPretty(Out, 0, PrintingPolicy(LO));
341 Out << " : " << I.getData();
344 // Print block-expression bindings.
345 isFirst = true;
347 for (Environment::iterator I = Env.begin(), E = Env.end(); I != E; ++I) {
348 if (!C.isBlkExpr(I.getKey()))
349 continue;
351 if (isFirst) {
352 Out << nl << nl << "Block-level Expressions:" << nl;
353 isFirst = false;
355 else { Out << nl; }
357 Out << " (" << (void*) I.getKey() << ") ";
358 LangOptions LO; // FIXME.
359 I.getKey()->printPretty(Out, 0, PrintingPolicy(LO));
360 Out << " : " << I.getData();
363 // Print locations.
364 isFirst = true;
366 for (Environment::iterator I = Env.begin(), E = Env.end(); I != E; ++I) {
367 if (!IsEnvLoc(I.getKey()))
368 continue;
370 if (isFirst) {
371 Out << nl << nl << "Load/store locations:" << nl;
372 isFirst = false;
374 else { Out << nl; }
376 const Stmt *S = (Stmt*) (((uintptr_t) I.getKey()) & ((uintptr_t) ~0x1));
378 Out << " (" << (void*) S << ") ";
379 LangOptions LO; // FIXME.
380 S->printPretty(Out, 0, PrintingPolicy(LO));
381 Out << " : " << I.getData();
384 Mgr.getConstraintManager().print(this, Out, nl, sep);
386 // Print checker-specific data.
387 for (std::vector<Printer*>::iterator I = Mgr.Printers.begin(),
388 E = Mgr.Printers.end(); I != E; ++I) {
389 (*I)->Print(Out, this, nl, sep);
393 void GRState::printDOT(llvm::raw_ostream& Out, CFG &C) const {
394 print(Out, C, "\\l", "\\|");
397 void GRState::printStdErr(CFG &C) const {
398 print(llvm::errs(), C);
401 //===----------------------------------------------------------------------===//
402 // Generic Data Map.
403 //===----------------------------------------------------------------------===//
405 void* const* GRState::FindGDM(void* K) const {
406 return GDM.lookup(K);
409 void*
410 GRStateManager::FindGDMContext(void* K,
411 void* (*CreateContext)(llvm::BumpPtrAllocator&),
412 void (*DeleteContext)(void*)) {
414 std::pair<void*, void (*)(void*)>& p = GDMContexts[K];
415 if (!p.first) {
416 p.first = CreateContext(Alloc);
417 p.second = DeleteContext;
420 return p.first;
423 const GRState* GRStateManager::addGDM(const GRState* St, void* Key, void* Data){
424 GRState::GenericDataMap M1 = St->getGDM();
425 GRState::GenericDataMap M2 = GDMFactory.add(M1, Key, Data);
427 if (M1 == M2)
428 return St;
430 GRState NewSt = *St;
431 NewSt.GDM = M2;
432 return getPersistentState(NewSt);
435 const GRState *GRStateManager::removeGDM(const GRState *state, void *Key) {
436 GRState::GenericDataMap OldM = state->getGDM();
437 GRState::GenericDataMap NewM = GDMFactory.remove(OldM, Key);
439 if (NewM == OldM)
440 return state;
442 GRState NewState = *state;
443 NewState.GDM = NewM;
444 return getPersistentState(NewState);
447 //===----------------------------------------------------------------------===//
448 // Utility.
449 //===----------------------------------------------------------------------===//
451 namespace {
452 class ScanReachableSymbols : public SubRegionMap::Visitor {
453 typedef llvm::DenseSet<const MemRegion*> VisitedRegionsTy;
455 VisitedRegionsTy visited;
456 const GRState *state;
457 SymbolVisitor &visitor;
458 llvm::OwningPtr<SubRegionMap> SRM;
459 public:
461 ScanReachableSymbols(const GRState *st, SymbolVisitor& v)
462 : state(st), visitor(v) {}
464 bool scan(nonloc::CompoundVal val);
465 bool scan(SVal val);
466 bool scan(const MemRegion *R);
468 // From SubRegionMap::Visitor.
469 bool Visit(const MemRegion* Parent, const MemRegion* SubRegion) {
470 return scan(SubRegion);
475 bool ScanReachableSymbols::scan(nonloc::CompoundVal val) {
476 for (nonloc::CompoundVal::iterator I=val.begin(), E=val.end(); I!=E; ++I)
477 if (!scan(*I))
478 return false;
480 return true;
483 bool ScanReachableSymbols::scan(SVal val) {
484 if (loc::MemRegionVal *X = dyn_cast<loc::MemRegionVal>(&val))
485 return scan(X->getRegion());
487 if (nonloc::LocAsInteger *X = dyn_cast<nonloc::LocAsInteger>(&val))
488 return scan(X->getLoc());
490 if (SymbolRef Sym = val.getAsSymbol())
491 return visitor.VisitSymbol(Sym);
493 if (nonloc::CompoundVal *X = dyn_cast<nonloc::CompoundVal>(&val))
494 return scan(*X);
496 return true;
499 bool ScanReachableSymbols::scan(const MemRegion *R) {
500 if (isa<MemSpaceRegion>(R) || visited.count(R))
501 return true;
503 visited.insert(R);
505 // If this is a symbolic region, visit the symbol for the region.
506 if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(R))
507 if (!visitor.VisitSymbol(SR->getSymbol()))
508 return false;
510 // If this is a subregion, also visit the parent regions.
511 if (const SubRegion *SR = dyn_cast<SubRegion>(R))
512 if (!scan(SR->getSuperRegion()))
513 return false;
515 // Now look at the binding to this region (if any).
516 if (!scan(state->getSValAsScalarOrLoc(R)))
517 return false;
519 // Now look at the subregions.
520 if (!SRM.get())
521 SRM.reset(state->getStateManager().getStoreManager().
522 getSubRegionMap(state->getStore()));
524 return SRM->iterSubRegions(R, *this);
527 bool GRState::scanReachableSymbols(SVal val, SymbolVisitor& visitor) const {
528 ScanReachableSymbols S(this, visitor);
529 return S.scan(val);
532 bool GRState::scanReachableSymbols(const SVal *I, const SVal *E,
533 SymbolVisitor &visitor) const {
534 ScanReachableSymbols S(this, visitor);
535 for ( ; I != E; ++I) {
536 if (!S.scan(*I))
537 return false;
539 return true;
542 bool GRState::scanReachableSymbols(const MemRegion * const *I,
543 const MemRegion * const *E,
544 SymbolVisitor &visitor) const {
545 ScanReachableSymbols S(this, visitor);
546 for ( ; I != E; ++I) {
547 if (!S.scan(*I))
548 return false;
550 return true;