blob: ae575f116469e0ac89d4278dac8d1d315a1d06a3 [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 Xuff4fe312008-11-03 04:12:24 +000047QualType AnonPointeeRegion::getType(ASTContext& C) const {
48 QualType T = C.getCanonicalType(Pointer->getType());
49 PointerType* PTy = cast<PointerType>(T.getTypePtr());
50
51 QualType PointeeTy = C.getCanonicalType(PTy->getPointeeType());
52 return PointeeTy;
Ted Kremenekb15eba42008-10-04 05:50:14 +000053}
54
Zhongxing Xu79c57f82008-10-08 02:50:44 +000055void AnonPointeeRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
Zhongxing Xuff4fe312008-11-03 04:12:24 +000056 const VarDecl* VD,
Zhongxing Xu79c57f82008-10-08 02:50:44 +000057 const MemRegion* superRegion) {
58 ID.AddInteger((unsigned) AnonPointeeRegionKind);
Zhongxing Xu79c57f82008-10-08 02:50:44 +000059 ID.AddPointer(VD);
60 ID.AddPointer(superRegion);
61}
62
Ted Kremenek6bc91b92008-10-27 20:57:58 +000063void CompoundLiteralRegion::Profile(llvm::FoldingSetNodeID& ID) const {
64 CompoundLiteralRegion::ProfileRegion(ID, CL, superRegion);
65}
66
67void CompoundLiteralRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
68 const CompoundLiteralExpr* CL,
69 const MemRegion* superRegion) {
70 ID.AddInteger((unsigned) CompoundLiteralRegionKind);
71 ID.AddPointer(CL);
72 ID.AddPointer(superRegion);
73}
74
Ted Kremenekb15eba42008-10-04 05:50:14 +000075void DeclRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, const Decl* D,
76 const MemRegion* superRegion, Kind k) {
77 ID.AddInteger((unsigned) k);
78 ID.AddPointer(D);
79 ID.AddPointer(superRegion);
80}
81
82void DeclRegion::Profile(llvm::FoldingSetNodeID& ID) const {
83 DeclRegion::ProfileRegion(ID, D, superRegion, getKind());
84}
85
Ted Kremenek38a4b4b2008-10-17 20:28:54 +000086void SymbolicRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, SymbolID sym) {
87 ID.AddInteger((unsigned) MemRegion::SymbolicRegionKind);
88 ID.AddInteger(sym.getNumber());
89}
90
91void SymbolicRegion::Profile(llvm::FoldingSetNodeID& ID) const {
92 SymbolicRegion::ProfileRegion(ID, sym);
93}
94
Zhongxing Xu54969732008-10-21 05:27:10 +000095void ElementRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, SVal Idx,
96 const MemRegion* superRegion) {
97 ID.AddInteger(MemRegion::ElementRegionKind);
98 ID.AddPointer(superRegion);
99 Idx.Profile(ID);
100}
101
102void ElementRegion::Profile(llvm::FoldingSetNodeID& ID) const {
103 ElementRegion::ProfileRegion(ID, Index, superRegion);
104}
Zhongxing Xu1a563da2008-10-27 13:17:02 +0000105
106QualType ElementRegion::getType(ASTContext& C) const {
107 QualType T = cast<TypedRegion>(superRegion)->getType(C);
108 ArrayType* AT = cast<ArrayType>(T.getTypePtr());
109 return AT->getElementType();
110}
111
Ted Kremenekb15eba42008-10-04 05:50:14 +0000112//===----------------------------------------------------------------------===//
113// Region pretty-printing.
114//===----------------------------------------------------------------------===//
115
116std::string MemRegion::getString() const {
117 std::string s;
118 llvm::raw_string_ostream os(s);
119 print(os);
120 return os.str();
121}
122
123void MemRegion::print(llvm::raw_ostream& os) const {
124 os << "<Unknown Region>";
125}
126
Ted Kremenekea9ca502008-11-02 00:34:33 +0000127void AllocaRegion::print(llvm::raw_ostream& os) const {
128 os << "alloca{" << (void*) Ex << ',' << Cnt << '}';
129}
130
Ted Kremenekb15eba42008-10-04 05:50:14 +0000131void VarRegion::print(llvm::raw_ostream& os) const {
132 os << cast<VarDecl>(D)->getName();
133}
134
Ted Kremenek38a4b4b2008-10-17 20:28:54 +0000135void SymbolicRegion::print(llvm::raw_ostream& os) const {
136 os << "$" << sym.getNumber();
137}
138
Ted Kremenekdea0c6b2008-10-17 21:05:44 +0000139void FieldRegion::print(llvm::raw_ostream& os) const {
140 superRegion->print(os);
141 os << "->" << getDecl()->getName();
142}
143
Zhongxing Xu74a4e3a2008-10-24 06:30:07 +0000144void ElementRegion::print(llvm::raw_ostream& os) const {
145 superRegion->print(os);
146 os << '['; Index.print(os); os << ']';
147}
148
Ted Kremenek6bc91b92008-10-27 20:57:58 +0000149void CompoundLiteralRegion::print(llvm::raw_ostream& os) const {
150 // FIXME: More elaborate pretty-printing.
151 os << "{ " << (void*) CL << " }";
152}
153
Zhongxing Xu4c9390f2008-11-10 13:05:26 +0000154void StringRegion::print(llvm::raw_ostream& os) const {
Zhongxing Xuff81fc52008-11-11 01:36:32 +0000155 if (Str->isWide()) os << 'L';
156 os << '"';
157
158 // FIXME: this doesn't print wstrings right.
159 for (unsigned i = 0, e = Str->getByteLength(); i != e; ++i) {
160 switch (Str->getStrData()[i]) {
161 default: os << Str->getStrData()[i]; break;
162 // Handle some common ones to make dumps prettier.
163 case '\\': os << "\\\\"; break;
164 case '"': os << "\\\""; break;
165 case '\n': os << "\\n"; break;
166 case '\t': os << "\\t"; break;
167 case '\a': os << "\\a"; break;
168 case '\b': os << "\\b"; break;
169 }
170 }
171 os << '"';
Zhongxing Xu4c9390f2008-11-10 13:05:26 +0000172}
173
Ted Kremenekb15eba42008-10-04 05:50:14 +0000174//===----------------------------------------------------------------------===//
175// MemRegionManager methods.
176//===----------------------------------------------------------------------===//
177
178MemSpaceRegion* MemRegionManager::LazyAllocate(MemSpaceRegion*& region) {
179
180 if (!region) {
181 region = (MemSpaceRegion*) A.Allocate<MemSpaceRegion>();
182 new (region) MemSpaceRegion();
183 }
184
185 return region;
186}
187
188MemSpaceRegion* MemRegionManager::getStackRegion() {
189 return LazyAllocate(stack);
190}
191
192MemSpaceRegion* MemRegionManager::getGlobalsRegion() {
193 return LazyAllocate(globals);
194}
195
196MemSpaceRegion* MemRegionManager::getHeapRegion() {
197 return LazyAllocate(heap);
198}
199
Zhongxing Xu79c57f82008-10-08 02:50:44 +0000200MemSpaceRegion* MemRegionManager::getUnknownRegion() {
201 return LazyAllocate(unknown);
202}
203
Zhongxing Xu73507bd2008-10-25 14:13:41 +0000204StringRegion* MemRegionManager::getStringRegion(const StringLiteral* Str) {
205 llvm::FoldingSetNodeID ID;
206 MemSpaceRegion* GlobalsR = getGlobalsRegion();
207
208 StringRegion::ProfileRegion(ID, Str, GlobalsR);
209
210 void* InsertPos;
211 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
212 StringRegion* R = cast_or_null<StringRegion>(data);
213
214 if (!R) {
215 R = (StringRegion*) A.Allocate<StringRegion>();
216 new (R) StringRegion(Str, GlobalsR);
217 Regions.InsertNode(R, InsertPos);
218 }
219
220 return R;
221}
222
Ted Kremenek81329ab2008-10-27 21:01:26 +0000223VarRegion* MemRegionManager::getVarRegion(const VarDecl* d) {
224
225 const MemRegion* superRegion = d->hasLocalStorage() ? getStackRegion()
226 : getGlobalsRegion();
227
Ted Kremenekb15eba42008-10-04 05:50:14 +0000228 llvm::FoldingSetNodeID ID;
229 DeclRegion::ProfileRegion(ID, d, superRegion, MemRegion::VarRegionKind);
230
231 void* InsertPos;
232 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
233 VarRegion* R = cast_or_null<VarRegion>(data);
234
235 if (!R) {
236 R = (VarRegion*) A.Allocate<VarRegion>();
237 new (R) VarRegion(d, superRegion);
238 Regions.InsertNode(R, InsertPos);
239 }
240
241 return R;
242}
243
Ted Kremenek6bc91b92008-10-27 20:57:58 +0000244CompoundLiteralRegion*
245MemRegionManager::getCompoundLiteralRegion(const CompoundLiteralExpr* CL) {
246 // Is this compound literal allocated on the stack or is part of the
247 // global constant pool?
248 const MemRegion* superRegion = CL->isFileScope() ?
249 getGlobalsRegion() : getStackRegion();
250
251 // Profile the compound literal.
252 llvm::FoldingSetNodeID ID;
253 CompoundLiteralRegion::ProfileRegion(ID, CL, superRegion);
254
255 void* InsertPos;
256 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
257 CompoundLiteralRegion* R = cast_or_null<CompoundLiteralRegion>(data);
258
259 if (!R) {
260 R = (CompoundLiteralRegion*) A.Allocate<CompoundLiteralRegion>();
261 new (R) CompoundLiteralRegion(CL, superRegion);
262 Regions.InsertNode(R, InsertPos);
263 }
264
265 return R;
266}
267
Zhongxing Xu54969732008-10-21 05:27:10 +0000268ElementRegion* MemRegionManager::getElementRegion(SVal Idx,
269 const MemRegion* superRegion){
270 llvm::FoldingSetNodeID ID;
271 ElementRegion::ProfileRegion(ID, Idx, superRegion);
272
273 void* InsertPos;
274 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
275 ElementRegion* R = cast_or_null<ElementRegion>(data);
276
277 if (!R) {
278 R = (ElementRegion*) A.Allocate<ElementRegion>();
279 new (R) ElementRegion(Idx, superRegion);
280 Regions.InsertNode(R, InsertPos);
281 }
282
283 return R;
284}
285
Ted Kremenek38a4b4b2008-10-17 20:28:54 +0000286/// getSymbolicRegion - Retrieve or create a "symbolic" memory region.
287SymbolicRegion* MemRegionManager::getSymbolicRegion(const SymbolID sym) {
288
289 llvm::FoldingSetNodeID ID;
290 SymbolicRegion::ProfileRegion(ID, sym);
291
292 void* InsertPos;
293 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
294 SymbolicRegion* R = cast_or_null<SymbolicRegion>(data);
295
296 if (!R) {
297 R = (SymbolicRegion*) A.Allocate<SymbolicRegion>();
298 new (R) SymbolicRegion(sym);
299 Regions.InsertNode(R, InsertPos);
300 }
301
302 return R;
303}
304
Ted Kremenekb15eba42008-10-04 05:50:14 +0000305FieldRegion* MemRegionManager::getFieldRegion(const FieldDecl* d,
Ted Kremenek38a4b4b2008-10-17 20:28:54 +0000306 const MemRegion* superRegion) {
Ted Kremenekb15eba42008-10-04 05:50:14 +0000307 llvm::FoldingSetNodeID ID;
308 DeclRegion::ProfileRegion(ID, d, superRegion, MemRegion::FieldRegionKind);
309
310 void* InsertPos;
311 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
312 FieldRegion* R = cast_or_null<FieldRegion>(data);
313
314 if (!R) {
315 R = (FieldRegion*) A.Allocate<FieldRegion>();
316 new (R) FieldRegion(d, superRegion);
317 Regions.InsertNode(R, InsertPos);
318 }
319
320 return R;
321}
322
Ted Kremenek38a4b4b2008-10-17 20:28:54 +0000323ObjCIvarRegion*
324MemRegionManager::getObjCIvarRegion(const ObjCIvarDecl* d,
325 const MemRegion* superRegion) {
Ted Kremenekb15eba42008-10-04 05:50:14 +0000326 llvm::FoldingSetNodeID ID;
327 DeclRegion::ProfileRegion(ID, d, superRegion, MemRegion::ObjCIvarRegionKind);
328
329 void* InsertPos;
330 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
331 ObjCIvarRegion* R = cast_or_null<ObjCIvarRegion>(data);
332
333 if (!R) {
Zhongxing Xu7a861e82008-10-06 03:03:33 +0000334 R = (ObjCIvarRegion*) A.Allocate<ObjCIvarRegion>();
335 new (R) ObjCIvarRegion(d, superRegion);
Ted Kremenekb15eba42008-10-04 05:50:14 +0000336 Regions.InsertNode(R, InsertPos);
337 }
338
339 return R;
340}
341
Ted Kremenek2539c112008-10-24 20:30:08 +0000342ObjCObjectRegion*
343MemRegionManager::getObjCObjectRegion(const ObjCInterfaceDecl* d,
344 const MemRegion* superRegion) {
345 llvm::FoldingSetNodeID ID;
346 DeclRegion::ProfileRegion(ID, d, superRegion,
347 MemRegion::ObjCObjectRegionKind);
348
349 void* InsertPos;
350 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
351 ObjCObjectRegion* R = cast_or_null<ObjCObjectRegion>(data);
352
353 if (!R) {
354 R = (ObjCObjectRegion*) A.Allocate<ObjCObjectRegion>();
355 new (R) ObjCObjectRegion(d, superRegion);
356 Regions.InsertNode(R, InsertPos);
357 }
358
359 return R;
360}
361
362
Zhongxing Xu79c57f82008-10-08 02:50:44 +0000363AnonPointeeRegion* MemRegionManager::getAnonPointeeRegion(const VarDecl* d) {
364 llvm::FoldingSetNodeID ID;
Zhongxing Xu79c57f82008-10-08 02:50:44 +0000365 MemRegion* superRegion = getUnknownRegion();
366
Zhongxing Xuff4fe312008-11-03 04:12:24 +0000367 AnonPointeeRegion::ProfileRegion(ID, d, superRegion);
Zhongxing Xu79c57f82008-10-08 02:50:44 +0000368
369 void* InsertPos;
370 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
371 AnonPointeeRegion* R = cast_or_null<AnonPointeeRegion>(data);
372
373 if (!R) {
374 R = (AnonPointeeRegion*) A.Allocate<AnonPointeeRegion>();
Zhongxing Xuff4fe312008-11-03 04:12:24 +0000375 new (R) AnonPointeeRegion(d, superRegion);
Zhongxing Xu79c57f82008-10-08 02:50:44 +0000376 Regions.InsertNode(R, InsertPos);
377 }
378
379 return R;
380}
381
Ted Kremenekea9ca502008-11-02 00:34:33 +0000382AllocaRegion* MemRegionManager::getAllocaRegion(const Expr* E, unsigned cnt) {
383 llvm::FoldingSetNodeID ID;
384 AllocaRegion::ProfileRegion(ID, E, cnt);
385
386 void* InsertPos;
387 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
388 AllocaRegion* R = cast_or_null<AllocaRegion>(data);
389
390 if (!R) {
391 R = (AllocaRegion*) A.Allocate<AllocaRegion>();
392 new (R) AllocaRegion(E, cnt, getStackRegion());
393 Regions.InsertNode(R, InsertPos);
394 }
395
396 return R;
397}
398
Ted Kremenekb15eba42008-10-04 05:50:14 +0000399bool MemRegionManager::hasStackStorage(const MemRegion* R) {
Ted Kremenek38a4b4b2008-10-17 20:28:54 +0000400
401 // Only subregions can have stack storage.
Ted Kremenekea9ca502008-11-02 00:34:33 +0000402 const SubRegion* SR = dyn_cast<SubRegion>(R);
403
Ted Kremenek38a4b4b2008-10-17 20:28:54 +0000404 if (!SR)
405 return false;
Ted Kremenekea9ca502008-11-02 00:34:33 +0000406
Ted Kremenekb15eba42008-10-04 05:50:14 +0000407 MemSpaceRegion* S = getStackRegion();
408
Ted Kremenek38a4b4b2008-10-17 20:28:54 +0000409 while (SR) {
410 R = SR->getSuperRegion();
411 if (R == S)
412 return true;
413
414 SR = dyn_cast<SubRegion>(R);
Ted Kremenekb15eba42008-10-04 05:50:14 +0000415 }
416
417 return false;
418}