blob: 8767781354e707e011ff7044c0083c3c09a731df [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
Zhongxing Xu8fbe7ae2008-11-16 04:07:26 +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
Ted Kremenek6bc91b92008-10-27 20:57:58 +000054void CompoundLiteralRegion::Profile(llvm::FoldingSetNodeID& ID) const {
55 CompoundLiteralRegion::ProfileRegion(ID, CL, superRegion);
56}
57
58void CompoundLiteralRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
59 const CompoundLiteralExpr* CL,
60 const MemRegion* superRegion) {
61 ID.AddInteger((unsigned) CompoundLiteralRegionKind);
62 ID.AddPointer(CL);
63 ID.AddPointer(superRegion);
64}
65
Ted Kremenekb15eba42008-10-04 05:50:14 +000066void DeclRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, const Decl* D,
67 const MemRegion* superRegion, Kind k) {
68 ID.AddInteger((unsigned) k);
69 ID.AddPointer(D);
70 ID.AddPointer(superRegion);
71}
72
73void DeclRegion::Profile(llvm::FoldingSetNodeID& ID) const {
74 DeclRegion::ProfileRegion(ID, D, superRegion, getKind());
75}
76
Ted Kremenekb9cd9a72008-12-05 02:27:51 +000077void SymbolicRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, SymbolRef sym) {
Ted Kremenek38a4b4b2008-10-17 20:28:54 +000078 ID.AddInteger((unsigned) MemRegion::SymbolicRegionKind);
Ted Kremeneke8993f12008-12-05 02:39:38 +000079 ID.Add(sym);
Ted Kremenek38a4b4b2008-10-17 20:28:54 +000080}
81
82void SymbolicRegion::Profile(llvm::FoldingSetNodeID& ID) const {
83 SymbolicRegion::ProfileRegion(ID, sym);
84}
85
Zhongxing Xu54969732008-10-21 05:27:10 +000086void ElementRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, SVal Idx,
87 const MemRegion* superRegion) {
88 ID.AddInteger(MemRegion::ElementRegionKind);
89 ID.AddPointer(superRegion);
90 Idx.Profile(ID);
91}
92
93void ElementRegion::Profile(llvm::FoldingSetNodeID& ID) const {
94 ElementRegion::ProfileRegion(ID, Index, superRegion);
95}
Zhongxing Xu1a563da2008-10-27 13:17:02 +000096
Ted Kremenekf5da3252008-12-13 21:49:13 +000097QualType ElementRegion::getRValueType(ASTContext& C) const {
98 QualType T = getArrayRegion()->getLValueType(C);
99 // FIXME: Should ArrayType be considered an LValue or RValue type?
Zhongxing Xu9f801532008-11-13 07:30:58 +0000100 if (isa<ArrayType>(T.getTypePtr())) {
101 ArrayType* AT = cast<ArrayType>(T.getTypePtr());
102 return AT->getElementType();
103 }
Ted Kremenek3ba2c5f2008-11-17 22:55:12 +0000104 else {
Zhongxing Xu9f801532008-11-13 07:30:58 +0000105 PointerType* PtrT = cast<PointerType>(T.getTypePtr());
106 QualType PTy = PtrT->getPointeeType();
107 return C.getCanonicalType(PTy);
108 }
Zhongxing Xu1a563da2008-10-27 13:17:02 +0000109}
110
Ted Kremenekb15eba42008-10-04 05:50:14 +0000111//===----------------------------------------------------------------------===//
Ted Kremenekf5da3252008-12-13 21:49:13 +0000112// getLValueType() and getRValueType()
113//===----------------------------------------------------------------------===//
114
115QualType StringRegion::getRValueType(ASTContext& C) const {
116 return Str->getType();
117}
118
119//===----------------------------------------------------------------------===//
Ted Kremenekb15eba42008-10-04 05:50:14 +0000120// Region pretty-printing.
121//===----------------------------------------------------------------------===//
122
123std::string MemRegion::getString() const {
124 std::string s;
125 llvm::raw_string_ostream os(s);
126 print(os);
127 return os.str();
128}
129
130void MemRegion::print(llvm::raw_ostream& os) const {
131 os << "<Unknown Region>";
132}
133
Ted Kremenekea9ca502008-11-02 00:34:33 +0000134void AllocaRegion::print(llvm::raw_ostream& os) const {
135 os << "alloca{" << (void*) Ex << ',' << Cnt << '}';
136}
137
Ted Kremenek542c34d2008-12-17 19:25:50 +0000138void AnonTypedRegion::print(llvm::raw_ostream& os) const {
139 os << "anon_type{" << T.getAsString() << ',';
140 getSuperRegion()->print(os);
141 os << '}';
142}
143
Ted Kremenekb15eba42008-10-04 05:50:14 +0000144void VarRegion::print(llvm::raw_ostream& os) const {
Chris Lattner271d4c22008-11-24 05:29:24 +0000145 os << cast<VarDecl>(D)->getNameAsString();
Ted Kremenekb15eba42008-10-04 05:50:14 +0000146}
147
Ted Kremenek38a4b4b2008-10-17 20:28:54 +0000148void SymbolicRegion::print(llvm::raw_ostream& os) const {
Ted Kremenek8b60bad2008-12-05 02:45:20 +0000149 os << "SymRegion-";
150 sym.print(os);
Ted Kremenek38a4b4b2008-10-17 20:28:54 +0000151}
152
Ted Kremenekdea0c6b2008-10-17 21:05:44 +0000153void FieldRegion::print(llvm::raw_ostream& os) const {
154 superRegion->print(os);
Chris Lattner271d4c22008-11-24 05:29:24 +0000155 os << "->" << getDecl()->getNameAsString();
Ted Kremenekdea0c6b2008-10-17 21:05:44 +0000156}
157
Zhongxing Xu74a4e3a2008-10-24 06:30:07 +0000158void ElementRegion::print(llvm::raw_ostream& os) const {
159 superRegion->print(os);
160 os << '['; Index.print(os); os << ']';
161}
162
Ted Kremenek6bc91b92008-10-27 20:57:58 +0000163void CompoundLiteralRegion::print(llvm::raw_ostream& os) const {
164 // FIXME: More elaborate pretty-printing.
165 os << "{ " << (void*) CL << " }";
166}
167
Zhongxing Xu4c9390f2008-11-10 13:05:26 +0000168void StringRegion::print(llvm::raw_ostream& os) const {
Zhongxing Xuff81fc52008-11-11 01:36:32 +0000169 if (Str->isWide()) os << 'L';
170 os << '"';
171
172 // FIXME: this doesn't print wstrings right.
173 for (unsigned i = 0, e = Str->getByteLength(); i != e; ++i) {
174 switch (Str->getStrData()[i]) {
175 default: os << Str->getStrData()[i]; break;
176 // Handle some common ones to make dumps prettier.
177 case '\\': os << "\\\\"; break;
178 case '"': os << "\\\""; break;
179 case '\n': os << "\\n"; break;
180 case '\t': os << "\\t"; break;
181 case '\a': os << "\\a"; break;
182 case '\b': os << "\\b"; break;
183 }
184 }
185 os << '"';
Zhongxing Xu4c9390f2008-11-10 13:05:26 +0000186}
187
Ted Kremenekb15eba42008-10-04 05:50:14 +0000188//===----------------------------------------------------------------------===//
189// MemRegionManager methods.
190//===----------------------------------------------------------------------===//
191
192MemSpaceRegion* MemRegionManager::LazyAllocate(MemSpaceRegion*& region) {
193
194 if (!region) {
195 region = (MemSpaceRegion*) A.Allocate<MemSpaceRegion>();
196 new (region) MemSpaceRegion();
197 }
198
199 return region;
200}
201
202MemSpaceRegion* MemRegionManager::getStackRegion() {
203 return LazyAllocate(stack);
204}
205
206MemSpaceRegion* MemRegionManager::getGlobalsRegion() {
207 return LazyAllocate(globals);
208}
209
210MemSpaceRegion* MemRegionManager::getHeapRegion() {
211 return LazyAllocate(heap);
212}
213
Zhongxing Xu79c57f82008-10-08 02:50:44 +0000214MemSpaceRegion* MemRegionManager::getUnknownRegion() {
215 return LazyAllocate(unknown);
216}
217
Zhongxing Xu5ea4ad02008-12-20 06:32:12 +0000218bool MemRegionManager::onStack(const MemRegion* R) {
219 while (const SubRegion* SR = dyn_cast<SubRegion>(R))
220 R = SR->getSuperRegion();
221
222 return (R != 0) && (R == stack);
223}
224
225bool MemRegionManager::onHeap(const MemRegion* R) {
226 while (const SubRegion* SR = dyn_cast<SubRegion>(R))
227 R = SR->getSuperRegion();
228
229 return (R != 0) && (R == heap);
230}
231
Zhongxing Xu73507bd2008-10-25 14:13:41 +0000232StringRegion* MemRegionManager::getStringRegion(const StringLiteral* Str) {
233 llvm::FoldingSetNodeID ID;
234 MemSpaceRegion* GlobalsR = getGlobalsRegion();
235
236 StringRegion::ProfileRegion(ID, Str, GlobalsR);
237
238 void* InsertPos;
239 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
240 StringRegion* R = cast_or_null<StringRegion>(data);
241
242 if (!R) {
243 R = (StringRegion*) A.Allocate<StringRegion>();
244 new (R) StringRegion(Str, GlobalsR);
245 Regions.InsertNode(R, InsertPos);
246 }
247
248 return R;
249}
250
Ted Kremenek81329ab2008-10-27 21:01:26 +0000251VarRegion* MemRegionManager::getVarRegion(const VarDecl* d) {
252
253 const MemRegion* superRegion = d->hasLocalStorage() ? getStackRegion()
254 : getGlobalsRegion();
255
Ted Kremenekb15eba42008-10-04 05:50:14 +0000256 llvm::FoldingSetNodeID ID;
257 DeclRegion::ProfileRegion(ID, d, superRegion, MemRegion::VarRegionKind);
258
259 void* InsertPos;
260 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
261 VarRegion* R = cast_or_null<VarRegion>(data);
262
263 if (!R) {
264 R = (VarRegion*) A.Allocate<VarRegion>();
265 new (R) VarRegion(d, superRegion);
266 Regions.InsertNode(R, InsertPos);
267 }
268
269 return R;
270}
271
Ted Kremenek6bc91b92008-10-27 20:57:58 +0000272CompoundLiteralRegion*
273MemRegionManager::getCompoundLiteralRegion(const CompoundLiteralExpr* CL) {
274 // Is this compound literal allocated on the stack or is part of the
275 // global constant pool?
276 const MemRegion* superRegion = CL->isFileScope() ?
277 getGlobalsRegion() : getStackRegion();
278
279 // Profile the compound literal.
280 llvm::FoldingSetNodeID ID;
281 CompoundLiteralRegion::ProfileRegion(ID, CL, superRegion);
282
283 void* InsertPos;
284 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
285 CompoundLiteralRegion* R = cast_or_null<CompoundLiteralRegion>(data);
286
287 if (!R) {
288 R = (CompoundLiteralRegion*) A.Allocate<CompoundLiteralRegion>();
289 new (R) CompoundLiteralRegion(CL, superRegion);
290 Regions.InsertNode(R, InsertPos);
291 }
292
293 return R;
294}
295
Ted Kremenek2c0de352008-12-13 19:24:37 +0000296ElementRegion*
297MemRegionManager::getElementRegion(SVal Idx, const TypedRegion* superRegion){
298
Zhongxing Xu54969732008-10-21 05:27:10 +0000299 llvm::FoldingSetNodeID ID;
300 ElementRegion::ProfileRegion(ID, Idx, superRegion);
301
302 void* InsertPos;
303 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
304 ElementRegion* R = cast_or_null<ElementRegion>(data);
305
306 if (!R) {
307 R = (ElementRegion*) A.Allocate<ElementRegion>();
308 new (R) ElementRegion(Idx, superRegion);
309 Regions.InsertNode(R, InsertPos);
310 }
311
312 return R;
313}
314
Ted Kremenek38a4b4b2008-10-17 20:28:54 +0000315/// getSymbolicRegion - Retrieve or create a "symbolic" memory region.
Ted Kremenekb9cd9a72008-12-05 02:27:51 +0000316SymbolicRegion* MemRegionManager::getSymbolicRegion(const SymbolRef sym) {
Ted Kremenek38a4b4b2008-10-17 20:28:54 +0000317
318 llvm::FoldingSetNodeID ID;
319 SymbolicRegion::ProfileRegion(ID, sym);
320
321 void* InsertPos;
322 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
323 SymbolicRegion* R = cast_or_null<SymbolicRegion>(data);
324
325 if (!R) {
326 R = (SymbolicRegion*) A.Allocate<SymbolicRegion>();
327 new (R) SymbolicRegion(sym);
328 Regions.InsertNode(R, InsertPos);
329 }
330
331 return R;
332}
333
Ted Kremenekb15eba42008-10-04 05:50:14 +0000334FieldRegion* MemRegionManager::getFieldRegion(const FieldDecl* d,
Ted Kremenek38a4b4b2008-10-17 20:28:54 +0000335 const MemRegion* superRegion) {
Ted Kremenekb15eba42008-10-04 05:50:14 +0000336 llvm::FoldingSetNodeID ID;
337 DeclRegion::ProfileRegion(ID, d, superRegion, MemRegion::FieldRegionKind);
338
339 void* InsertPos;
340 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
341 FieldRegion* R = cast_or_null<FieldRegion>(data);
342
343 if (!R) {
344 R = (FieldRegion*) A.Allocate<FieldRegion>();
345 new (R) FieldRegion(d, superRegion);
346 Regions.InsertNode(R, InsertPos);
347 }
348
349 return R;
350}
351
Ted Kremenek38a4b4b2008-10-17 20:28:54 +0000352ObjCIvarRegion*
353MemRegionManager::getObjCIvarRegion(const ObjCIvarDecl* d,
354 const MemRegion* superRegion) {
Ted Kremenekb15eba42008-10-04 05:50:14 +0000355 llvm::FoldingSetNodeID ID;
356 DeclRegion::ProfileRegion(ID, d, superRegion, MemRegion::ObjCIvarRegionKind);
357
358 void* InsertPos;
359 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
360 ObjCIvarRegion* R = cast_or_null<ObjCIvarRegion>(data);
361
362 if (!R) {
Zhongxing Xu7a861e82008-10-06 03:03:33 +0000363 R = (ObjCIvarRegion*) A.Allocate<ObjCIvarRegion>();
364 new (R) ObjCIvarRegion(d, superRegion);
Ted Kremenekb15eba42008-10-04 05:50:14 +0000365 Regions.InsertNode(R, InsertPos);
366 }
367
368 return R;
369}
370
Ted Kremenek2539c112008-10-24 20:30:08 +0000371ObjCObjectRegion*
372MemRegionManager::getObjCObjectRegion(const ObjCInterfaceDecl* d,
373 const MemRegion* superRegion) {
374 llvm::FoldingSetNodeID ID;
375 DeclRegion::ProfileRegion(ID, d, superRegion,
376 MemRegion::ObjCObjectRegionKind);
377
378 void* InsertPos;
379 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
380 ObjCObjectRegion* R = cast_or_null<ObjCObjectRegion>(data);
381
382 if (!R) {
383 R = (ObjCObjectRegion*) A.Allocate<ObjCObjectRegion>();
384 new (R) ObjCObjectRegion(d, superRegion);
385 Regions.InsertNode(R, InsertPos);
386 }
387
388 return R;
389}
390
Zhongxing Xu8fbe7ae2008-11-16 04:07:26 +0000391AnonTypedRegion*
392MemRegionManager::getAnonTypedRegion(QualType t, const MemRegion* superRegion) {
393 llvm::FoldingSetNodeID ID;
394 AnonTypedRegion::ProfileRegion(ID, t, superRegion);
395
396 void* InsertPos;
397 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
398 AnonTypedRegion* R = cast_or_null<AnonTypedRegion>(data);
399
400 if (!R) {
401 R = (AnonTypedRegion*) A.Allocate<AnonTypedRegion>();
402 new (R) AnonTypedRegion(t, superRegion);
403 Regions.InsertNode(R, InsertPos);
404 }
405
406 return R;
407}
Ted Kremenek2539c112008-10-24 20:30:08 +0000408
Ted Kremenekea9ca502008-11-02 00:34:33 +0000409AllocaRegion* MemRegionManager::getAllocaRegion(const Expr* E, unsigned cnt) {
410 llvm::FoldingSetNodeID ID;
411 AllocaRegion::ProfileRegion(ID, E, cnt);
412
413 void* InsertPos;
414 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
415 AllocaRegion* R = cast_or_null<AllocaRegion>(data);
416
417 if (!R) {
418 R = (AllocaRegion*) A.Allocate<AllocaRegion>();
419 new (R) AllocaRegion(E, cnt, getStackRegion());
420 Regions.InsertNode(R, InsertPos);
421 }
422
423 return R;
424}
425
Ted Kremenekb15eba42008-10-04 05:50:14 +0000426bool MemRegionManager::hasStackStorage(const MemRegion* R) {
Ted Kremenek38a4b4b2008-10-17 20:28:54 +0000427
428 // Only subregions can have stack storage.
Ted Kremenekea9ca502008-11-02 00:34:33 +0000429 const SubRegion* SR = dyn_cast<SubRegion>(R);
430
Ted Kremenek38a4b4b2008-10-17 20:28:54 +0000431 if (!SR)
432 return false;
Ted Kremenekea9ca502008-11-02 00:34:33 +0000433
Ted Kremenekb15eba42008-10-04 05:50:14 +0000434 MemSpaceRegion* S = getStackRegion();
435
Ted Kremenek38a4b4b2008-10-17 20:28:54 +0000436 while (SR) {
437 R = SR->getSuperRegion();
438 if (R == S)
439 return true;
440
441 SR = dyn_cast<SubRegion>(R);
Ted Kremenekb15eba42008-10-04 05:50:14 +0000442 }
443
444 return false;
445}