blob: 5dad3560f0a1883873df5e1774b6864acb5ea2b9 [file] [log] [blame]
Ted Kremenek9e240492008-10-04 05:50:14 +00001//== MemRegion.cpp - Abstract memory regions for static analysis --*- 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 MemRegion and its subclasses. MemRegion defines a
11// partially-typed abstraction of memory useful for path-sensitive dataflow
12// analyses.
13//
14//===----------------------------------------------------------------------===//
15
16#include "llvm/Support/raw_ostream.h"
17#include "clang/Analysis/PathSensitive/MemRegion.h"
18
19using namespace clang;
20
21
22MemRegion::~MemRegion() {}
23
24void MemSpaceRegion::Profile(llvm::FoldingSetNodeID& ID) const {
25 ID.AddInteger((unsigned)getKind());
26}
27
28void AnonTypedRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, QualType T,
29 const MemRegion* superRegion) {
30 ID.AddInteger((unsigned) AnonTypedRegionKind);
31 ID.Add(T);
32 ID.AddPointer(superRegion);
33}
34
Zhongxing Xu17892752008-10-08 02:50:44 +000035void AnonPointeeRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
36 const VarDecl* VD, QualType T,
37 const MemRegion* superRegion) {
38 ID.AddInteger((unsigned) AnonPointeeRegionKind);
39 ID.Add(T);
40 ID.AddPointer(VD);
41 ID.AddPointer(superRegion);
42}
43
Ted Kremenek9e240492008-10-04 05:50:14 +000044void AnonTypedRegion::Profile(llvm::FoldingSetNodeID& ID) const {
45 AnonTypedRegion::ProfileRegion(ID, T, superRegion);
46}
47
48void DeclRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, const Decl* D,
49 const MemRegion* superRegion, Kind k) {
50 ID.AddInteger((unsigned) k);
51 ID.AddPointer(D);
52 ID.AddPointer(superRegion);
53}
54
55void DeclRegion::Profile(llvm::FoldingSetNodeID& ID) const {
56 DeclRegion::ProfileRegion(ID, D, superRegion, getKind());
57}
58
Ted Kremenek993f1c72008-10-17 20:28:54 +000059void SymbolicRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, SymbolID sym) {
60 ID.AddInteger((unsigned) MemRegion::SymbolicRegionKind);
61 ID.AddInteger(sym.getNumber());
62}
63
64void SymbolicRegion::Profile(llvm::FoldingSetNodeID& ID) const {
65 SymbolicRegion::ProfileRegion(ID, sym);
66}
67
Zhongxing Xu511191c2008-10-21 05:27:10 +000068void ElementRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, SVal Idx,
69 const MemRegion* superRegion) {
70 ID.AddInteger(MemRegion::ElementRegionKind);
71 ID.AddPointer(superRegion);
72 Idx.Profile(ID);
73}
74
75void ElementRegion::Profile(llvm::FoldingSetNodeID& ID) const {
76 ElementRegion::ProfileRegion(ID, Index, superRegion);
77}
Ted Kremenek9e240492008-10-04 05:50:14 +000078//===----------------------------------------------------------------------===//
79// Region pretty-printing.
80//===----------------------------------------------------------------------===//
81
82std::string MemRegion::getString() const {
83 std::string s;
84 llvm::raw_string_ostream os(s);
85 print(os);
86 return os.str();
87}
88
89void MemRegion::print(llvm::raw_ostream& os) const {
90 os << "<Unknown Region>";
91}
92
93void VarRegion::print(llvm::raw_ostream& os) const {
94 os << cast<VarDecl>(D)->getName();
95}
96
Ted Kremenek993f1c72008-10-17 20:28:54 +000097void SymbolicRegion::print(llvm::raw_ostream& os) const {
98 os << "$" << sym.getNumber();
99}
100
Ted Kremenek4bd1eef2008-10-17 21:05:44 +0000101void FieldRegion::print(llvm::raw_ostream& os) const {
102 superRegion->print(os);
103 os << "->" << getDecl()->getName();
104}
105
Zhongxing Xub21ff772008-10-24 06:30:07 +0000106void ElementRegion::print(llvm::raw_ostream& os) const {
107 superRegion->print(os);
108 os << '['; Index.print(os); os << ']';
109}
110
Ted Kremenek9e240492008-10-04 05:50:14 +0000111//===----------------------------------------------------------------------===//
112// MemRegionManager methods.
113//===----------------------------------------------------------------------===//
114
115MemSpaceRegion* MemRegionManager::LazyAllocate(MemSpaceRegion*& region) {
116
117 if (!region) {
118 region = (MemSpaceRegion*) A.Allocate<MemSpaceRegion>();
119 new (region) MemSpaceRegion();
120 }
121
122 return region;
123}
124
125MemSpaceRegion* MemRegionManager::getStackRegion() {
126 return LazyAllocate(stack);
127}
128
129MemSpaceRegion* MemRegionManager::getGlobalsRegion() {
130 return LazyAllocate(globals);
131}
132
133MemSpaceRegion* MemRegionManager::getHeapRegion() {
134 return LazyAllocate(heap);
135}
136
Zhongxing Xu17892752008-10-08 02:50:44 +0000137MemSpaceRegion* MemRegionManager::getUnknownRegion() {
138 return LazyAllocate(unknown);
139}
140
Ted Kremenek9e240492008-10-04 05:50:14 +0000141VarRegion* MemRegionManager::getVarRegion(const VarDecl* d,
Ted Kremenek993f1c72008-10-17 20:28:54 +0000142 const MemRegion* superRegion) {
Ted Kremenek9e240492008-10-04 05:50:14 +0000143 llvm::FoldingSetNodeID ID;
144 DeclRegion::ProfileRegion(ID, d, superRegion, MemRegion::VarRegionKind);
145
146 void* InsertPos;
147 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
148 VarRegion* R = cast_or_null<VarRegion>(data);
149
150 if (!R) {
151 R = (VarRegion*) A.Allocate<VarRegion>();
152 new (R) VarRegion(d, superRegion);
153 Regions.InsertNode(R, InsertPos);
154 }
155
156 return R;
157}
158
Zhongxing Xu511191c2008-10-21 05:27:10 +0000159ElementRegion* MemRegionManager::getElementRegion(SVal Idx,
160 const MemRegion* superRegion){
161 llvm::FoldingSetNodeID ID;
162 ElementRegion::ProfileRegion(ID, Idx, superRegion);
163
164 void* InsertPos;
165 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
166 ElementRegion* R = cast_or_null<ElementRegion>(data);
167
168 if (!R) {
169 R = (ElementRegion*) A.Allocate<ElementRegion>();
170 new (R) ElementRegion(Idx, superRegion);
171 Regions.InsertNode(R, InsertPos);
172 }
173
174 return R;
175}
176
Ted Kremenek993f1c72008-10-17 20:28:54 +0000177/// getSymbolicRegion - Retrieve or create a "symbolic" memory region.
178SymbolicRegion* MemRegionManager::getSymbolicRegion(const SymbolID sym) {
179
180 llvm::FoldingSetNodeID ID;
181 SymbolicRegion::ProfileRegion(ID, sym);
182
183 void* InsertPos;
184 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
185 SymbolicRegion* R = cast_or_null<SymbolicRegion>(data);
186
187 if (!R) {
188 R = (SymbolicRegion*) A.Allocate<SymbolicRegion>();
189 new (R) SymbolicRegion(sym);
190 Regions.InsertNode(R, InsertPos);
191 }
192
193 return R;
194}
195
Ted Kremenek9e240492008-10-04 05:50:14 +0000196FieldRegion* MemRegionManager::getFieldRegion(const FieldDecl* d,
Ted Kremenek993f1c72008-10-17 20:28:54 +0000197 const MemRegion* superRegion) {
Ted Kremenek9e240492008-10-04 05:50:14 +0000198 llvm::FoldingSetNodeID ID;
199 DeclRegion::ProfileRegion(ID, d, superRegion, MemRegion::FieldRegionKind);
200
201 void* InsertPos;
202 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
203 FieldRegion* R = cast_or_null<FieldRegion>(data);
204
205 if (!R) {
206 R = (FieldRegion*) A.Allocate<FieldRegion>();
207 new (R) FieldRegion(d, superRegion);
208 Regions.InsertNode(R, InsertPos);
209 }
210
211 return R;
212}
213
Ted Kremenek993f1c72008-10-17 20:28:54 +0000214ObjCIvarRegion*
215MemRegionManager::getObjCIvarRegion(const ObjCIvarDecl* d,
216 const MemRegion* superRegion) {
Ted Kremenek9e240492008-10-04 05:50:14 +0000217 llvm::FoldingSetNodeID ID;
218 DeclRegion::ProfileRegion(ID, d, superRegion, MemRegion::ObjCIvarRegionKind);
219
220 void* InsertPos;
221 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
222 ObjCIvarRegion* R = cast_or_null<ObjCIvarRegion>(data);
223
224 if (!R) {
Zhongxing Xu722c2882008-10-06 03:03:33 +0000225 R = (ObjCIvarRegion*) A.Allocate<ObjCIvarRegion>();
226 new (R) ObjCIvarRegion(d, superRegion);
Ted Kremenek9e240492008-10-04 05:50:14 +0000227 Regions.InsertNode(R, InsertPos);
228 }
229
230 return R;
231}
232
Ted Kremeneka7f1b9e2008-10-24 20:30:08 +0000233ObjCObjectRegion*
234MemRegionManager::getObjCObjectRegion(const ObjCInterfaceDecl* d,
235 const MemRegion* superRegion) {
236 llvm::FoldingSetNodeID ID;
237 DeclRegion::ProfileRegion(ID, d, superRegion,
238 MemRegion::ObjCObjectRegionKind);
239
240 void* InsertPos;
241 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
242 ObjCObjectRegion* R = cast_or_null<ObjCObjectRegion>(data);
243
244 if (!R) {
245 R = (ObjCObjectRegion*) A.Allocate<ObjCObjectRegion>();
246 new (R) ObjCObjectRegion(d, superRegion);
247 Regions.InsertNode(R, InsertPos);
248 }
249
250 return R;
251}
252
253
Zhongxing Xu17892752008-10-08 02:50:44 +0000254AnonPointeeRegion* MemRegionManager::getAnonPointeeRegion(const VarDecl* d) {
255 llvm::FoldingSetNodeID ID;
256 QualType T = d->getType();
257 QualType PointeeType = cast<PointerType>(T.getTypePtr())->getPointeeType();
258 MemRegion* superRegion = getUnknownRegion();
259
260 AnonPointeeRegion::ProfileRegion(ID, d, PointeeType, superRegion);
261
262 void* InsertPos;
263 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
264 AnonPointeeRegion* R = cast_or_null<AnonPointeeRegion>(data);
265
266 if (!R) {
267 R = (AnonPointeeRegion*) A.Allocate<AnonPointeeRegion>();
268 new (R) AnonPointeeRegion(d, PointeeType, superRegion);
269 Regions.InsertNode(R, InsertPos);
270 }
271
272 return R;
273}
274
Ted Kremenek9e240492008-10-04 05:50:14 +0000275bool MemRegionManager::hasStackStorage(const MemRegion* R) {
Ted Kremenek993f1c72008-10-17 20:28:54 +0000276 const SubRegion* SR = dyn_cast<SubRegion>(R);
277
278 // Only subregions can have stack storage.
279 if (!SR)
280 return false;
281
Ted Kremenek9e240492008-10-04 05:50:14 +0000282 MemSpaceRegion* S = getStackRegion();
283
Ted Kremenek993f1c72008-10-17 20:28:54 +0000284 while (SR) {
285 R = SR->getSuperRegion();
286 if (R == S)
287 return true;
288
289 SR = dyn_cast<SubRegion>(R);
Ted Kremenek9e240492008-10-04 05:50:14 +0000290 }
291
292 return false;
293}