blob: 6757f43ae1062b5ca4819e2f82b38fcb57bbf69e [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
Zhongxing Xu097fc982008-10-17 05:57:07 +000026typedef llvm::ImmutableMap<const MemRegion*, SVal> RegionBindingsTy;
Zhongxing Xu79c57f82008-10-08 02:50:44 +000027
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
Zhongxing Xu097fc982008-10-17 05:57:07 +000041 Store SetSVal(Store St, Loc LV, SVal V);
Zhongxing Xu79c57f82008-10-08 02:50:44 +000042
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
Zhongxing Xu097fc982008-10-17 05:57:07 +000052Store RegionStoreManager::SetSVal(Store store, Loc LV, SVal V) {
53 assert(LV.getSubKind() == loc::MemRegionKind);
Zhongxing Xu79c57f82008-10-08 02:50:44 +000054
Zhongxing Xu097fc982008-10-17 05:57:07 +000055 MemRegion* R = cast<loc::MemRegionVal>(LV).getRegion();
Zhongxing Xu79c57f82008-10-08 02:50:44 +000056
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.
Zhongxing Xu097fc982008-10-17 05:57:07 +000082 if (Loc::IsLocType(T) || T->isIntegerType()) {
Zhongxing Xu79c57f82008-10-08 02:50:44 +000083 MemRegion* R = MRMgr.getVarRegion(VD);
84 // Initialize globals and parameters to symbolic values.
85 // Initialize local variables to undefined.
Zhongxing Xu097fc982008-10-17 05:57:07 +000086 SVal X = (VD->hasGlobalStorage() || isa<ParmVarDecl>(VD) ||
Zhongxing Xu79c57f82008-10-08 02:50:44 +000087 isa<ImplicitParamDecl>(VD))
Zhongxing Xu097fc982008-10-17 05:57:07 +000088 ? SVal::GetSymbolValue(StateMgr.getSymbolManager(), VD)
Zhongxing Xu79c57f82008-10-08 02:50:44 +000089 : UndefinedVal();
90
Zhongxing Xu097fc982008-10-17 05:57:07 +000091 St = SetSVal(St, loc::MemRegionVal(R), X);
Zhongxing Xu79c57f82008-10-08 02:50:44 +000092 }
93 }
94 }
95 return St;
96}