blob: 28a27b048ae123848c8d8f76bb710b481a9ad87c [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
Zhongxing Xue9f4e542008-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 Kremenek7090ae12008-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 Xudc0a25d2008-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
Zhongxing Xu817c67d2008-11-03 04:12:24 +000054QualType AnonPointeeRegion::getType(ASTContext& C) const {
55 QualType T = C.getCanonicalType(Pointer->getType());
56 PointerType* PTy = cast<PointerType>(T.getTypePtr());
57
58 QualType PointeeTy = C.getCanonicalType(PTy->getPointeeType());
59 return PointeeTy;
Ted Kremenek9e240492008-10-04 05:50:14 +000060}
61
Zhongxing Xu17892752008-10-08 02:50:44 +000062void AnonPointeeRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
Zhongxing Xu817c67d2008-11-03 04:12:24 +000063 const VarDecl* VD,
Zhongxing Xu17892752008-10-08 02:50:44 +000064 const MemRegion* superRegion) {
65 ID.AddInteger((unsigned) AnonPointeeRegionKind);
Zhongxing Xu17892752008-10-08 02:50:44 +000066 ID.AddPointer(VD);
67 ID.AddPointer(superRegion);
68}
69
Ted Kremenek329d6fd2008-10-27 20:57:58 +000070void CompoundLiteralRegion::Profile(llvm::FoldingSetNodeID& ID) const {
71 CompoundLiteralRegion::ProfileRegion(ID, CL, superRegion);
72}
73
74void CompoundLiteralRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
75 const CompoundLiteralExpr* CL,
76 const MemRegion* superRegion) {
77 ID.AddInteger((unsigned) CompoundLiteralRegionKind);
78 ID.AddPointer(CL);
79 ID.AddPointer(superRegion);
80}
81
Ted Kremenek9e240492008-10-04 05:50:14 +000082void DeclRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, const Decl* D,
83 const MemRegion* superRegion, Kind k) {
84 ID.AddInteger((unsigned) k);
85 ID.AddPointer(D);
86 ID.AddPointer(superRegion);
87}
88
89void DeclRegion::Profile(llvm::FoldingSetNodeID& ID) const {
90 DeclRegion::ProfileRegion(ID, D, superRegion, getKind());
91}
92
Ted Kremenek993f1c72008-10-17 20:28:54 +000093void SymbolicRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, SymbolID sym) {
94 ID.AddInteger((unsigned) MemRegion::SymbolicRegionKind);
95 ID.AddInteger(sym.getNumber());
96}
97
98void SymbolicRegion::Profile(llvm::FoldingSetNodeID& ID) const {
99 SymbolicRegion::ProfileRegion(ID, sym);
100}
101
Zhongxing Xu511191c2008-10-21 05:27:10 +0000102void ElementRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, SVal Idx,
103 const MemRegion* superRegion) {
104 ID.AddInteger(MemRegion::ElementRegionKind);
105 ID.AddPointer(superRegion);
106 Idx.Profile(ID);
107}
108
109void ElementRegion::Profile(llvm::FoldingSetNodeID& ID) const {
110 ElementRegion::ProfileRegion(ID, Index, superRegion);
111}
Zhongxing Xu27b57062008-10-27 13:17:02 +0000112
113QualType ElementRegion::getType(ASTContext& C) const {
114 QualType T = cast<TypedRegion>(superRegion)->getType(C);
Zhongxing Xu56af9772008-11-13 07:30:58 +0000115
116 if (isa<ArrayType>(T.getTypePtr())) {
117 ArrayType* AT = cast<ArrayType>(T.getTypePtr());
118 return AT->getElementType();
119 }
Ted Kremenek34265e72008-11-17 22:55:12 +0000120 else {
121 assert (isa<AnonTypedRegion>(superRegion));
Zhongxing Xu56af9772008-11-13 07:30:58 +0000122 PointerType* PtrT = cast<PointerType>(T.getTypePtr());
123 QualType PTy = PtrT->getPointeeType();
124 return C.getCanonicalType(PTy);
125 }
Zhongxing Xu27b57062008-10-27 13:17:02 +0000126}
127
Ted Kremenek9e240492008-10-04 05:50:14 +0000128//===----------------------------------------------------------------------===//
129// Region pretty-printing.
130//===----------------------------------------------------------------------===//
131
132std::string MemRegion::getString() const {
133 std::string s;
134 llvm::raw_string_ostream os(s);
135 print(os);
136 return os.str();
137}
138
139void MemRegion::print(llvm::raw_ostream& os) const {
140 os << "<Unknown Region>";
141}
142
Ted Kremenek7090ae12008-11-02 00:34:33 +0000143void AllocaRegion::print(llvm::raw_ostream& os) const {
144 os << "alloca{" << (void*) Ex << ',' << Cnt << '}';
145}
146
Ted Kremenek9e240492008-10-04 05:50:14 +0000147void VarRegion::print(llvm::raw_ostream& os) const {
148 os << cast<VarDecl>(D)->getName();
149}
150
Ted Kremenek993f1c72008-10-17 20:28:54 +0000151void SymbolicRegion::print(llvm::raw_ostream& os) const {
152 os << "$" << sym.getNumber();
153}
154
Ted Kremenek4bd1eef2008-10-17 21:05:44 +0000155void FieldRegion::print(llvm::raw_ostream& os) const {
156 superRegion->print(os);
157 os << "->" << getDecl()->getName();
158}
159
Zhongxing Xub21ff772008-10-24 06:30:07 +0000160void ElementRegion::print(llvm::raw_ostream& os) const {
161 superRegion->print(os);
162 os << '['; Index.print(os); os << ']';
163}
164
Ted Kremenek329d6fd2008-10-27 20:57:58 +0000165void CompoundLiteralRegion::print(llvm::raw_ostream& os) const {
166 // FIXME: More elaborate pretty-printing.
167 os << "{ " << (void*) CL << " }";
168}
169
Zhongxing Xucc128b32008-11-10 13:05:26 +0000170void StringRegion::print(llvm::raw_ostream& os) const {
Zhongxing Xud2f016f2008-11-11 01:36:32 +0000171 if (Str->isWide()) os << 'L';
172 os << '"';
173
174 // FIXME: this doesn't print wstrings right.
175 for (unsigned i = 0, e = Str->getByteLength(); i != e; ++i) {
176 switch (Str->getStrData()[i]) {
177 default: os << Str->getStrData()[i]; break;
178 // Handle some common ones to make dumps prettier.
179 case '\\': os << "\\\\"; break;
180 case '"': os << "\\\""; break;
181 case '\n': os << "\\n"; break;
182 case '\t': os << "\\t"; break;
183 case '\a': os << "\\a"; break;
184 case '\b': os << "\\b"; break;
185 }
186 }
187 os << '"';
Zhongxing Xucc128b32008-11-10 13:05:26 +0000188}
189
Ted Kremenek9e240492008-10-04 05:50:14 +0000190//===----------------------------------------------------------------------===//
191// MemRegionManager methods.
192//===----------------------------------------------------------------------===//
193
194MemSpaceRegion* MemRegionManager::LazyAllocate(MemSpaceRegion*& region) {
195
196 if (!region) {
197 region = (MemSpaceRegion*) A.Allocate<MemSpaceRegion>();
198 new (region) MemSpaceRegion();
199 }
200
201 return region;
202}
203
204MemSpaceRegion* MemRegionManager::getStackRegion() {
205 return LazyAllocate(stack);
206}
207
208MemSpaceRegion* MemRegionManager::getGlobalsRegion() {
209 return LazyAllocate(globals);
210}
211
212MemSpaceRegion* MemRegionManager::getHeapRegion() {
213 return LazyAllocate(heap);
214}
215
Zhongxing Xu17892752008-10-08 02:50:44 +0000216MemSpaceRegion* MemRegionManager::getUnknownRegion() {
217 return LazyAllocate(unknown);
218}
219
Zhongxing Xue9f4e542008-10-25 14:13:41 +0000220StringRegion* MemRegionManager::getStringRegion(const StringLiteral* Str) {
221 llvm::FoldingSetNodeID ID;
222 MemSpaceRegion* GlobalsR = getGlobalsRegion();
223
224 StringRegion::ProfileRegion(ID, Str, GlobalsR);
225
226 void* InsertPos;
227 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
228 StringRegion* R = cast_or_null<StringRegion>(data);
229
230 if (!R) {
231 R = (StringRegion*) A.Allocate<StringRegion>();
232 new (R) StringRegion(Str, GlobalsR);
233 Regions.InsertNode(R, InsertPos);
234 }
235
236 return R;
237}
238
Ted Kremenek9a1f03a2008-10-27 21:01:26 +0000239VarRegion* MemRegionManager::getVarRegion(const VarDecl* d) {
240
241 const MemRegion* superRegion = d->hasLocalStorage() ? getStackRegion()
242 : getGlobalsRegion();
243
Ted Kremenek9e240492008-10-04 05:50:14 +0000244 llvm::FoldingSetNodeID ID;
245 DeclRegion::ProfileRegion(ID, d, superRegion, MemRegion::VarRegionKind);
246
247 void* InsertPos;
248 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
249 VarRegion* R = cast_or_null<VarRegion>(data);
250
251 if (!R) {
252 R = (VarRegion*) A.Allocate<VarRegion>();
253 new (R) VarRegion(d, superRegion);
254 Regions.InsertNode(R, InsertPos);
255 }
256
257 return R;
258}
259
Ted Kremenek329d6fd2008-10-27 20:57:58 +0000260CompoundLiteralRegion*
261MemRegionManager::getCompoundLiteralRegion(const CompoundLiteralExpr* CL) {
262 // Is this compound literal allocated on the stack or is part of the
263 // global constant pool?
264 const MemRegion* superRegion = CL->isFileScope() ?
265 getGlobalsRegion() : getStackRegion();
266
267 // Profile the compound literal.
268 llvm::FoldingSetNodeID ID;
269 CompoundLiteralRegion::ProfileRegion(ID, CL, superRegion);
270
271 void* InsertPos;
272 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
273 CompoundLiteralRegion* R = cast_or_null<CompoundLiteralRegion>(data);
274
275 if (!R) {
276 R = (CompoundLiteralRegion*) A.Allocate<CompoundLiteralRegion>();
277 new (R) CompoundLiteralRegion(CL, superRegion);
278 Regions.InsertNode(R, InsertPos);
279 }
280
281 return R;
282}
283
Zhongxing Xu511191c2008-10-21 05:27:10 +0000284ElementRegion* MemRegionManager::getElementRegion(SVal Idx,
285 const MemRegion* superRegion){
286 llvm::FoldingSetNodeID ID;
287 ElementRegion::ProfileRegion(ID, Idx, superRegion);
288
289 void* InsertPos;
290 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
291 ElementRegion* R = cast_or_null<ElementRegion>(data);
292
293 if (!R) {
294 R = (ElementRegion*) A.Allocate<ElementRegion>();
295 new (R) ElementRegion(Idx, superRegion);
296 Regions.InsertNode(R, InsertPos);
297 }
298
299 return R;
300}
301
Ted Kremenek993f1c72008-10-17 20:28:54 +0000302/// getSymbolicRegion - Retrieve or create a "symbolic" memory region.
303SymbolicRegion* MemRegionManager::getSymbolicRegion(const SymbolID sym) {
304
305 llvm::FoldingSetNodeID ID;
306 SymbolicRegion::ProfileRegion(ID, sym);
307
308 void* InsertPos;
309 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
310 SymbolicRegion* R = cast_or_null<SymbolicRegion>(data);
311
312 if (!R) {
313 R = (SymbolicRegion*) A.Allocate<SymbolicRegion>();
314 new (R) SymbolicRegion(sym);
315 Regions.InsertNode(R, InsertPos);
316 }
317
318 return R;
319}
320
Ted Kremenek9e240492008-10-04 05:50:14 +0000321FieldRegion* MemRegionManager::getFieldRegion(const FieldDecl* d,
Ted Kremenek993f1c72008-10-17 20:28:54 +0000322 const MemRegion* superRegion) {
Ted Kremenek9e240492008-10-04 05:50:14 +0000323 llvm::FoldingSetNodeID ID;
324 DeclRegion::ProfileRegion(ID, d, superRegion, MemRegion::FieldRegionKind);
325
326 void* InsertPos;
327 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
328 FieldRegion* R = cast_or_null<FieldRegion>(data);
329
330 if (!R) {
331 R = (FieldRegion*) A.Allocate<FieldRegion>();
332 new (R) FieldRegion(d, superRegion);
333 Regions.InsertNode(R, InsertPos);
334 }
335
336 return R;
337}
338
Ted Kremenek993f1c72008-10-17 20:28:54 +0000339ObjCIvarRegion*
340MemRegionManager::getObjCIvarRegion(const ObjCIvarDecl* d,
341 const MemRegion* superRegion) {
Ted Kremenek9e240492008-10-04 05:50:14 +0000342 llvm::FoldingSetNodeID ID;
343 DeclRegion::ProfileRegion(ID, d, superRegion, MemRegion::ObjCIvarRegionKind);
344
345 void* InsertPos;
346 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
347 ObjCIvarRegion* R = cast_or_null<ObjCIvarRegion>(data);
348
349 if (!R) {
Zhongxing Xu722c2882008-10-06 03:03:33 +0000350 R = (ObjCIvarRegion*) A.Allocate<ObjCIvarRegion>();
351 new (R) ObjCIvarRegion(d, superRegion);
Ted Kremenek9e240492008-10-04 05:50:14 +0000352 Regions.InsertNode(R, InsertPos);
353 }
354
355 return R;
356}
357
Ted Kremeneka7f1b9e2008-10-24 20:30:08 +0000358ObjCObjectRegion*
359MemRegionManager::getObjCObjectRegion(const ObjCInterfaceDecl* d,
360 const MemRegion* superRegion) {
361 llvm::FoldingSetNodeID ID;
362 DeclRegion::ProfileRegion(ID, d, superRegion,
363 MemRegion::ObjCObjectRegionKind);
364
365 void* InsertPos;
366 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
367 ObjCObjectRegion* R = cast_or_null<ObjCObjectRegion>(data);
368
369 if (!R) {
370 R = (ObjCObjectRegion*) A.Allocate<ObjCObjectRegion>();
371 new (R) ObjCObjectRegion(d, superRegion);
372 Regions.InsertNode(R, InsertPos);
373 }
374
375 return R;
376}
377
Zhongxing Xudc0a25d2008-11-16 04:07:26 +0000378AnonTypedRegion*
379MemRegionManager::getAnonTypedRegion(QualType t, const MemRegion* superRegion) {
380 llvm::FoldingSetNodeID ID;
381 AnonTypedRegion::ProfileRegion(ID, t, superRegion);
382
383 void* InsertPos;
384 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
385 AnonTypedRegion* R = cast_or_null<AnonTypedRegion>(data);
386
387 if (!R) {
388 R = (AnonTypedRegion*) A.Allocate<AnonTypedRegion>();
389 new (R) AnonTypedRegion(t, superRegion);
390 Regions.InsertNode(R, InsertPos);
391 }
392
393 return R;
394}
Ted Kremeneka7f1b9e2008-10-24 20:30:08 +0000395
Zhongxing Xu17892752008-10-08 02:50:44 +0000396AnonPointeeRegion* MemRegionManager::getAnonPointeeRegion(const VarDecl* d) {
397 llvm::FoldingSetNodeID ID;
Zhongxing Xu17892752008-10-08 02:50:44 +0000398 MemRegion* superRegion = getUnknownRegion();
399
Zhongxing Xu817c67d2008-11-03 04:12:24 +0000400 AnonPointeeRegion::ProfileRegion(ID, d, superRegion);
Zhongxing Xu17892752008-10-08 02:50:44 +0000401
402 void* InsertPos;
403 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
404 AnonPointeeRegion* R = cast_or_null<AnonPointeeRegion>(data);
405
406 if (!R) {
407 R = (AnonPointeeRegion*) A.Allocate<AnonPointeeRegion>();
Zhongxing Xu817c67d2008-11-03 04:12:24 +0000408 new (R) AnonPointeeRegion(d, superRegion);
Zhongxing Xu17892752008-10-08 02:50:44 +0000409 Regions.InsertNode(R, InsertPos);
410 }
411
412 return R;
413}
414
Ted Kremenek7090ae12008-11-02 00:34:33 +0000415AllocaRegion* MemRegionManager::getAllocaRegion(const Expr* E, unsigned cnt) {
416 llvm::FoldingSetNodeID ID;
417 AllocaRegion::ProfileRegion(ID, E, cnt);
418
419 void* InsertPos;
420 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
421 AllocaRegion* R = cast_or_null<AllocaRegion>(data);
422
423 if (!R) {
424 R = (AllocaRegion*) A.Allocate<AllocaRegion>();
425 new (R) AllocaRegion(E, cnt, getStackRegion());
426 Regions.InsertNode(R, InsertPos);
427 }
428
429 return R;
430}
431
Ted Kremenek9e240492008-10-04 05:50:14 +0000432bool MemRegionManager::hasStackStorage(const MemRegion* R) {
Ted Kremenek993f1c72008-10-17 20:28:54 +0000433
434 // Only subregions can have stack storage.
Ted Kremenek7090ae12008-11-02 00:34:33 +0000435 const SubRegion* SR = dyn_cast<SubRegion>(R);
436
Ted Kremenek993f1c72008-10-17 20:28:54 +0000437 if (!SR)
438 return false;
Ted Kremenek7090ae12008-11-02 00:34:33 +0000439
Ted Kremenek9e240492008-10-04 05:50:14 +0000440 MemSpaceRegion* S = getStackRegion();
441
Ted Kremenek993f1c72008-10-17 20:28:54 +0000442 while (SR) {
443 R = SR->getSuperRegion();
444 if (R == S)
445 return true;
446
447 SR = dyn_cast<SubRegion>(R);
Ted Kremenek9e240492008-10-04 05:50:14 +0000448 }
449
450 return false;
451}