blob: 619d1617d0006251090fdd783377c1314ddd2fe2 [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
Ted Kremenek25010132009-06-22 23:13:13 +000021//===----------------------------------------------------------------------===//
22// Basic methods.
23//===----------------------------------------------------------------------===//
Ted Kremenek9e240492008-10-04 05:50:14 +000024
25MemRegion::~MemRegion() {}
26
Zhongxing Xu7e5d6ed2009-01-08 13:17:14 +000027bool SubRegion::isSubRegionOf(const MemRegion* R) const {
28 const MemRegion* r = getSuperRegion();
29 while (r != 0) {
30 if (r == R)
31 return true;
32 if (const SubRegion* sr = dyn_cast<SubRegion>(r))
33 r = sr->getSuperRegion();
34 else
35 break;
36 }
37 return false;
38}
39
Ted Kremeneka43484a2009-06-23 00:46:41 +000040
41MemRegionManager* SubRegion::getMemRegionManager() const {
42 const SubRegion* r = this;
43 do {
44 const MemRegion *superRegion = r->getSuperRegion();
45 if (const SubRegion *sr = dyn_cast<SubRegion>(superRegion)) {
46 r = sr;
47 continue;
48 }
49 return superRegion->getMemRegionManager();
50 } while (1);
51}
52
Ted Kremenek9e240492008-10-04 05:50:14 +000053void MemSpaceRegion::Profile(llvm::FoldingSetNodeID& ID) const {
54 ID.AddInteger((unsigned)getKind());
55}
56
Zhongxing Xue9f4e542008-10-25 14:13:41 +000057void StringRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
58 const StringLiteral* Str,
59 const MemRegion* superRegion) {
60 ID.AddInteger((unsigned) StringRegionKind);
61 ID.AddPointer(Str);
62 ID.AddPointer(superRegion);
63}
64
Ted Kremenek7090ae12008-11-02 00:34:33 +000065void AllocaRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
Ted Kremenek7ae7ad92009-06-23 00:15:41 +000066 const Expr* Ex, unsigned cnt,
67 const MemRegion *) {
Ted Kremenek7090ae12008-11-02 00:34:33 +000068 ID.AddInteger((unsigned) AllocaRegionKind);
69 ID.AddPointer(Ex);
70 ID.AddInteger(cnt);
71}
72
73void AllocaRegion::Profile(llvm::FoldingSetNodeID& ID) const {
Ted Kremenek7ae7ad92009-06-23 00:15:41 +000074 ProfileRegion(ID, Ex, Cnt, superRegion);
Ted Kremenek7090ae12008-11-02 00:34:33 +000075}
76
Ted Kremenek0312c0e2009-03-01 05:44:08 +000077void TypedViewRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, QualType T,
Zhongxing Xudc0a25d2008-11-16 04:07:26 +000078 const MemRegion* superRegion) {
Ted Kremenek0312c0e2009-03-01 05:44:08 +000079 ID.AddInteger((unsigned) TypedViewRegionKind);
Zhongxing Xudc0a25d2008-11-16 04:07:26 +000080 ID.Add(T);
81 ID.AddPointer(superRegion);
82}
83
Ted Kremenek329d6fd2008-10-27 20:57:58 +000084void CompoundLiteralRegion::Profile(llvm::FoldingSetNodeID& ID) const {
85 CompoundLiteralRegion::ProfileRegion(ID, CL, superRegion);
86}
87
88void CompoundLiteralRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
89 const CompoundLiteralExpr* CL,
90 const MemRegion* superRegion) {
91 ID.AddInteger((unsigned) CompoundLiteralRegionKind);
92 ID.AddPointer(CL);
93 ID.AddPointer(superRegion);
94}
95
Ted Kremenek9e240492008-10-04 05:50:14 +000096void DeclRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, const Decl* D,
97 const MemRegion* superRegion, Kind k) {
98 ID.AddInteger((unsigned) k);
99 ID.AddPointer(D);
100 ID.AddPointer(superRegion);
101}
102
103void DeclRegion::Profile(llvm::FoldingSetNodeID& ID) const {
104 DeclRegion::ProfileRegion(ID, D, superRegion, getKind());
105}
106
Ted Kremenek25010132009-06-22 23:13:13 +0000107void SymbolicRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, SymbolRef sym,
108 const MemRegion *sreg) {
Ted Kremenek993f1c72008-10-17 20:28:54 +0000109 ID.AddInteger((unsigned) MemRegion::SymbolicRegionKind);
Ted Kremenek6d0e2d22008-12-05 02:39:38 +0000110 ID.Add(sym);
Ted Kremenek25010132009-06-22 23:13:13 +0000111 ID.AddPointer(sreg);
Ted Kremenek993f1c72008-10-17 20:28:54 +0000112}
113
114void SymbolicRegion::Profile(llvm::FoldingSetNodeID& ID) const {
Ted Kremenek25010132009-06-22 23:13:13 +0000115 SymbolicRegion::ProfileRegion(ID, sym, getSuperRegion());
Ted Kremenek993f1c72008-10-17 20:28:54 +0000116}
117
Ted Kremenekf936f452009-05-04 06:18:28 +0000118void ElementRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
119 QualType ElementType, SVal Idx,
Zhongxing Xu511191c2008-10-21 05:27:10 +0000120 const MemRegion* superRegion) {
121 ID.AddInteger(MemRegion::ElementRegionKind);
Ted Kremenekf936f452009-05-04 06:18:28 +0000122 ID.Add(ElementType);
Zhongxing Xu511191c2008-10-21 05:27:10 +0000123 ID.AddPointer(superRegion);
124 Idx.Profile(ID);
125}
126
127void ElementRegion::Profile(llvm::FoldingSetNodeID& ID) const {
Ted Kremenekf936f452009-05-04 06:18:28 +0000128 ElementRegion::ProfileRegion(ID, ElementType, Index, superRegion);
Zhongxing Xu511191c2008-10-21 05:27:10 +0000129}
Zhongxing Xu27b57062008-10-27 13:17:02 +0000130
Zhongxing Xuec13d922009-04-10 08:45:10 +0000131void CodeTextRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, const void* data,
132 QualType t) {
133 ID.AddInteger(MemRegion::CodeTextRegionKind);
134 ID.AddPointer(data);
135 ID.Add(t);
136}
137
138void CodeTextRegion::Profile(llvm::FoldingSetNodeID& ID) const {
139 CodeTextRegion::ProfileRegion(ID, Data, LocationType);
140}
141
Zhongxing Xu026c6632009-02-05 06:57:29 +0000142//===----------------------------------------------------------------------===//
Ted Kremenek9e240492008-10-04 05:50:14 +0000143// Region pretty-printing.
144//===----------------------------------------------------------------------===//
145
146std::string MemRegion::getString() const {
147 std::string s;
148 llvm::raw_string_ostream os(s);
149 print(os);
150 return os.str();
151}
152
153void MemRegion::print(llvm::raw_ostream& os) const {
154 os << "<Unknown Region>";
155}
156
Ted Kremenek7090ae12008-11-02 00:34:33 +0000157void AllocaRegion::print(llvm::raw_ostream& os) const {
158 os << "alloca{" << (void*) Ex << ',' << Cnt << '}';
159}
160
Ted Kremenek72e03202009-04-21 19:56:58 +0000161void CodeTextRegion::print(llvm::raw_ostream& os) const {
162 os << "code{";
163 if (isDeclared())
Ted Kremenek82539b02009-04-29 15:37:24 +0000164 os << getDecl()->getDeclName().getAsString();
Ted Kremenek72e03202009-04-21 19:56:58 +0000165 else
166 os << '$' << getSymbol();
167
168 os << '}';
169}
170
Ted Kremenek5639a3e2009-04-21 18:09:22 +0000171void CompoundLiteralRegion::print(llvm::raw_ostream& os) const {
172 // FIXME: More elaborate pretty-printing.
173 os << "{ " << (void*) CL << " }";
174}
175
176void ElementRegion::print(llvm::raw_ostream& os) const {
177 superRegion->print(os);
178 os << '['; Index.print(os); os << ']';
179}
180
181void FieldRegion::print(llvm::raw_ostream& os) const {
182 superRegion->print(os);
183 os << "->" << getDecl()->getNameAsString();
184}
185
186void StringRegion::print(llvm::raw_ostream& os) const {
187 Str->printPretty(os);
188}
189
190void SymbolicRegion::print(llvm::raw_ostream& os) const {
191 os << "SymRegion-" << sym;
192}
193
Ted Kremenek0312c0e2009-03-01 05:44:08 +0000194void TypedViewRegion::print(llvm::raw_ostream& os) const {
Ted Kremenekb2dea732009-03-11 21:57:34 +0000195 os << "typed_view{" << LValueType.getAsString() << ',';
Ted Kremenek500d2ee2008-12-17 19:25:50 +0000196 getSuperRegion()->print(os);
197 os << '}';
198}
199
Ted Kremenek9e240492008-10-04 05:50:14 +0000200void VarRegion::print(llvm::raw_ostream& os) const {
Chris Lattnerd9d22dd2008-11-24 05:29:24 +0000201 os << cast<VarDecl>(D)->getNameAsString();
Ted Kremenek9e240492008-10-04 05:50:14 +0000202}
203
204//===----------------------------------------------------------------------===//
205// MemRegionManager methods.
206//===----------------------------------------------------------------------===//
207
Ted Kremeneka43484a2009-06-23 00:46:41 +0000208MemSpaceRegion* MemRegionManager::LazyAllocate(MemSpaceRegion*& region) {
Ted Kremenek9e240492008-10-04 05:50:14 +0000209 if (!region) {
210 region = (MemSpaceRegion*) A.Allocate<MemSpaceRegion>();
Ted Kremeneka43484a2009-06-23 00:46:41 +0000211 new (region) MemSpaceRegion(this);
Ted Kremenek9e240492008-10-04 05:50:14 +0000212 }
Ted Kremeneka43484a2009-06-23 00:46:41 +0000213
Ted Kremenek9e240492008-10-04 05:50:14 +0000214 return region;
215}
216
217MemSpaceRegion* MemRegionManager::getStackRegion() {
218 return LazyAllocate(stack);
219}
220
221MemSpaceRegion* MemRegionManager::getGlobalsRegion() {
222 return LazyAllocate(globals);
223}
224
225MemSpaceRegion* MemRegionManager::getHeapRegion() {
226 return LazyAllocate(heap);
227}
228
Zhongxing Xu17892752008-10-08 02:50:44 +0000229MemSpaceRegion* MemRegionManager::getUnknownRegion() {
230 return LazyAllocate(unknown);
231}
232
Zhongxing Xuec13d922009-04-10 08:45:10 +0000233MemSpaceRegion* MemRegionManager::getCodeRegion() {
234 return LazyAllocate(code);
235}
236
Ted Kremenek25010132009-06-22 23:13:13 +0000237//===----------------------------------------------------------------------===//
238// Constructing regions.
239//===----------------------------------------------------------------------===//
240
Zhongxing Xue9f4e542008-10-25 14:13:41 +0000241StringRegion* MemRegionManager::getStringRegion(const StringLiteral* Str) {
Ted Kremenek25010132009-06-22 23:13:13 +0000242 return getRegion<StringRegion>(Str);
Zhongxing Xue9f4e542008-10-25 14:13:41 +0000243}
244
Ted Kremenek9a1f03a2008-10-27 21:01:26 +0000245VarRegion* MemRegionManager::getVarRegion(const VarDecl* d) {
Ted Kremenek25010132009-06-22 23:13:13 +0000246 return getRegion<VarRegion>(d);
Ted Kremenek9e240492008-10-04 05:50:14 +0000247}
248
Ted Kremenek329d6fd2008-10-27 20:57:58 +0000249CompoundLiteralRegion*
250MemRegionManager::getCompoundLiteralRegion(const CompoundLiteralExpr* CL) {
Ted Kremenek25010132009-06-22 23:13:13 +0000251 return getRegion<CompoundLiteralRegion>(CL);
Ted Kremenek329d6fd2008-10-27 20:57:58 +0000252}
253
Ted Kremenekabb042f2008-12-13 19:24:37 +0000254ElementRegion*
Ted Kremenekf936f452009-05-04 06:18:28 +0000255MemRegionManager::getElementRegion(QualType elementType, SVal Idx,
Zhongxing Xu143b2fc2009-06-16 09:55:50 +0000256 const MemRegion* superRegion, ASTContext& Ctx){
257
258 QualType T = Ctx.getCanonicalType(elementType);
Ted Kremenekabb042f2008-12-13 19:24:37 +0000259
Zhongxing Xu511191c2008-10-21 05:27:10 +0000260 llvm::FoldingSetNodeID ID;
Zhongxing Xu143b2fc2009-06-16 09:55:50 +0000261 ElementRegion::ProfileRegion(ID, T, Idx, superRegion);
Zhongxing Xu511191c2008-10-21 05:27:10 +0000262
263 void* InsertPos;
264 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
265 ElementRegion* R = cast_or_null<ElementRegion>(data);
266
267 if (!R) {
268 R = (ElementRegion*) A.Allocate<ElementRegion>();
Zhongxing Xu143b2fc2009-06-16 09:55:50 +0000269 new (R) ElementRegion(T, Idx, superRegion);
Zhongxing Xu511191c2008-10-21 05:27:10 +0000270 Regions.InsertNode(R, InsertPos);
271 }
272
273 return R;
274}
275
Zhongxing Xuec13d922009-04-10 08:45:10 +0000276CodeTextRegion* MemRegionManager::getCodeTextRegion(const FunctionDecl* fd,
277 QualType t) {
278 llvm::FoldingSetNodeID ID;
279 CodeTextRegion::ProfileRegion(ID, fd, t);
280 void* InsertPos;
281 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
282 CodeTextRegion* R = cast_or_null<CodeTextRegion>(data);
283
284 if (!R) {
285 R = (CodeTextRegion*) A.Allocate<CodeTextRegion>();
286 new (R) CodeTextRegion(fd, t, getCodeRegion());
287 Regions.InsertNode(R, InsertPos);
288 }
289
290 return R;
291}
292
293CodeTextRegion* MemRegionManager::getCodeTextRegion(SymbolRef sym, QualType t) {
294 llvm::FoldingSetNodeID ID;
295 CodeTextRegion::ProfileRegion(ID, sym, t);
296 void* InsertPos;
297 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
298 CodeTextRegion* R = cast_or_null<CodeTextRegion>(data);
299
300 if (!R) {
301 R = (CodeTextRegion*) A.Allocate<CodeTextRegion>();
302 new (R) CodeTextRegion(sym, t, getCodeRegion());
303 Regions.InsertNode(R, InsertPos);
304 }
305
306 return R;
307}
308
Ted Kremenek993f1c72008-10-17 20:28:54 +0000309/// getSymbolicRegion - Retrieve or create a "symbolic" memory region.
Ted Kremeneke0e4ebf2009-03-26 03:35:11 +0000310SymbolicRegion* MemRegionManager::getSymbolicRegion(SymbolRef sym) {
Ted Kremenek25010132009-06-22 23:13:13 +0000311 return getRegion<SymbolicRegion>(sym);
Ted Kremenek993f1c72008-10-17 20:28:54 +0000312}
313
Ted Kremenek9e240492008-10-04 05:50:14 +0000314FieldRegion* MemRegionManager::getFieldRegion(const FieldDecl* d,
Ted Kremenek993f1c72008-10-17 20:28:54 +0000315 const MemRegion* superRegion) {
Ted Kremenek6304b082009-06-22 23:34:21 +0000316 return getRegion<FieldRegion>(d, superRegion);
Ted Kremenek9e240492008-10-04 05:50:14 +0000317}
318
Ted Kremenek993f1c72008-10-17 20:28:54 +0000319ObjCIvarRegion*
320MemRegionManager::getObjCIvarRegion(const ObjCIvarDecl* d,
321 const MemRegion* superRegion) {
Ted Kremenek6304b082009-06-22 23:34:21 +0000322 return getRegion<ObjCIvarRegion>(d, superRegion);
Ted Kremenek9e240492008-10-04 05:50:14 +0000323}
324
Ted Kremeneka7f1b9e2008-10-24 20:30:08 +0000325ObjCObjectRegion*
326MemRegionManager::getObjCObjectRegion(const ObjCInterfaceDecl* d,
Ted Kremenekded12212009-06-23 00:04:09 +0000327 const MemRegion* superRegion) {
328 return getRegion<ObjCObjectRegion>(d, superRegion);
Ted Kremeneka7f1b9e2008-10-24 20:30:08 +0000329}
330
Ted Kremenek0312c0e2009-03-01 05:44:08 +0000331TypedViewRegion*
332MemRegionManager::getTypedViewRegion(QualType t, const MemRegion* superRegion) {
Ted Kremenekded12212009-06-23 00:04:09 +0000333 return getRegion<TypedViewRegion>(t, superRegion);
Zhongxing Xudc0a25d2008-11-16 04:07:26 +0000334}
Ted Kremeneka7f1b9e2008-10-24 20:30:08 +0000335
Ted Kremenek7090ae12008-11-02 00:34:33 +0000336AllocaRegion* MemRegionManager::getAllocaRegion(const Expr* E, unsigned cnt) {
Ted Kremenek7ae7ad92009-06-23 00:15:41 +0000337 return getRegion<AllocaRegion>(E, cnt);
Ted Kremenek7090ae12008-11-02 00:34:33 +0000338}
339
Ted Kremenek9e240492008-10-04 05:50:14 +0000340bool MemRegionManager::hasStackStorage(const MemRegion* R) {
Ted Kremenek993f1c72008-10-17 20:28:54 +0000341 // Only subregions can have stack storage.
Ted Kremenek7090ae12008-11-02 00:34:33 +0000342 const SubRegion* SR = dyn_cast<SubRegion>(R);
343
Ted Kremenek993f1c72008-10-17 20:28:54 +0000344 if (!SR)
345 return false;
Ted Kremenek7090ae12008-11-02 00:34:33 +0000346
Ted Kremenek9e240492008-10-04 05:50:14 +0000347 MemSpaceRegion* S = getStackRegion();
348
Ted Kremenek993f1c72008-10-17 20:28:54 +0000349 while (SR) {
350 R = SR->getSuperRegion();
351 if (R == S)
352 return true;
353
354 SR = dyn_cast<SubRegion>(R);
Ted Kremenek9e240492008-10-04 05:50:14 +0000355 }
Zhongxing Xudd198f02009-06-23 02:51:21 +0000356
Ted Kremenek9e240492008-10-04 05:50:14 +0000357 return false;
358}
Ted Kremenek1670e402009-04-11 00:11:10 +0000359
Zhongxing Xudd198f02009-06-23 02:51:21 +0000360bool MemRegionManager::hasHeapStorage(const MemRegion* R) {
361 // Only subregions can have stack storage.
362 const SubRegion* SR = dyn_cast<SubRegion>(R);
363
364 if (!SR)
365 return false;
366
367 MemSpaceRegion* H = getHeapRegion();
368
369 while (SR) {
370 R = SR->getSuperRegion();
371 if (R == H)
372 return true;
373
374 SR = dyn_cast<SubRegion>(R);
375 }
376
377 return false;
378}
Ted Kremenek1670e402009-04-11 00:11:10 +0000379
380//===----------------------------------------------------------------------===//
381// View handling.
382//===----------------------------------------------------------------------===//
383
384const MemRegion *TypedViewRegion::removeViews() const {
385 const SubRegion *SR = this;
386 const MemRegion *R = SR;
387 while (SR && isa<TypedViewRegion>(SR)) {
388 R = SR->getSuperRegion();
389 SR = dyn_cast<SubRegion>(R);
390 }
391 return R;
392}