blob: 7004c5558e42b955d5ae63d4607c7f8c19db6726 [file] [log] [blame]
Zhongxing Xu79c57f82008-10-08 02:50:44 +00001//== RegionStore.cpp - Field-sensitive store model --------------*- 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 a basic region store model. In this model, we do have field
11// sensitivity. But we assume nothing about the heap shape. So recursive data
12// structures are largely ignored. Basically we do 1-limiting analysis.
13// Parameter pointers are assumed with no aliasing. Pointee objects of
14// parameters are created lazily.
15//
16//===----------------------------------------------------------------------===//
17#include "clang/Analysis/PathSensitive/MemRegion.h"
18#include "clang/Analysis/PathSensitive/GRState.h"
19#include "clang/Analysis/Analyses/LiveVariables.h"
20
21#include "llvm/ADT/ImmutableMap.h"
22#include "llvm/Support/Compiler.h"
23
24using namespace clang;
25
26typedef llvm::ImmutableMap<const MemRegion*, RVal> RegionBindingsTy;
27
28namespace {
29
30class VISIBILITY_HIDDEN RegionStoreManager : public StoreManager {
31 RegionBindingsTy::Factory RBFactory;
32 GRStateManager& StateMgr;
33 MemRegionManager MRMgr;
34
35public:
36 RegionStoreManager(GRStateManager& mgr)
37 : StateMgr(mgr), MRMgr(StateMgr.getAllocator()) {}
38
39 virtual ~RegionStoreManager() {}
40
41 Store SetRVal(Store St, LVal LV, RVal V);
42
43 Store getInitialStore();
44
45 static inline RegionBindingsTy GetRegionBindings(Store store) {
46 return RegionBindingsTy(static_cast<const RegionBindingsTy::TreeTy*>(store));
47 }
48};
49
50} // end anonymous namespace
51
52Store RegionStoreManager::SetRVal(Store store, LVal LV, RVal V) {
53 assert(LV.getSubKind() == lval::MemRegionKind);
54
55 MemRegion* R = cast<lval::MemRegionVal>(LV).getRegion();
56
57 if (!R)
58 return store;
59
60 RegionBindingsTy B = GetRegionBindings(store);
61 return V.isUnknown()
62 ? RBFactory.Remove(B, R).getRoot()
63 : RBFactory.Add(B, R, V).getRoot();
64}
65
66Store RegionStoreManager::getInitialStore() {
67 typedef LiveVariables::AnalysisDataTy LVDataTy;
68 LVDataTy& D = StateMgr.getLiveVariables().getAnalysisData();
69
70 Store St = RBFactory.GetEmptyMap().getRoot();
71
72 for (LVDataTy::decl_iterator I=D.begin_decl(), E=D.end_decl(); I != E; ++I) {
73 ScopedDecl* SD = const_cast<ScopedDecl*>(I->first);
74
75 if (VarDecl* VD = dyn_cast<VarDecl>(SD)) {
76 // Punt on static variables for now.
77 if (VD->getStorageClass() == VarDecl::Static)
78 continue;
79
80 QualType T = VD->getType();
81 // Only handle pointers and integers for now.
82 if (LVal::IsLValType(T) || T->isIntegerType()) {
83 MemRegion* R = MRMgr.getVarRegion(VD);
84 // Initialize globals and parameters to symbolic values.
85 // Initialize local variables to undefined.
86 RVal X = (VD->hasGlobalStorage() || isa<ParmVarDecl>(VD) ||
87 isa<ImplicitParamDecl>(VD))
88 ? RVal::GetSymbolValue(StateMgr.getSymbolManager(), VD)
89 : UndefinedVal();
90
91 St = SetRVal(St, lval::MemRegionVal(R), X);
92 }
93 }
94 }
95 return St;
96}