blob: ad40f667d33f415025c3680b95dd4e4467b8018f [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,
Ted Kremenek7ae7ad92009-06-23 00:15:41 +000053 const Expr* Ex, unsigned cnt,
54 const MemRegion *) {
Ted Kremenek7090ae12008-11-02 00:34:33 +000055 ID.AddInteger((unsigned) AllocaRegionKind);
56 ID.AddPointer(Ex);
57 ID.AddInteger(cnt);
58}
59
60void AllocaRegion::Profile(llvm::FoldingSetNodeID& ID) const {
Ted Kremenek7ae7ad92009-06-23 00:15:41 +000061 ProfileRegion(ID, Ex, Cnt, superRegion);
Ted Kremenek7090ae12008-11-02 00:34:33 +000062}
63
Ted Kremenek0312c0e2009-03-01 05:44:08 +000064void TypedViewRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, QualType T,
Zhongxing Xudc0a25d2008-11-16 04:07:26 +000065 const MemRegion* superRegion) {
Ted Kremenek0312c0e2009-03-01 05:44:08 +000066 ID.AddInteger((unsigned) TypedViewRegionKind);
Zhongxing Xudc0a25d2008-11-16 04:07:26 +000067 ID.Add(T);
68 ID.AddPointer(superRegion);
69}
70
Ted Kremenek329d6fd2008-10-27 20:57:58 +000071void CompoundLiteralRegion::Profile(llvm::FoldingSetNodeID& ID) const {
72 CompoundLiteralRegion::ProfileRegion(ID, CL, superRegion);
73}
74
75void CompoundLiteralRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
76 const CompoundLiteralExpr* CL,
77 const MemRegion* superRegion) {
78 ID.AddInteger((unsigned) CompoundLiteralRegionKind);
79 ID.AddPointer(CL);
80 ID.AddPointer(superRegion);
81}
82
Ted Kremenek9e240492008-10-04 05:50:14 +000083void DeclRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, const Decl* D,
84 const MemRegion* superRegion, Kind k) {
85 ID.AddInteger((unsigned) k);
86 ID.AddPointer(D);
87 ID.AddPointer(superRegion);
88}
89
90void DeclRegion::Profile(llvm::FoldingSetNodeID& ID) const {
91 DeclRegion::ProfileRegion(ID, D, superRegion, getKind());
92}
93
Ted Kremenek25010132009-06-22 23:13:13 +000094void SymbolicRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, SymbolRef sym,
95 const MemRegion *sreg) {
Ted Kremenek993f1c72008-10-17 20:28:54 +000096 ID.AddInteger((unsigned) MemRegion::SymbolicRegionKind);
Ted Kremenek6d0e2d22008-12-05 02:39:38 +000097 ID.Add(sym);
Ted Kremenek25010132009-06-22 23:13:13 +000098 ID.AddPointer(sreg);
Ted Kremenek993f1c72008-10-17 20:28:54 +000099}
100
101void SymbolicRegion::Profile(llvm::FoldingSetNodeID& ID) const {
Ted Kremenek25010132009-06-22 23:13:13 +0000102 SymbolicRegion::ProfileRegion(ID, sym, getSuperRegion());
Ted Kremenek993f1c72008-10-17 20:28:54 +0000103}
104
Ted Kremenekf936f452009-05-04 06:18:28 +0000105void ElementRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
106 QualType ElementType, SVal Idx,
Zhongxing Xu511191c2008-10-21 05:27:10 +0000107 const MemRegion* superRegion) {
108 ID.AddInteger(MemRegion::ElementRegionKind);
Ted Kremenekf936f452009-05-04 06:18:28 +0000109 ID.Add(ElementType);
Zhongxing Xu511191c2008-10-21 05:27:10 +0000110 ID.AddPointer(superRegion);
111 Idx.Profile(ID);
112}
113
114void ElementRegion::Profile(llvm::FoldingSetNodeID& ID) const {
Ted Kremenekf936f452009-05-04 06:18:28 +0000115 ElementRegion::ProfileRegion(ID, ElementType, Index, superRegion);
Zhongxing Xu511191c2008-10-21 05:27:10 +0000116}
Zhongxing Xu27b57062008-10-27 13:17:02 +0000117
Zhongxing Xuec13d922009-04-10 08:45:10 +0000118void CodeTextRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, const void* data,
119 QualType t) {
120 ID.AddInteger(MemRegion::CodeTextRegionKind);
121 ID.AddPointer(data);
122 ID.Add(t);
123}
124
125void CodeTextRegion::Profile(llvm::FoldingSetNodeID& ID) const {
126 CodeTextRegion::ProfileRegion(ID, Data, LocationType);
127}
128
Zhongxing Xu026c6632009-02-05 06:57:29 +0000129//===----------------------------------------------------------------------===//
Ted Kremenek9e240492008-10-04 05:50:14 +0000130// Region pretty-printing.
131//===----------------------------------------------------------------------===//
132
133std::string MemRegion::getString() const {
134 std::string s;
135 llvm::raw_string_ostream os(s);
136 print(os);
137 return os.str();
138}
139
140void MemRegion::print(llvm::raw_ostream& os) const {
141 os << "<Unknown Region>";
142}
143
Ted Kremenek7090ae12008-11-02 00:34:33 +0000144void AllocaRegion::print(llvm::raw_ostream& os) const {
145 os << "alloca{" << (void*) Ex << ',' << Cnt << '}';
146}
147
Ted Kremenek72e03202009-04-21 19:56:58 +0000148void CodeTextRegion::print(llvm::raw_ostream& os) const {
149 os << "code{";
150 if (isDeclared())
Ted Kremenek82539b02009-04-29 15:37:24 +0000151 os << getDecl()->getDeclName().getAsString();
Ted Kremenek72e03202009-04-21 19:56:58 +0000152 else
153 os << '$' << getSymbol();
154
155 os << '}';
156}
157
Ted Kremenek5639a3e2009-04-21 18:09:22 +0000158void CompoundLiteralRegion::print(llvm::raw_ostream& os) const {
159 // FIXME: More elaborate pretty-printing.
160 os << "{ " << (void*) CL << " }";
161}
162
163void ElementRegion::print(llvm::raw_ostream& os) const {
164 superRegion->print(os);
165 os << '['; Index.print(os); os << ']';
166}
167
168void FieldRegion::print(llvm::raw_ostream& os) const {
169 superRegion->print(os);
170 os << "->" << getDecl()->getNameAsString();
171}
172
173void StringRegion::print(llvm::raw_ostream& os) const {
174 Str->printPretty(os);
175}
176
177void SymbolicRegion::print(llvm::raw_ostream& os) const {
178 os << "SymRegion-" << sym;
179}
180
Ted Kremenek0312c0e2009-03-01 05:44:08 +0000181void TypedViewRegion::print(llvm::raw_ostream& os) const {
Ted Kremenekb2dea732009-03-11 21:57:34 +0000182 os << "typed_view{" << LValueType.getAsString() << ',';
Ted Kremenek500d2ee2008-12-17 19:25:50 +0000183 getSuperRegion()->print(os);
184 os << '}';
185}
186
Ted Kremenek9e240492008-10-04 05:50:14 +0000187void VarRegion::print(llvm::raw_ostream& os) const {
Chris Lattnerd9d22dd2008-11-24 05:29:24 +0000188 os << cast<VarDecl>(D)->getNameAsString();
Ted Kremenek9e240492008-10-04 05:50:14 +0000189}
190
191//===----------------------------------------------------------------------===//
192// MemRegionManager methods.
193//===----------------------------------------------------------------------===//
194
195MemSpaceRegion* MemRegionManager::LazyAllocate(MemSpaceRegion*& region) {
196
197 if (!region) {
198 region = (MemSpaceRegion*) A.Allocate<MemSpaceRegion>();
199 new (region) MemSpaceRegion();
200 }
201
202 return region;
203}
204
205MemSpaceRegion* MemRegionManager::getStackRegion() {
206 return LazyAllocate(stack);
207}
208
209MemSpaceRegion* MemRegionManager::getGlobalsRegion() {
210 return LazyAllocate(globals);
211}
212
213MemSpaceRegion* MemRegionManager::getHeapRegion() {
214 return LazyAllocate(heap);
215}
216
Zhongxing Xu17892752008-10-08 02:50:44 +0000217MemSpaceRegion* MemRegionManager::getUnknownRegion() {
218 return LazyAllocate(unknown);
219}
220
Zhongxing Xuec13d922009-04-10 08:45:10 +0000221MemSpaceRegion* MemRegionManager::getCodeRegion() {
222 return LazyAllocate(code);
223}
224
Zhongxing Xu4193eca2008-12-20 06:32:12 +0000225bool MemRegionManager::onStack(const MemRegion* R) {
226 while (const SubRegion* SR = dyn_cast<SubRegion>(R))
227 R = SR->getSuperRegion();
228
229 return (R != 0) && (R == stack);
230}
231
232bool MemRegionManager::onHeap(const MemRegion* R) {
233 while (const SubRegion* SR = dyn_cast<SubRegion>(R))
234 R = SR->getSuperRegion();
235
236 return (R != 0) && (R == heap);
237}
238
Ted Kremenek25010132009-06-22 23:13:13 +0000239//===----------------------------------------------------------------------===//
240// Constructing regions.
241//===----------------------------------------------------------------------===//
242
Zhongxing Xue9f4e542008-10-25 14:13:41 +0000243StringRegion* MemRegionManager::getStringRegion(const StringLiteral* Str) {
Ted Kremenek25010132009-06-22 23:13:13 +0000244 return getRegion<StringRegion>(Str);
Zhongxing Xue9f4e542008-10-25 14:13:41 +0000245}
246
Ted Kremenek9a1f03a2008-10-27 21:01:26 +0000247VarRegion* MemRegionManager::getVarRegion(const VarDecl* d) {
Ted Kremenek25010132009-06-22 23:13:13 +0000248 return getRegion<VarRegion>(d);
Ted Kremenek9e240492008-10-04 05:50:14 +0000249}
250
Ted Kremenek329d6fd2008-10-27 20:57:58 +0000251CompoundLiteralRegion*
252MemRegionManager::getCompoundLiteralRegion(const CompoundLiteralExpr* CL) {
Ted Kremenek25010132009-06-22 23:13:13 +0000253 return getRegion<CompoundLiteralRegion>(CL);
Ted Kremenek329d6fd2008-10-27 20:57:58 +0000254}
255
Ted Kremenekabb042f2008-12-13 19:24:37 +0000256ElementRegion*
Ted Kremenekf936f452009-05-04 06:18:28 +0000257MemRegionManager::getElementRegion(QualType elementType, SVal Idx,
Zhongxing Xu143b2fc2009-06-16 09:55:50 +0000258 const MemRegion* superRegion, ASTContext& Ctx){
259
260 QualType T = Ctx.getCanonicalType(elementType);
Ted Kremenekabb042f2008-12-13 19:24:37 +0000261
Zhongxing Xu511191c2008-10-21 05:27:10 +0000262 llvm::FoldingSetNodeID ID;
Zhongxing Xu143b2fc2009-06-16 09:55:50 +0000263 ElementRegion::ProfileRegion(ID, T, Idx, superRegion);
Zhongxing Xu511191c2008-10-21 05:27:10 +0000264
265 void* InsertPos;
266 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
267 ElementRegion* R = cast_or_null<ElementRegion>(data);
268
269 if (!R) {
270 R = (ElementRegion*) A.Allocate<ElementRegion>();
Zhongxing Xu143b2fc2009-06-16 09:55:50 +0000271 new (R) ElementRegion(T, Idx, superRegion);
Zhongxing Xu511191c2008-10-21 05:27:10 +0000272 Regions.InsertNode(R, InsertPos);
273 }
274
275 return R;
276}
277
Zhongxing Xuec13d922009-04-10 08:45:10 +0000278CodeTextRegion* MemRegionManager::getCodeTextRegion(const FunctionDecl* fd,
279 QualType t) {
280 llvm::FoldingSetNodeID ID;
281 CodeTextRegion::ProfileRegion(ID, fd, t);
282 void* InsertPos;
283 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
284 CodeTextRegion* R = cast_or_null<CodeTextRegion>(data);
285
286 if (!R) {
287 R = (CodeTextRegion*) A.Allocate<CodeTextRegion>();
288 new (R) CodeTextRegion(fd, t, getCodeRegion());
289 Regions.InsertNode(R, InsertPos);
290 }
291
292 return R;
293}
294
295CodeTextRegion* MemRegionManager::getCodeTextRegion(SymbolRef sym, QualType t) {
296 llvm::FoldingSetNodeID ID;
297 CodeTextRegion::ProfileRegion(ID, sym, t);
298 void* InsertPos;
299 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
300 CodeTextRegion* R = cast_or_null<CodeTextRegion>(data);
301
302 if (!R) {
303 R = (CodeTextRegion*) A.Allocate<CodeTextRegion>();
304 new (R) CodeTextRegion(sym, t, getCodeRegion());
305 Regions.InsertNode(R, InsertPos);
306 }
307
308 return R;
309}
310
Ted Kremenek993f1c72008-10-17 20:28:54 +0000311/// getSymbolicRegion - Retrieve or create a "symbolic" memory region.
Ted Kremeneke0e4ebf2009-03-26 03:35:11 +0000312SymbolicRegion* MemRegionManager::getSymbolicRegion(SymbolRef sym) {
Ted Kremenek25010132009-06-22 23:13:13 +0000313 return getRegion<SymbolicRegion>(sym);
Ted Kremenek993f1c72008-10-17 20:28:54 +0000314}
315
Ted Kremenek9e240492008-10-04 05:50:14 +0000316FieldRegion* MemRegionManager::getFieldRegion(const FieldDecl* d,
Ted Kremenek993f1c72008-10-17 20:28:54 +0000317 const MemRegion* superRegion) {
Ted Kremenek6304b082009-06-22 23:34:21 +0000318 return getRegion<FieldRegion>(d, superRegion);
Ted Kremenek9e240492008-10-04 05:50:14 +0000319}
320
Ted Kremenek993f1c72008-10-17 20:28:54 +0000321ObjCIvarRegion*
322MemRegionManager::getObjCIvarRegion(const ObjCIvarDecl* d,
323 const MemRegion* superRegion) {
Ted Kremenek6304b082009-06-22 23:34:21 +0000324 return getRegion<ObjCIvarRegion>(d, superRegion);
Ted Kremenek9e240492008-10-04 05:50:14 +0000325}
326
Ted Kremeneka7f1b9e2008-10-24 20:30:08 +0000327ObjCObjectRegion*
328MemRegionManager::getObjCObjectRegion(const ObjCInterfaceDecl* d,
Ted Kremenekded12212009-06-23 00:04:09 +0000329 const MemRegion* superRegion) {
330 return getRegion<ObjCObjectRegion>(d, superRegion);
Ted Kremeneka7f1b9e2008-10-24 20:30:08 +0000331}
332
Ted Kremenek0312c0e2009-03-01 05:44:08 +0000333TypedViewRegion*
334MemRegionManager::getTypedViewRegion(QualType t, const MemRegion* superRegion) {
Ted Kremenekded12212009-06-23 00:04:09 +0000335 return getRegion<TypedViewRegion>(t, superRegion);
Zhongxing Xudc0a25d2008-11-16 04:07:26 +0000336}
Ted Kremeneka7f1b9e2008-10-24 20:30:08 +0000337
Ted Kremenek7090ae12008-11-02 00:34:33 +0000338AllocaRegion* MemRegionManager::getAllocaRegion(const Expr* E, unsigned cnt) {
Ted Kremenek7ae7ad92009-06-23 00:15:41 +0000339 return getRegion<AllocaRegion>(E, cnt);
Ted Kremenek7090ae12008-11-02 00:34:33 +0000340}
341
Ted Kremenek9e240492008-10-04 05:50:14 +0000342bool MemRegionManager::hasStackStorage(const MemRegion* R) {
Ted Kremenek993f1c72008-10-17 20:28:54 +0000343
344 // Only subregions can have stack storage.
Ted Kremenek7090ae12008-11-02 00:34:33 +0000345 const SubRegion* SR = dyn_cast<SubRegion>(R);
346
Ted Kremenek993f1c72008-10-17 20:28:54 +0000347 if (!SR)
348 return false;
Ted Kremenek7090ae12008-11-02 00:34:33 +0000349
Ted Kremenek9e240492008-10-04 05:50:14 +0000350 MemSpaceRegion* S = getStackRegion();
351
Ted Kremenek993f1c72008-10-17 20:28:54 +0000352 while (SR) {
353 R = SR->getSuperRegion();
354 if (R == S)
355 return true;
356
357 SR = dyn_cast<SubRegion>(R);
Ted Kremenek9e240492008-10-04 05:50:14 +0000358 }
Ted Kremenek1670e402009-04-11 00:11:10 +0000359
Ted Kremenek9e240492008-10-04 05:50:14 +0000360 return false;
361}
Ted Kremenek1670e402009-04-11 00:11:10 +0000362
363
364//===----------------------------------------------------------------------===//
365// View handling.
366//===----------------------------------------------------------------------===//
367
368const MemRegion *TypedViewRegion::removeViews() const {
369 const SubRegion *SR = this;
370 const MemRegion *R = SR;
371 while (SR && isa<TypedViewRegion>(SR)) {
372 R = SR->getSuperRegion();
373 SR = dyn_cast<SubRegion>(R);
374 }
375 return R;
376}