blob: 27ecffdc06ea70f8550cc0b88654a62b7cbfa2e0 [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 Kremenek81329ab2008-10-27 21:01:26 +0000192VarRegion* MemRegionManager::getVarRegion(const VarDecl* d) {
193
194 const MemRegion* superRegion = d->hasLocalStorage() ? getStackRegion()
195 : getGlobalsRegion();
196
Ted Kremenekb15eba42008-10-04 05:50:14 +0000197 llvm::FoldingSetNodeID ID;
198 DeclRegion::ProfileRegion(ID, d, superRegion, MemRegion::VarRegionKind);
199
200 void* InsertPos;
201 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
202 VarRegion* R = cast_or_null<VarRegion>(data);
203
204 if (!R) {
205 R = (VarRegion*) A.Allocate<VarRegion>();
206 new (R) VarRegion(d, superRegion);
207 Regions.InsertNode(R, InsertPos);
208 }
209
210 return R;
211}
212
Ted Kremenek6bc91b92008-10-27 20:57:58 +0000213CompoundLiteralRegion*
214MemRegionManager::getCompoundLiteralRegion(const CompoundLiteralExpr* CL) {
215 // Is this compound literal allocated on the stack or is part of the
216 // global constant pool?
217 const MemRegion* superRegion = CL->isFileScope() ?
218 getGlobalsRegion() : getStackRegion();
219
220 // Profile the compound literal.
221 llvm::FoldingSetNodeID ID;
222 CompoundLiteralRegion::ProfileRegion(ID, CL, superRegion);
223
224 void* InsertPos;
225 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
226 CompoundLiteralRegion* R = cast_or_null<CompoundLiteralRegion>(data);
227
228 if (!R) {
229 R = (CompoundLiteralRegion*) A.Allocate<CompoundLiteralRegion>();
230 new (R) CompoundLiteralRegion(CL, superRegion);
231 Regions.InsertNode(R, InsertPos);
232 }
233
234 return R;
235}
236
Zhongxing Xu54969732008-10-21 05:27:10 +0000237ElementRegion* MemRegionManager::getElementRegion(SVal Idx,
238 const MemRegion* superRegion){
239 llvm::FoldingSetNodeID ID;
240 ElementRegion::ProfileRegion(ID, Idx, superRegion);
241
242 void* InsertPos;
243 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
244 ElementRegion* R = cast_or_null<ElementRegion>(data);
245
246 if (!R) {
247 R = (ElementRegion*) A.Allocate<ElementRegion>();
248 new (R) ElementRegion(Idx, superRegion);
249 Regions.InsertNode(R, InsertPos);
250 }
251
252 return R;
253}
254
Ted Kremenek38a4b4b2008-10-17 20:28:54 +0000255/// getSymbolicRegion - Retrieve or create a "symbolic" memory region.
256SymbolicRegion* MemRegionManager::getSymbolicRegion(const SymbolID sym) {
257
258 llvm::FoldingSetNodeID ID;
259 SymbolicRegion::ProfileRegion(ID, sym);
260
261 void* InsertPos;
262 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
263 SymbolicRegion* R = cast_or_null<SymbolicRegion>(data);
264
265 if (!R) {
266 R = (SymbolicRegion*) A.Allocate<SymbolicRegion>();
267 new (R) SymbolicRegion(sym);
268 Regions.InsertNode(R, InsertPos);
269 }
270
271 return R;
272}
273
Ted Kremenekb15eba42008-10-04 05:50:14 +0000274FieldRegion* MemRegionManager::getFieldRegion(const FieldDecl* d,
Ted Kremenek38a4b4b2008-10-17 20:28:54 +0000275 const MemRegion* superRegion) {
Ted Kremenekb15eba42008-10-04 05:50:14 +0000276 llvm::FoldingSetNodeID ID;
277 DeclRegion::ProfileRegion(ID, d, superRegion, MemRegion::FieldRegionKind);
278
279 void* InsertPos;
280 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
281 FieldRegion* R = cast_or_null<FieldRegion>(data);
282
283 if (!R) {
284 R = (FieldRegion*) A.Allocate<FieldRegion>();
285 new (R) FieldRegion(d, superRegion);
286 Regions.InsertNode(R, InsertPos);
287 }
288
289 return R;
290}
291
Ted Kremenek38a4b4b2008-10-17 20:28:54 +0000292ObjCIvarRegion*
293MemRegionManager::getObjCIvarRegion(const ObjCIvarDecl* d,
294 const MemRegion* superRegion) {
Ted Kremenekb15eba42008-10-04 05:50:14 +0000295 llvm::FoldingSetNodeID ID;
296 DeclRegion::ProfileRegion(ID, d, superRegion, MemRegion::ObjCIvarRegionKind);
297
298 void* InsertPos;
299 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
300 ObjCIvarRegion* R = cast_or_null<ObjCIvarRegion>(data);
301
302 if (!R) {
Zhongxing Xu7a861e82008-10-06 03:03:33 +0000303 R = (ObjCIvarRegion*) A.Allocate<ObjCIvarRegion>();
304 new (R) ObjCIvarRegion(d, superRegion);
Ted Kremenekb15eba42008-10-04 05:50:14 +0000305 Regions.InsertNode(R, InsertPos);
306 }
307
308 return R;
309}
310
Ted Kremenek2539c112008-10-24 20:30:08 +0000311ObjCObjectRegion*
312MemRegionManager::getObjCObjectRegion(const ObjCInterfaceDecl* d,
313 const MemRegion* superRegion) {
314 llvm::FoldingSetNodeID ID;
315 DeclRegion::ProfileRegion(ID, d, superRegion,
316 MemRegion::ObjCObjectRegionKind);
317
318 void* InsertPos;
319 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
320 ObjCObjectRegion* R = cast_or_null<ObjCObjectRegion>(data);
321
322 if (!R) {
323 R = (ObjCObjectRegion*) A.Allocate<ObjCObjectRegion>();
324 new (R) ObjCObjectRegion(d, superRegion);
325 Regions.InsertNode(R, InsertPos);
326 }
327
328 return R;
329}
330
331
Zhongxing Xu79c57f82008-10-08 02:50:44 +0000332AnonPointeeRegion* MemRegionManager::getAnonPointeeRegion(const VarDecl* d) {
333 llvm::FoldingSetNodeID ID;
334 QualType T = d->getType();
335 QualType PointeeType = cast<PointerType>(T.getTypePtr())->getPointeeType();
336 MemRegion* superRegion = getUnknownRegion();
337
338 AnonPointeeRegion::ProfileRegion(ID, d, PointeeType, superRegion);
339
340 void* InsertPos;
341 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
342 AnonPointeeRegion* R = cast_or_null<AnonPointeeRegion>(data);
343
344 if (!R) {
345 R = (AnonPointeeRegion*) A.Allocate<AnonPointeeRegion>();
346 new (R) AnonPointeeRegion(d, PointeeType, superRegion);
347 Regions.InsertNode(R, InsertPos);
348 }
349
350 return R;
351}
352
Ted Kremenekb15eba42008-10-04 05:50:14 +0000353bool MemRegionManager::hasStackStorage(const MemRegion* R) {
Ted Kremenek38a4b4b2008-10-17 20:28:54 +0000354 const SubRegion* SR = dyn_cast<SubRegion>(R);
355
356 // Only subregions can have stack storage.
357 if (!SR)
358 return false;
359
Ted Kremenekb15eba42008-10-04 05:50:14 +0000360 MemSpaceRegion* S = getStackRegion();
361
Ted Kremenek38a4b4b2008-10-17 20:28:54 +0000362 while (SR) {
363 R = SR->getSuperRegion();
364 if (R == S)
365 return true;
366
367 SR = dyn_cast<SubRegion>(R);
Ted Kremenekb15eba42008-10-04 05:50:14 +0000368 }
369
370 return false;
371}