blob: 14da4db990b4f07a5371faf553a771fe4ad0f219 [file] [log] [blame]
Ted Kremenekb15eba42008-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
Zhongxing Xu73507bd2008-10-25 14:13:41 +000028void StringRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
29 const StringLiteral* Str,
30 const MemRegion* superRegion) {
31 ID.AddInteger((unsigned) StringRegionKind);
32 ID.AddPointer(Str);
33 ID.AddPointer(superRegion);
34}
35
Ted Kremenekea9ca502008-11-02 00:34:33 +000036void AllocaRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
37 const Expr* Ex, unsigned cnt) {
38 ID.AddInteger((unsigned) AllocaRegionKind);
39 ID.AddPointer(Ex);
40 ID.AddInteger(cnt);
41}
42
43void AllocaRegion::Profile(llvm::FoldingSetNodeID& ID) const {
44 ProfileRegion(ID, Ex, Cnt);
45}
46
Ted Kremenekb15eba42008-10-04 05:50:14 +000047void AnonTypedRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, QualType T,
48 const MemRegion* superRegion) {
49 ID.AddInteger((unsigned) AnonTypedRegionKind);
50 ID.Add(T);
51 ID.AddPointer(superRegion);
52}
53
Zhongxing Xu79c57f82008-10-08 02:50:44 +000054void AnonPointeeRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
55 const VarDecl* VD, QualType T,
56 const MemRegion* superRegion) {
57 ID.AddInteger((unsigned) AnonPointeeRegionKind);
58 ID.Add(T);
59 ID.AddPointer(VD);
60 ID.AddPointer(superRegion);
61}
62
Ted Kremenekb15eba42008-10-04 05:50:14 +000063void AnonTypedRegion::Profile(llvm::FoldingSetNodeID& ID) const {
64 AnonTypedRegion::ProfileRegion(ID, T, superRegion);
65}
66
Ted Kremenek6bc91b92008-10-27 20:57:58 +000067void CompoundLiteralRegion::Profile(llvm::FoldingSetNodeID& ID) const {
68 CompoundLiteralRegion::ProfileRegion(ID, CL, superRegion);
69}
70
71void CompoundLiteralRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
72 const CompoundLiteralExpr* CL,
73 const MemRegion* superRegion) {
74 ID.AddInteger((unsigned) CompoundLiteralRegionKind);
75 ID.AddPointer(CL);
76 ID.AddPointer(superRegion);
77}
78
Ted Kremenekb15eba42008-10-04 05:50:14 +000079void DeclRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, const Decl* D,
80 const MemRegion* superRegion, Kind k) {
81 ID.AddInteger((unsigned) k);
82 ID.AddPointer(D);
83 ID.AddPointer(superRegion);
84}
85
86void DeclRegion::Profile(llvm::FoldingSetNodeID& ID) const {
87 DeclRegion::ProfileRegion(ID, D, superRegion, getKind());
88}
89
Ted Kremenek38a4b4b2008-10-17 20:28:54 +000090void SymbolicRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, SymbolID sym) {
91 ID.AddInteger((unsigned) MemRegion::SymbolicRegionKind);
92 ID.AddInteger(sym.getNumber());
93}
94
95void SymbolicRegion::Profile(llvm::FoldingSetNodeID& ID) const {
96 SymbolicRegion::ProfileRegion(ID, sym);
97}
98
Zhongxing Xu54969732008-10-21 05:27:10 +000099void ElementRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, SVal Idx,
100 const MemRegion* superRegion) {
101 ID.AddInteger(MemRegion::ElementRegionKind);
102 ID.AddPointer(superRegion);
103 Idx.Profile(ID);
104}
105
106void ElementRegion::Profile(llvm::FoldingSetNodeID& ID) const {
107 ElementRegion::ProfileRegion(ID, Index, superRegion);
108}
Zhongxing Xu1a563da2008-10-27 13:17:02 +0000109
110QualType ElementRegion::getType(ASTContext& C) const {
111 QualType T = cast<TypedRegion>(superRegion)->getType(C);
112 ArrayType* AT = cast<ArrayType>(T.getTypePtr());
113 return AT->getElementType();
114}
115
Ted Kremenekb15eba42008-10-04 05:50:14 +0000116//===----------------------------------------------------------------------===//
117// Region pretty-printing.
118//===----------------------------------------------------------------------===//
119
120std::string MemRegion::getString() const {
121 std::string s;
122 llvm::raw_string_ostream os(s);
123 print(os);
124 return os.str();
125}
126
127void MemRegion::print(llvm::raw_ostream& os) const {
128 os << "<Unknown Region>";
129}
130
Ted Kremenekea9ca502008-11-02 00:34:33 +0000131void AllocaRegion::print(llvm::raw_ostream& os) const {
132 os << "alloca{" << (void*) Ex << ',' << Cnt << '}';
133}
134
Ted Kremenekb15eba42008-10-04 05:50:14 +0000135void VarRegion::print(llvm::raw_ostream& os) const {
136 os << cast<VarDecl>(D)->getName();
137}
138
Ted Kremenek38a4b4b2008-10-17 20:28:54 +0000139void SymbolicRegion::print(llvm::raw_ostream& os) const {
140 os << "$" << sym.getNumber();
141}
142
Ted Kremenekdea0c6b2008-10-17 21:05:44 +0000143void FieldRegion::print(llvm::raw_ostream& os) const {
144 superRegion->print(os);
145 os << "->" << getDecl()->getName();
146}
147
Zhongxing Xu74a4e3a2008-10-24 06:30:07 +0000148void ElementRegion::print(llvm::raw_ostream& os) const {
149 superRegion->print(os);
150 os << '['; Index.print(os); os << ']';
151}
152
Ted Kremenek6bc91b92008-10-27 20:57:58 +0000153void CompoundLiteralRegion::print(llvm::raw_ostream& os) const {
154 // FIXME: More elaborate pretty-printing.
155 os << "{ " << (void*) CL << " }";
156}
157
Ted Kremenekb15eba42008-10-04 05:50:14 +0000158//===----------------------------------------------------------------------===//
159// MemRegionManager methods.
160//===----------------------------------------------------------------------===//
161
162MemSpaceRegion* MemRegionManager::LazyAllocate(MemSpaceRegion*& region) {
163
164 if (!region) {
165 region = (MemSpaceRegion*) A.Allocate<MemSpaceRegion>();
166 new (region) MemSpaceRegion();
167 }
168
169 return region;
170}
171
172MemSpaceRegion* MemRegionManager::getStackRegion() {
173 return LazyAllocate(stack);
174}
175
176MemSpaceRegion* MemRegionManager::getGlobalsRegion() {
177 return LazyAllocate(globals);
178}
179
180MemSpaceRegion* MemRegionManager::getHeapRegion() {
181 return LazyAllocate(heap);
182}
183
Zhongxing Xu79c57f82008-10-08 02:50:44 +0000184MemSpaceRegion* MemRegionManager::getUnknownRegion() {
185 return LazyAllocate(unknown);
186}
187
Zhongxing Xu73507bd2008-10-25 14:13:41 +0000188StringRegion* MemRegionManager::getStringRegion(const StringLiteral* Str) {
189 llvm::FoldingSetNodeID ID;
190 MemSpaceRegion* GlobalsR = getGlobalsRegion();
191
192 StringRegion::ProfileRegion(ID, Str, GlobalsR);
193
194 void* InsertPos;
195 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
196 StringRegion* R = cast_or_null<StringRegion>(data);
197
198 if (!R) {
199 R = (StringRegion*) A.Allocate<StringRegion>();
200 new (R) StringRegion(Str, GlobalsR);
201 Regions.InsertNode(R, InsertPos);
202 }
203
204 return R;
205}
206
Ted Kremenek81329ab2008-10-27 21:01:26 +0000207VarRegion* MemRegionManager::getVarRegion(const VarDecl* d) {
208
209 const MemRegion* superRegion = d->hasLocalStorage() ? getStackRegion()
210 : getGlobalsRegion();
211
Ted Kremenekb15eba42008-10-04 05:50:14 +0000212 llvm::FoldingSetNodeID ID;
213 DeclRegion::ProfileRegion(ID, d, superRegion, MemRegion::VarRegionKind);
214
215 void* InsertPos;
216 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
217 VarRegion* R = cast_or_null<VarRegion>(data);
218
219 if (!R) {
220 R = (VarRegion*) A.Allocate<VarRegion>();
221 new (R) VarRegion(d, superRegion);
222 Regions.InsertNode(R, InsertPos);
223 }
224
225 return R;
226}
227
Ted Kremenek6bc91b92008-10-27 20:57:58 +0000228CompoundLiteralRegion*
229MemRegionManager::getCompoundLiteralRegion(const CompoundLiteralExpr* CL) {
230 // Is this compound literal allocated on the stack or is part of the
231 // global constant pool?
232 const MemRegion* superRegion = CL->isFileScope() ?
233 getGlobalsRegion() : getStackRegion();
234
235 // Profile the compound literal.
236 llvm::FoldingSetNodeID ID;
237 CompoundLiteralRegion::ProfileRegion(ID, CL, superRegion);
238
239 void* InsertPos;
240 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
241 CompoundLiteralRegion* R = cast_or_null<CompoundLiteralRegion>(data);
242
243 if (!R) {
244 R = (CompoundLiteralRegion*) A.Allocate<CompoundLiteralRegion>();
245 new (R) CompoundLiteralRegion(CL, superRegion);
246 Regions.InsertNode(R, InsertPos);
247 }
248
249 return R;
250}
251
Zhongxing Xu54969732008-10-21 05:27:10 +0000252ElementRegion* MemRegionManager::getElementRegion(SVal Idx,
253 const MemRegion* superRegion){
254 llvm::FoldingSetNodeID ID;
255 ElementRegion::ProfileRegion(ID, Idx, superRegion);
256
257 void* InsertPos;
258 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
259 ElementRegion* R = cast_or_null<ElementRegion>(data);
260
261 if (!R) {
262 R = (ElementRegion*) A.Allocate<ElementRegion>();
263 new (R) ElementRegion(Idx, superRegion);
264 Regions.InsertNode(R, InsertPos);
265 }
266
267 return R;
268}
269
Ted Kremenek38a4b4b2008-10-17 20:28:54 +0000270/// getSymbolicRegion - Retrieve or create a "symbolic" memory region.
271SymbolicRegion* MemRegionManager::getSymbolicRegion(const SymbolID sym) {
272
273 llvm::FoldingSetNodeID ID;
274 SymbolicRegion::ProfileRegion(ID, sym);
275
276 void* InsertPos;
277 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
278 SymbolicRegion* R = cast_or_null<SymbolicRegion>(data);
279
280 if (!R) {
281 R = (SymbolicRegion*) A.Allocate<SymbolicRegion>();
282 new (R) SymbolicRegion(sym);
283 Regions.InsertNode(R, InsertPos);
284 }
285
286 return R;
287}
288
Ted Kremenekb15eba42008-10-04 05:50:14 +0000289FieldRegion* MemRegionManager::getFieldRegion(const FieldDecl* d,
Ted Kremenek38a4b4b2008-10-17 20:28:54 +0000290 const MemRegion* superRegion) {
Ted Kremenekb15eba42008-10-04 05:50:14 +0000291 llvm::FoldingSetNodeID ID;
292 DeclRegion::ProfileRegion(ID, d, superRegion, MemRegion::FieldRegionKind);
293
294 void* InsertPos;
295 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
296 FieldRegion* R = cast_or_null<FieldRegion>(data);
297
298 if (!R) {
299 R = (FieldRegion*) A.Allocate<FieldRegion>();
300 new (R) FieldRegion(d, superRegion);
301 Regions.InsertNode(R, InsertPos);
302 }
303
304 return R;
305}
306
Ted Kremenek38a4b4b2008-10-17 20:28:54 +0000307ObjCIvarRegion*
308MemRegionManager::getObjCIvarRegion(const ObjCIvarDecl* d,
309 const MemRegion* superRegion) {
Ted Kremenekb15eba42008-10-04 05:50:14 +0000310 llvm::FoldingSetNodeID ID;
311 DeclRegion::ProfileRegion(ID, d, superRegion, MemRegion::ObjCIvarRegionKind);
312
313 void* InsertPos;
314 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
315 ObjCIvarRegion* R = cast_or_null<ObjCIvarRegion>(data);
316
317 if (!R) {
Zhongxing Xu7a861e82008-10-06 03:03:33 +0000318 R = (ObjCIvarRegion*) A.Allocate<ObjCIvarRegion>();
319 new (R) ObjCIvarRegion(d, superRegion);
Ted Kremenekb15eba42008-10-04 05:50:14 +0000320 Regions.InsertNode(R, InsertPos);
321 }
322
323 return R;
324}
325
Ted Kremenek2539c112008-10-24 20:30:08 +0000326ObjCObjectRegion*
327MemRegionManager::getObjCObjectRegion(const ObjCInterfaceDecl* d,
328 const MemRegion* superRegion) {
329 llvm::FoldingSetNodeID ID;
330 DeclRegion::ProfileRegion(ID, d, superRegion,
331 MemRegion::ObjCObjectRegionKind);
332
333 void* InsertPos;
334 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
335 ObjCObjectRegion* R = cast_or_null<ObjCObjectRegion>(data);
336
337 if (!R) {
338 R = (ObjCObjectRegion*) A.Allocate<ObjCObjectRegion>();
339 new (R) ObjCObjectRegion(d, superRegion);
340 Regions.InsertNode(R, InsertPos);
341 }
342
343 return R;
344}
345
346
Zhongxing Xu79c57f82008-10-08 02:50:44 +0000347AnonPointeeRegion* MemRegionManager::getAnonPointeeRegion(const VarDecl* d) {
348 llvm::FoldingSetNodeID ID;
349 QualType T = d->getType();
350 QualType PointeeType = cast<PointerType>(T.getTypePtr())->getPointeeType();
351 MemRegion* superRegion = getUnknownRegion();
352
353 AnonPointeeRegion::ProfileRegion(ID, d, PointeeType, superRegion);
354
355 void* InsertPos;
356 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
357 AnonPointeeRegion* R = cast_or_null<AnonPointeeRegion>(data);
358
359 if (!R) {
360 R = (AnonPointeeRegion*) A.Allocate<AnonPointeeRegion>();
361 new (R) AnonPointeeRegion(d, PointeeType, superRegion);
362 Regions.InsertNode(R, InsertPos);
363 }
364
365 return R;
366}
367
Ted Kremenekea9ca502008-11-02 00:34:33 +0000368AllocaRegion* MemRegionManager::getAllocaRegion(const Expr* E, unsigned cnt) {
369 llvm::FoldingSetNodeID ID;
370 AllocaRegion::ProfileRegion(ID, E, cnt);
371
372 void* InsertPos;
373 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
374 AllocaRegion* R = cast_or_null<AllocaRegion>(data);
375
376 if (!R) {
377 R = (AllocaRegion*) A.Allocate<AllocaRegion>();
378 new (R) AllocaRegion(E, cnt, getStackRegion());
379 Regions.InsertNode(R, InsertPos);
380 }
381
382 return R;
383}
384
Ted Kremenekb15eba42008-10-04 05:50:14 +0000385bool MemRegionManager::hasStackStorage(const MemRegion* R) {
Ted Kremenek38a4b4b2008-10-17 20:28:54 +0000386
387 // Only subregions can have stack storage.
Ted Kremenekea9ca502008-11-02 00:34:33 +0000388 const SubRegion* SR = dyn_cast<SubRegion>(R);
389
Ted Kremenek38a4b4b2008-10-17 20:28:54 +0000390 if (!SR)
391 return false;
Ted Kremenekea9ca502008-11-02 00:34:33 +0000392
Ted Kremenekb15eba42008-10-04 05:50:14 +0000393 MemSpaceRegion* S = getStackRegion();
394
Ted Kremenek38a4b4b2008-10-17 20:28:54 +0000395 while (SR) {
396 R = SR->getSuperRegion();
397 if (R == S)
398 return true;
399
400 SR = dyn_cast<SubRegion>(R);
Ted Kremenekb15eba42008-10-04 05:50:14 +0000401 }
402
403 return false;
404}