blob: bd42858a4fa040665393bfbbf447949dc765cfff [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 Kremenek9e240492008-10-04 05:50:14 +000040void MemSpaceRegion::Profile(llvm::FoldingSetNodeID& ID) const {
41 ID.AddInteger((unsigned)getKind());
42}
43
Zhongxing Xue9f4e542008-10-25 14:13:41 +000044void StringRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
45 const StringLiteral* Str,
46 const MemRegion* superRegion) {
47 ID.AddInteger((unsigned) StringRegionKind);
48 ID.AddPointer(Str);
49 ID.AddPointer(superRegion);
50}
51
Ted Kremenek7090ae12008-11-02 00:34:33 +000052void AllocaRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
53 const Expr* Ex, unsigned cnt) {
54 ID.AddInteger((unsigned) AllocaRegionKind);
55 ID.AddPointer(Ex);
56 ID.AddInteger(cnt);
57}
58
59void AllocaRegion::Profile(llvm::FoldingSetNodeID& ID) const {
60 ProfileRegion(ID, Ex, Cnt);
61}
62
Ted Kremenek0312c0e2009-03-01 05:44:08 +000063void TypedViewRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, QualType T,
Zhongxing Xudc0a25d2008-11-16 04:07:26 +000064 const MemRegion* superRegion) {
Ted Kremenek0312c0e2009-03-01 05:44:08 +000065 ID.AddInteger((unsigned) TypedViewRegionKind);
Zhongxing Xudc0a25d2008-11-16 04:07:26 +000066 ID.Add(T);
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 Kremenek25010132009-06-22 23:13:13 +000093void SymbolicRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, SymbolRef sym,
94 const MemRegion *sreg) {
Ted Kremenek993f1c72008-10-17 20:28:54 +000095 ID.AddInteger((unsigned) MemRegion::SymbolicRegionKind);
Ted Kremenek6d0e2d22008-12-05 02:39:38 +000096 ID.Add(sym);
Ted Kremenek25010132009-06-22 23:13:13 +000097 ID.AddPointer(sreg);
Ted Kremenek993f1c72008-10-17 20:28:54 +000098}
99
100void SymbolicRegion::Profile(llvm::FoldingSetNodeID& ID) const {
Ted Kremenek25010132009-06-22 23:13:13 +0000101 SymbolicRegion::ProfileRegion(ID, sym, getSuperRegion());
Ted Kremenek993f1c72008-10-17 20:28:54 +0000102}
103
Ted Kremenekf936f452009-05-04 06:18:28 +0000104void ElementRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
105 QualType ElementType, SVal Idx,
Zhongxing Xu511191c2008-10-21 05:27:10 +0000106 const MemRegion* superRegion) {
107 ID.AddInteger(MemRegion::ElementRegionKind);
Ted Kremenekf936f452009-05-04 06:18:28 +0000108 ID.Add(ElementType);
Zhongxing Xu511191c2008-10-21 05:27:10 +0000109 ID.AddPointer(superRegion);
110 Idx.Profile(ID);
111}
112
113void ElementRegion::Profile(llvm::FoldingSetNodeID& ID) const {
Ted Kremenekf936f452009-05-04 06:18:28 +0000114 ElementRegion::ProfileRegion(ID, ElementType, Index, superRegion);
Zhongxing Xu511191c2008-10-21 05:27:10 +0000115}
Zhongxing Xu27b57062008-10-27 13:17:02 +0000116
Zhongxing Xuec13d922009-04-10 08:45:10 +0000117void CodeTextRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, const void* data,
118 QualType t) {
119 ID.AddInteger(MemRegion::CodeTextRegionKind);
120 ID.AddPointer(data);
121 ID.Add(t);
122}
123
124void CodeTextRegion::Profile(llvm::FoldingSetNodeID& ID) const {
125 CodeTextRegion::ProfileRegion(ID, Data, LocationType);
126}
127
Zhongxing Xu026c6632009-02-05 06:57:29 +0000128//===----------------------------------------------------------------------===//
Ted Kremenek9e240492008-10-04 05:50:14 +0000129// 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 Kremenek72e03202009-04-21 19:56:58 +0000147void CodeTextRegion::print(llvm::raw_ostream& os) const {
148 os << "code{";
149 if (isDeclared())
Ted Kremenek82539b02009-04-29 15:37:24 +0000150 os << getDecl()->getDeclName().getAsString();
Ted Kremenek72e03202009-04-21 19:56:58 +0000151 else
152 os << '$' << getSymbol();
153
154 os << '}';
155}
156
Ted Kremenek5639a3e2009-04-21 18:09:22 +0000157void CompoundLiteralRegion::print(llvm::raw_ostream& os) const {
158 // FIXME: More elaborate pretty-printing.
159 os << "{ " << (void*) CL << " }";
160}
161
162void ElementRegion::print(llvm::raw_ostream& os) const {
163 superRegion->print(os);
164 os << '['; Index.print(os); os << ']';
165}
166
167void FieldRegion::print(llvm::raw_ostream& os) const {
168 superRegion->print(os);
169 os << "->" << getDecl()->getNameAsString();
170}
171
172void StringRegion::print(llvm::raw_ostream& os) const {
173 Str->printPretty(os);
174}
175
176void SymbolicRegion::print(llvm::raw_ostream& os) const {
177 os << "SymRegion-" << sym;
178}
179
Ted Kremenek0312c0e2009-03-01 05:44:08 +0000180void TypedViewRegion::print(llvm::raw_ostream& os) const {
Ted Kremenekb2dea732009-03-11 21:57:34 +0000181 os << "typed_view{" << LValueType.getAsString() << ',';
Ted Kremenek500d2ee2008-12-17 19:25:50 +0000182 getSuperRegion()->print(os);
183 os << '}';
184}
185
Ted Kremenek9e240492008-10-04 05:50:14 +0000186void VarRegion::print(llvm::raw_ostream& os) const {
Chris Lattnerd9d22dd2008-11-24 05:29:24 +0000187 os << cast<VarDecl>(D)->getNameAsString();
Ted Kremenek9e240492008-10-04 05:50:14 +0000188}
189
190//===----------------------------------------------------------------------===//
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 Xuec13d922009-04-10 08:45:10 +0000220MemSpaceRegion* MemRegionManager::getCodeRegion() {
221 return LazyAllocate(code);
222}
223
Zhongxing Xu4193eca2008-12-20 06:32:12 +0000224bool MemRegionManager::onStack(const MemRegion* R) {
225 while (const SubRegion* SR = dyn_cast<SubRegion>(R))
226 R = SR->getSuperRegion();
227
228 return (R != 0) && (R == stack);
229}
230
231bool MemRegionManager::onHeap(const MemRegion* R) {
232 while (const SubRegion* SR = dyn_cast<SubRegion>(R))
233 R = SR->getSuperRegion();
234
235 return (R != 0) && (R == heap);
236}
237
Ted Kremenek25010132009-06-22 23:13:13 +0000238//===----------------------------------------------------------------------===//
239// Constructing regions.
240//===----------------------------------------------------------------------===//
241
Zhongxing Xue9f4e542008-10-25 14:13:41 +0000242StringRegion* MemRegionManager::getStringRegion(const StringLiteral* Str) {
Ted Kremenek25010132009-06-22 23:13:13 +0000243 return getRegion<StringRegion>(Str);
Zhongxing Xue9f4e542008-10-25 14:13:41 +0000244}
245
Ted Kremenek9a1f03a2008-10-27 21:01:26 +0000246VarRegion* MemRegionManager::getVarRegion(const VarDecl* d) {
Ted Kremenek25010132009-06-22 23:13:13 +0000247 return getRegion<VarRegion>(d);
Ted Kremenek9e240492008-10-04 05:50:14 +0000248}
249
Ted Kremenek329d6fd2008-10-27 20:57:58 +0000250CompoundLiteralRegion*
251MemRegionManager::getCompoundLiteralRegion(const CompoundLiteralExpr* CL) {
Ted Kremenek25010132009-06-22 23:13:13 +0000252 return getRegion<CompoundLiteralRegion>(CL);
Ted Kremenek329d6fd2008-10-27 20:57:58 +0000253}
254
Ted Kremenekabb042f2008-12-13 19:24:37 +0000255ElementRegion*
Ted Kremenekf936f452009-05-04 06:18:28 +0000256MemRegionManager::getElementRegion(QualType elementType, SVal Idx,
Zhongxing Xu143b2fc2009-06-16 09:55:50 +0000257 const MemRegion* superRegion, ASTContext& Ctx){
258
259 QualType T = Ctx.getCanonicalType(elementType);
Ted Kremenekabb042f2008-12-13 19:24:37 +0000260
Zhongxing Xu511191c2008-10-21 05:27:10 +0000261 llvm::FoldingSetNodeID ID;
Zhongxing Xu143b2fc2009-06-16 09:55:50 +0000262 ElementRegion::ProfileRegion(ID, T, Idx, superRegion);
Zhongxing Xu511191c2008-10-21 05:27:10 +0000263
264 void* InsertPos;
265 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
266 ElementRegion* R = cast_or_null<ElementRegion>(data);
267
268 if (!R) {
269 R = (ElementRegion*) A.Allocate<ElementRegion>();
Zhongxing Xu143b2fc2009-06-16 09:55:50 +0000270 new (R) ElementRegion(T, Idx, superRegion);
Zhongxing Xu511191c2008-10-21 05:27:10 +0000271 Regions.InsertNode(R, InsertPos);
272 }
273
274 return R;
275}
276
Zhongxing Xuec13d922009-04-10 08:45:10 +0000277CodeTextRegion* MemRegionManager::getCodeTextRegion(const FunctionDecl* fd,
278 QualType t) {
279 llvm::FoldingSetNodeID ID;
280 CodeTextRegion::ProfileRegion(ID, fd, t);
281 void* InsertPos;
282 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
283 CodeTextRegion* R = cast_or_null<CodeTextRegion>(data);
284
285 if (!R) {
286 R = (CodeTextRegion*) A.Allocate<CodeTextRegion>();
287 new (R) CodeTextRegion(fd, t, getCodeRegion());
288 Regions.InsertNode(R, InsertPos);
289 }
290
291 return R;
292}
293
294CodeTextRegion* MemRegionManager::getCodeTextRegion(SymbolRef sym, QualType t) {
295 llvm::FoldingSetNodeID ID;
296 CodeTextRegion::ProfileRegion(ID, sym, t);
297 void* InsertPos;
298 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
299 CodeTextRegion* R = cast_or_null<CodeTextRegion>(data);
300
301 if (!R) {
302 R = (CodeTextRegion*) A.Allocate<CodeTextRegion>();
303 new (R) CodeTextRegion(sym, t, getCodeRegion());
304 Regions.InsertNode(R, InsertPos);
305 }
306
307 return R;
308}
309
Ted Kremenek993f1c72008-10-17 20:28:54 +0000310/// getSymbolicRegion - Retrieve or create a "symbolic" memory region.
Ted Kremeneke0e4ebf2009-03-26 03:35:11 +0000311SymbolicRegion* MemRegionManager::getSymbolicRegion(SymbolRef sym) {
Ted Kremenek25010132009-06-22 23:13:13 +0000312 return getRegion<SymbolicRegion>(sym);
Ted Kremenek993f1c72008-10-17 20:28:54 +0000313}
314
Ted Kremenek9e240492008-10-04 05:50:14 +0000315FieldRegion* MemRegionManager::getFieldRegion(const FieldDecl* d,
Ted Kremenek993f1c72008-10-17 20:28:54 +0000316 const MemRegion* superRegion) {
Ted Kremenek6304b082009-06-22 23:34:21 +0000317 return getRegion<FieldRegion>(d, superRegion);
Ted Kremenek9e240492008-10-04 05:50:14 +0000318}
319
Ted Kremenek993f1c72008-10-17 20:28:54 +0000320ObjCIvarRegion*
321MemRegionManager::getObjCIvarRegion(const ObjCIvarDecl* d,
322 const MemRegion* superRegion) {
Ted Kremenek6304b082009-06-22 23:34:21 +0000323 return getRegion<ObjCIvarRegion>(d, superRegion);
Ted Kremenek9e240492008-10-04 05:50:14 +0000324}
325
Ted Kremeneka7f1b9e2008-10-24 20:30:08 +0000326ObjCObjectRegion*
327MemRegionManager::getObjCObjectRegion(const ObjCInterfaceDecl* d,
Ted Kremenekded12212009-06-23 00:04:09 +0000328 const MemRegion* superRegion) {
329 return getRegion<ObjCObjectRegion>(d, superRegion);
Ted Kremeneka7f1b9e2008-10-24 20:30:08 +0000330}
331
Ted Kremenek0312c0e2009-03-01 05:44:08 +0000332TypedViewRegion*
333MemRegionManager::getTypedViewRegion(QualType t, const MemRegion* superRegion) {
Ted Kremenekded12212009-06-23 00:04:09 +0000334 return getRegion<TypedViewRegion>(t, superRegion);
Zhongxing Xudc0a25d2008-11-16 04:07:26 +0000335}
Ted Kremeneka7f1b9e2008-10-24 20:30:08 +0000336
Ted Kremenek7090ae12008-11-02 00:34:33 +0000337AllocaRegion* MemRegionManager::getAllocaRegion(const Expr* E, unsigned cnt) {
338 llvm::FoldingSetNodeID ID;
339 AllocaRegion::ProfileRegion(ID, E, cnt);
340
341 void* InsertPos;
342 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
343 AllocaRegion* R = cast_or_null<AllocaRegion>(data);
344
345 if (!R) {
346 R = (AllocaRegion*) A.Allocate<AllocaRegion>();
347 new (R) AllocaRegion(E, cnt, getStackRegion());
348 Regions.InsertNode(R, InsertPos);
349 }
350
351 return R;
352}
353
Ted Kremenek9e240492008-10-04 05:50:14 +0000354bool MemRegionManager::hasStackStorage(const MemRegion* R) {
Ted Kremenek993f1c72008-10-17 20:28:54 +0000355
356 // Only subregions can have stack storage.
Ted Kremenek7090ae12008-11-02 00:34:33 +0000357 const SubRegion* SR = dyn_cast<SubRegion>(R);
358
Ted Kremenek993f1c72008-10-17 20:28:54 +0000359 if (!SR)
360 return false;
Ted Kremenek7090ae12008-11-02 00:34:33 +0000361
Ted Kremenek9e240492008-10-04 05:50:14 +0000362 MemSpaceRegion* S = getStackRegion();
363
Ted Kremenek993f1c72008-10-17 20:28:54 +0000364 while (SR) {
365 R = SR->getSuperRegion();
366 if (R == S)
367 return true;
368
369 SR = dyn_cast<SubRegion>(R);
Ted Kremenek9e240492008-10-04 05:50:14 +0000370 }
Ted Kremenek1670e402009-04-11 00:11:10 +0000371
Ted Kremenek9e240492008-10-04 05:50:14 +0000372 return false;
373}
Ted Kremenek1670e402009-04-11 00:11:10 +0000374
375
376//===----------------------------------------------------------------------===//
377// View handling.
378//===----------------------------------------------------------------------===//
379
380const MemRegion *TypedViewRegion::removeViews() const {
381 const SubRegion *SR = this;
382 const MemRegion *R = SR;
383 while (SR && isa<TypedViewRegion>(SR)) {
384 R = SR->getSuperRegion();
385 SR = dyn_cast<SubRegion>(R);
386 }
387 return R;
388}