blob: 8a7be0d56481835ef17345e3460fcd9184af275f [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 Kremenekb15eba42008-10-04 05:50:14 +000036void AnonTypedRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, QualType T,
37 const MemRegion* superRegion) {
38 ID.AddInteger((unsigned) AnonTypedRegionKind);
39 ID.Add(T);
40 ID.AddPointer(superRegion);
41}
42
Zhongxing Xu79c57f82008-10-08 02:50:44 +000043void AnonPointeeRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
44 const VarDecl* VD, QualType T,
45 const MemRegion* superRegion) {
46 ID.AddInteger((unsigned) AnonPointeeRegionKind);
47 ID.Add(T);
48 ID.AddPointer(VD);
49 ID.AddPointer(superRegion);
50}
51
Ted Kremenekb15eba42008-10-04 05:50:14 +000052void AnonTypedRegion::Profile(llvm::FoldingSetNodeID& ID) const {
53 AnonTypedRegion::ProfileRegion(ID, T, superRegion);
54}
55
Ted Kremenek6bc91b92008-10-27 20:57:58 +000056void CompoundLiteralRegion::Profile(llvm::FoldingSetNodeID& ID) const {
57 CompoundLiteralRegion::ProfileRegion(ID, CL, superRegion);
58}
59
60void CompoundLiteralRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
61 const CompoundLiteralExpr* CL,
62 const MemRegion* superRegion) {
63 ID.AddInteger((unsigned) CompoundLiteralRegionKind);
64 ID.AddPointer(CL);
65 ID.AddPointer(superRegion);
66}
67
Ted Kremenekb15eba42008-10-04 05:50:14 +000068void DeclRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, const Decl* D,
69 const MemRegion* superRegion, Kind k) {
70 ID.AddInteger((unsigned) k);
71 ID.AddPointer(D);
72 ID.AddPointer(superRegion);
73}
74
75void DeclRegion::Profile(llvm::FoldingSetNodeID& ID) const {
76 DeclRegion::ProfileRegion(ID, D, superRegion, getKind());
77}
78
Ted Kremenek38a4b4b2008-10-17 20:28:54 +000079void SymbolicRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, SymbolID sym) {
80 ID.AddInteger((unsigned) MemRegion::SymbolicRegionKind);
81 ID.AddInteger(sym.getNumber());
82}
83
84void SymbolicRegion::Profile(llvm::FoldingSetNodeID& ID) const {
85 SymbolicRegion::ProfileRegion(ID, sym);
86}
87
Zhongxing Xu54969732008-10-21 05:27:10 +000088void ElementRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, SVal Idx,
89 const MemRegion* superRegion) {
90 ID.AddInteger(MemRegion::ElementRegionKind);
91 ID.AddPointer(superRegion);
92 Idx.Profile(ID);
93}
94
95void ElementRegion::Profile(llvm::FoldingSetNodeID& ID) const {
96 ElementRegion::ProfileRegion(ID, Index, superRegion);
97}
Zhongxing Xu1a563da2008-10-27 13:17:02 +000098
99QualType ElementRegion::getType(ASTContext& C) const {
100 QualType T = cast<TypedRegion>(superRegion)->getType(C);
101 ArrayType* AT = cast<ArrayType>(T.getTypePtr());
102 return AT->getElementType();
103}
104
Ted Kremenekb15eba42008-10-04 05:50:14 +0000105//===----------------------------------------------------------------------===//
106// Region pretty-printing.
107//===----------------------------------------------------------------------===//
108
109std::string MemRegion::getString() const {
110 std::string s;
111 llvm::raw_string_ostream os(s);
112 print(os);
113 return os.str();
114}
115
116void MemRegion::print(llvm::raw_ostream& os) const {
117 os << "<Unknown Region>";
118}
119
120void VarRegion::print(llvm::raw_ostream& os) const {
121 os << cast<VarDecl>(D)->getName();
122}
123
Ted Kremenek38a4b4b2008-10-17 20:28:54 +0000124void SymbolicRegion::print(llvm::raw_ostream& os) const {
125 os << "$" << sym.getNumber();
126}
127
Ted Kremenekdea0c6b2008-10-17 21:05:44 +0000128void FieldRegion::print(llvm::raw_ostream& os) const {
129 superRegion->print(os);
130 os << "->" << getDecl()->getName();
131}
132
Zhongxing Xu74a4e3a2008-10-24 06:30:07 +0000133void ElementRegion::print(llvm::raw_ostream& os) const {
134 superRegion->print(os);
135 os << '['; Index.print(os); os << ']';
136}
137
Ted Kremenek6bc91b92008-10-27 20:57:58 +0000138void CompoundLiteralRegion::print(llvm::raw_ostream& os) const {
139 // FIXME: More elaborate pretty-printing.
140 os << "{ " << (void*) CL << " }";
141}
142
Ted Kremenekb15eba42008-10-04 05:50:14 +0000143//===----------------------------------------------------------------------===//
144// MemRegionManager methods.
145//===----------------------------------------------------------------------===//
146
147MemSpaceRegion* MemRegionManager::LazyAllocate(MemSpaceRegion*& region) {
148
149 if (!region) {
150 region = (MemSpaceRegion*) A.Allocate<MemSpaceRegion>();
151 new (region) MemSpaceRegion();
152 }
153
154 return region;
155}
156
157MemSpaceRegion* MemRegionManager::getStackRegion() {
158 return LazyAllocate(stack);
159}
160
161MemSpaceRegion* MemRegionManager::getGlobalsRegion() {
162 return LazyAllocate(globals);
163}
164
165MemSpaceRegion* MemRegionManager::getHeapRegion() {
166 return LazyAllocate(heap);
167}
168
Zhongxing Xu79c57f82008-10-08 02:50:44 +0000169MemSpaceRegion* MemRegionManager::getUnknownRegion() {
170 return LazyAllocate(unknown);
171}
172
Zhongxing Xu73507bd2008-10-25 14:13:41 +0000173StringRegion* MemRegionManager::getStringRegion(const StringLiteral* Str) {
174 llvm::FoldingSetNodeID ID;
175 MemSpaceRegion* GlobalsR = getGlobalsRegion();
176
177 StringRegion::ProfileRegion(ID, Str, GlobalsR);
178
179 void* InsertPos;
180 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
181 StringRegion* R = cast_or_null<StringRegion>(data);
182
183 if (!R) {
184 R = (StringRegion*) A.Allocate<StringRegion>();
185 new (R) StringRegion(Str, GlobalsR);
186 Regions.InsertNode(R, InsertPos);
187 }
188
189 return R;
190}
191
Ted Kremenekb15eba42008-10-04 05:50:14 +0000192VarRegion* MemRegionManager::getVarRegion(const VarDecl* d,
Ted Kremenek38a4b4b2008-10-17 20:28:54 +0000193 const MemRegion* superRegion) {
Ted Kremenekb15eba42008-10-04 05:50:14 +0000194 llvm::FoldingSetNodeID ID;
195 DeclRegion::ProfileRegion(ID, d, superRegion, MemRegion::VarRegionKind);
196
197 void* InsertPos;
198 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
199 VarRegion* R = cast_or_null<VarRegion>(data);
200
201 if (!R) {
202 R = (VarRegion*) A.Allocate<VarRegion>();
203 new (R) VarRegion(d, superRegion);
204 Regions.InsertNode(R, InsertPos);
205 }
206
207 return R;
208}
209
Ted Kremenek6bc91b92008-10-27 20:57:58 +0000210CompoundLiteralRegion*
211MemRegionManager::getCompoundLiteralRegion(const CompoundLiteralExpr* CL) {
212 // Is this compound literal allocated on the stack or is part of the
213 // global constant pool?
214 const MemRegion* superRegion = CL->isFileScope() ?
215 getGlobalsRegion() : getStackRegion();
216
217 // Profile the compound literal.
218 llvm::FoldingSetNodeID ID;
219 CompoundLiteralRegion::ProfileRegion(ID, CL, superRegion);
220
221 void* InsertPos;
222 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
223 CompoundLiteralRegion* R = cast_or_null<CompoundLiteralRegion>(data);
224
225 if (!R) {
226 R = (CompoundLiteralRegion*) A.Allocate<CompoundLiteralRegion>();
227 new (R) CompoundLiteralRegion(CL, superRegion);
228 Regions.InsertNode(R, InsertPos);
229 }
230
231 return R;
232}
233
Zhongxing Xu54969732008-10-21 05:27:10 +0000234ElementRegion* MemRegionManager::getElementRegion(SVal Idx,
235 const MemRegion* superRegion){
236 llvm::FoldingSetNodeID ID;
237 ElementRegion::ProfileRegion(ID, Idx, superRegion);
238
239 void* InsertPos;
240 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
241 ElementRegion* R = cast_or_null<ElementRegion>(data);
242
243 if (!R) {
244 R = (ElementRegion*) A.Allocate<ElementRegion>();
245 new (R) ElementRegion(Idx, superRegion);
246 Regions.InsertNode(R, InsertPos);
247 }
248
249 return R;
250}
251
Ted Kremenek38a4b4b2008-10-17 20:28:54 +0000252/// getSymbolicRegion - Retrieve or create a "symbolic" memory region.
253SymbolicRegion* MemRegionManager::getSymbolicRegion(const SymbolID sym) {
254
255 llvm::FoldingSetNodeID ID;
256 SymbolicRegion::ProfileRegion(ID, sym);
257
258 void* InsertPos;
259 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
260 SymbolicRegion* R = cast_or_null<SymbolicRegion>(data);
261
262 if (!R) {
263 R = (SymbolicRegion*) A.Allocate<SymbolicRegion>();
264 new (R) SymbolicRegion(sym);
265 Regions.InsertNode(R, InsertPos);
266 }
267
268 return R;
269}
270
Ted Kremenekb15eba42008-10-04 05:50:14 +0000271FieldRegion* MemRegionManager::getFieldRegion(const FieldDecl* d,
Ted Kremenek38a4b4b2008-10-17 20:28:54 +0000272 const MemRegion* superRegion) {
Ted Kremenekb15eba42008-10-04 05:50:14 +0000273 llvm::FoldingSetNodeID ID;
274 DeclRegion::ProfileRegion(ID, d, superRegion, MemRegion::FieldRegionKind);
275
276 void* InsertPos;
277 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
278 FieldRegion* R = cast_or_null<FieldRegion>(data);
279
280 if (!R) {
281 R = (FieldRegion*) A.Allocate<FieldRegion>();
282 new (R) FieldRegion(d, superRegion);
283 Regions.InsertNode(R, InsertPos);
284 }
285
286 return R;
287}
288
Ted Kremenek38a4b4b2008-10-17 20:28:54 +0000289ObjCIvarRegion*
290MemRegionManager::getObjCIvarRegion(const ObjCIvarDecl* d,
291 const MemRegion* superRegion) {
Ted Kremenekb15eba42008-10-04 05:50:14 +0000292 llvm::FoldingSetNodeID ID;
293 DeclRegion::ProfileRegion(ID, d, superRegion, MemRegion::ObjCIvarRegionKind);
294
295 void* InsertPos;
296 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
297 ObjCIvarRegion* R = cast_or_null<ObjCIvarRegion>(data);
298
299 if (!R) {
Zhongxing Xu7a861e82008-10-06 03:03:33 +0000300 R = (ObjCIvarRegion*) A.Allocate<ObjCIvarRegion>();
301 new (R) ObjCIvarRegion(d, superRegion);
Ted Kremenekb15eba42008-10-04 05:50:14 +0000302 Regions.InsertNode(R, InsertPos);
303 }
304
305 return R;
306}
307
Ted Kremenek2539c112008-10-24 20:30:08 +0000308ObjCObjectRegion*
309MemRegionManager::getObjCObjectRegion(const ObjCInterfaceDecl* d,
310 const MemRegion* superRegion) {
311 llvm::FoldingSetNodeID ID;
312 DeclRegion::ProfileRegion(ID, d, superRegion,
313 MemRegion::ObjCObjectRegionKind);
314
315 void* InsertPos;
316 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
317 ObjCObjectRegion* R = cast_or_null<ObjCObjectRegion>(data);
318
319 if (!R) {
320 R = (ObjCObjectRegion*) A.Allocate<ObjCObjectRegion>();
321 new (R) ObjCObjectRegion(d, superRegion);
322 Regions.InsertNode(R, InsertPos);
323 }
324
325 return R;
326}
327
328
Zhongxing Xu79c57f82008-10-08 02:50:44 +0000329AnonPointeeRegion* MemRegionManager::getAnonPointeeRegion(const VarDecl* d) {
330 llvm::FoldingSetNodeID ID;
331 QualType T = d->getType();
332 QualType PointeeType = cast<PointerType>(T.getTypePtr())->getPointeeType();
333 MemRegion* superRegion = getUnknownRegion();
334
335 AnonPointeeRegion::ProfileRegion(ID, d, PointeeType, superRegion);
336
337 void* InsertPos;
338 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
339 AnonPointeeRegion* R = cast_or_null<AnonPointeeRegion>(data);
340
341 if (!R) {
342 R = (AnonPointeeRegion*) A.Allocate<AnonPointeeRegion>();
343 new (R) AnonPointeeRegion(d, PointeeType, superRegion);
344 Regions.InsertNode(R, InsertPos);
345 }
346
347 return R;
348}
349
Ted Kremenekb15eba42008-10-04 05:50:14 +0000350bool MemRegionManager::hasStackStorage(const MemRegion* R) {
Ted Kremenek38a4b4b2008-10-17 20:28:54 +0000351 const SubRegion* SR = dyn_cast<SubRegion>(R);
352
353 // Only subregions can have stack storage.
354 if (!SR)
355 return false;
356
Ted Kremenekb15eba42008-10-04 05:50:14 +0000357 MemSpaceRegion* S = getStackRegion();
358
Ted Kremenek38a4b4b2008-10-17 20:28:54 +0000359 while (SR) {
360 R = SR->getSuperRegion();
361 if (R == S)
362 return true;
363
364 SR = dyn_cast<SubRegion>(R);
Ted Kremenekb15eba42008-10-04 05:50:14 +0000365 }
366
367 return false;
368}