blob: 98b4cf9eb4cdde3199ae932be2e22495e9fbada8 [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
Ted Kremenek1b85d8e2009-06-22 23:13:13 +000021//===----------------------------------------------------------------------===//
22// Basic methods.
23//===----------------------------------------------------------------------===//
Ted Kremenekb15eba42008-10-04 05:50:14 +000024
25MemRegion::~MemRegion() {}
26
Zhongxing Xub287b212009-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 Kremenekd8f4cef2009-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 Kremenekb15eba42008-10-04 05:50:14 +000053void MemSpaceRegion::Profile(llvm::FoldingSetNodeID& ID) const {
54 ID.AddInteger((unsigned)getKind());
55}
56
Zhongxing Xu73507bd2008-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 Kremenekea9ca502008-11-02 00:34:33 +000065void AllocaRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
Ted Kremenek3680b452009-06-23 00:15:41 +000066 const Expr* Ex, unsigned cnt,
67 const MemRegion *) {
Ted Kremenekea9ca502008-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 Kremenek3680b452009-06-23 00:15:41 +000074 ProfileRegion(ID, Ex, Cnt, superRegion);
Ted Kremenekea9ca502008-11-02 00:34:33 +000075}
76
Ted Kremenek6a9b5352009-03-01 05:44:08 +000077void TypedViewRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, QualType T,
Zhongxing Xu8fbe7ae2008-11-16 04:07:26 +000078 const MemRegion* superRegion) {
Ted Kremenek6a9b5352009-03-01 05:44:08 +000079 ID.AddInteger((unsigned) TypedViewRegionKind);
Zhongxing Xu8fbe7ae2008-11-16 04:07:26 +000080 ID.Add(T);
81 ID.AddPointer(superRegion);
82}
83
Ted Kremenek6bc91b92008-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 Kremenekb15eba42008-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 Kremenek1b85d8e2009-06-22 23:13:13 +0000107void SymbolicRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, SymbolRef sym,
108 const MemRegion *sreg) {
Ted Kremenek38a4b4b2008-10-17 20:28:54 +0000109 ID.AddInteger((unsigned) MemRegion::SymbolicRegionKind);
Ted Kremeneke8993f12008-12-05 02:39:38 +0000110 ID.Add(sym);
Ted Kremenek1b85d8e2009-06-22 23:13:13 +0000111 ID.AddPointer(sreg);
Ted Kremenek38a4b4b2008-10-17 20:28:54 +0000112}
113
114void SymbolicRegion::Profile(llvm::FoldingSetNodeID& ID) const {
Ted Kremenek1b85d8e2009-06-22 23:13:13 +0000115 SymbolicRegion::ProfileRegion(ID, sym, getSuperRegion());
Ted Kremenek38a4b4b2008-10-17 20:28:54 +0000116}
117
Ted Kremenekaf81ece2009-05-04 06:18:28 +0000118void ElementRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
119 QualType ElementType, SVal Idx,
Zhongxing Xu54969732008-10-21 05:27:10 +0000120 const MemRegion* superRegion) {
121 ID.AddInteger(MemRegion::ElementRegionKind);
Ted Kremenekaf81ece2009-05-04 06:18:28 +0000122 ID.Add(ElementType);
Zhongxing Xu54969732008-10-21 05:27:10 +0000123 ID.AddPointer(superRegion);
124 Idx.Profile(ID);
125}
126
127void ElementRegion::Profile(llvm::FoldingSetNodeID& ID) const {
Ted Kremenekaf81ece2009-05-04 06:18:28 +0000128 ElementRegion::ProfileRegion(ID, ElementType, Index, superRegion);
Zhongxing Xu54969732008-10-21 05:27:10 +0000129}
Zhongxing Xu1a563da2008-10-27 13:17:02 +0000130
Zhongxing Xuef3fb4c2009-04-10 08:45:10 +0000131void CodeTextRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, const void* data,
Zhongxing Xu54cd8122009-06-23 03:50:30 +0000132 QualType t, const MemRegion*) {
Zhongxing Xuef3fb4c2009-04-10 08:45:10 +0000133 ID.AddInteger(MemRegion::CodeTextRegionKind);
134 ID.AddPointer(data);
135 ID.Add(t);
136}
137
138void CodeTextRegion::Profile(llvm::FoldingSetNodeID& ID) const {
Zhongxing Xu54cd8122009-06-23 03:50:30 +0000139 CodeTextRegion::ProfileRegion(ID, Data, LocationType, superRegion);
Zhongxing Xuef3fb4c2009-04-10 08:45:10 +0000140}
141
Zhongxing Xu93b80662009-02-05 06:57:29 +0000142//===----------------------------------------------------------------------===//
Ted Kremenekb15eba42008-10-04 05:50:14 +0000143// Region pretty-printing.
144//===----------------------------------------------------------------------===//
145
Ted Kremenekb80d8572009-07-02 17:24:10 +0000146void MemRegion::printStdErr() const {
147 print(llvm::errs());
148}
149
Ted Kremenekb15eba42008-10-04 05:50:14 +0000150std::string MemRegion::getString() const {
151 std::string s;
152 llvm::raw_string_ostream os(s);
153 print(os);
154 return os.str();
155}
156
157void MemRegion::print(llvm::raw_ostream& os) const {
158 os << "<Unknown Region>";
159}
160
Ted Kremenekea9ca502008-11-02 00:34:33 +0000161void AllocaRegion::print(llvm::raw_ostream& os) const {
162 os << "alloca{" << (void*) Ex << ',' << Cnt << '}';
163}
164
Ted Kremenek398efb52009-04-21 19:56:58 +0000165void CodeTextRegion::print(llvm::raw_ostream& os) const {
166 os << "code{";
167 if (isDeclared())
Ted Kremenekb895ed22009-04-29 15:37:24 +0000168 os << getDecl()->getDeclName().getAsString();
Ted Kremenek398efb52009-04-21 19:56:58 +0000169 else
170 os << '$' << getSymbol();
171
172 os << '}';
173}
174
Ted Kremenek3a4beb52009-04-21 18:09:22 +0000175void CompoundLiteralRegion::print(llvm::raw_ostream& os) const {
176 // FIXME: More elaborate pretty-printing.
177 os << "{ " << (void*) CL << " }";
178}
179
180void ElementRegion::print(llvm::raw_ostream& os) const {
181 superRegion->print(os);
182 os << '['; Index.print(os); os << ']';
183}
184
185void FieldRegion::print(llvm::raw_ostream& os) const {
186 superRegion->print(os);
187 os << "->" << getDecl()->getNameAsString();
188}
189
190void StringRegion::print(llvm::raw_ostream& os) const {
Chris Lattner7099c782009-06-30 01:26:17 +0000191 LangOptions LO; // FIXME.
192 Str->printPretty(os, 0, PrintingPolicy(LO));
Ted Kremenek3a4beb52009-04-21 18:09:22 +0000193}
194
195void SymbolicRegion::print(llvm::raw_ostream& os) const {
196 os << "SymRegion-" << sym;
197}
198
Ted Kremenek6a9b5352009-03-01 05:44:08 +0000199void TypedViewRegion::print(llvm::raw_ostream& os) const {
Ted Kremenekd71d13a2009-03-11 21:57:34 +0000200 os << "typed_view{" << LValueType.getAsString() << ',';
Ted Kremenek542c34d2008-12-17 19:25:50 +0000201 getSuperRegion()->print(os);
202 os << '}';
203}
204
Ted Kremenekb15eba42008-10-04 05:50:14 +0000205void VarRegion::print(llvm::raw_ostream& os) const {
Chris Lattner271d4c22008-11-24 05:29:24 +0000206 os << cast<VarDecl>(D)->getNameAsString();
Ted Kremenekb15eba42008-10-04 05:50:14 +0000207}
208
209//===----------------------------------------------------------------------===//
210// MemRegionManager methods.
211//===----------------------------------------------------------------------===//
212
Ted Kremenekd8f4cef2009-06-23 00:46:41 +0000213MemSpaceRegion* MemRegionManager::LazyAllocate(MemSpaceRegion*& region) {
Ted Kremenekb15eba42008-10-04 05:50:14 +0000214 if (!region) {
215 region = (MemSpaceRegion*) A.Allocate<MemSpaceRegion>();
Ted Kremenekd8f4cef2009-06-23 00:46:41 +0000216 new (region) MemSpaceRegion(this);
Ted Kremenekb15eba42008-10-04 05:50:14 +0000217 }
Ted Kremenekd8f4cef2009-06-23 00:46:41 +0000218
Ted Kremenekb15eba42008-10-04 05:50:14 +0000219 return region;
220}
221
222MemSpaceRegion* MemRegionManager::getStackRegion() {
223 return LazyAllocate(stack);
224}
225
226MemSpaceRegion* MemRegionManager::getGlobalsRegion() {
227 return LazyAllocate(globals);
228}
229
230MemSpaceRegion* MemRegionManager::getHeapRegion() {
231 return LazyAllocate(heap);
232}
233
Zhongxing Xu79c57f82008-10-08 02:50:44 +0000234MemSpaceRegion* MemRegionManager::getUnknownRegion() {
235 return LazyAllocate(unknown);
236}
237
Zhongxing Xuef3fb4c2009-04-10 08:45:10 +0000238MemSpaceRegion* MemRegionManager::getCodeRegion() {
239 return LazyAllocate(code);
240}
241
Ted Kremenek1b85d8e2009-06-22 23:13:13 +0000242//===----------------------------------------------------------------------===//
243// Constructing regions.
244//===----------------------------------------------------------------------===//
245
Zhongxing Xu73507bd2008-10-25 14:13:41 +0000246StringRegion* MemRegionManager::getStringRegion(const StringLiteral* Str) {
Ted Kremenek1b85d8e2009-06-22 23:13:13 +0000247 return getRegion<StringRegion>(Str);
Zhongxing Xu73507bd2008-10-25 14:13:41 +0000248}
249
Ted Kremenek81329ab2008-10-27 21:01:26 +0000250VarRegion* MemRegionManager::getVarRegion(const VarDecl* d) {
Ted Kremenek1b85d8e2009-06-22 23:13:13 +0000251 return getRegion<VarRegion>(d);
Ted Kremenekb15eba42008-10-04 05:50:14 +0000252}
253
Ted Kremenek6bc91b92008-10-27 20:57:58 +0000254CompoundLiteralRegion*
255MemRegionManager::getCompoundLiteralRegion(const CompoundLiteralExpr* CL) {
Ted Kremenek1b85d8e2009-06-22 23:13:13 +0000256 return getRegion<CompoundLiteralRegion>(CL);
Ted Kremenek6bc91b92008-10-27 20:57:58 +0000257}
258
Ted Kremenek2c0de352008-12-13 19:24:37 +0000259ElementRegion*
Ted Kremenekaf81ece2009-05-04 06:18:28 +0000260MemRegionManager::getElementRegion(QualType elementType, SVal Idx,
Zhongxing Xufe483ee2009-06-16 09:55:50 +0000261 const MemRegion* superRegion, ASTContext& Ctx){
262
263 QualType T = Ctx.getCanonicalType(elementType);
Ted Kremenek2c0de352008-12-13 19:24:37 +0000264
Zhongxing Xu54969732008-10-21 05:27:10 +0000265 llvm::FoldingSetNodeID ID;
Zhongxing Xufe483ee2009-06-16 09:55:50 +0000266 ElementRegion::ProfileRegion(ID, T, Idx, superRegion);
Zhongxing Xu54969732008-10-21 05:27:10 +0000267
268 void* InsertPos;
269 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
270 ElementRegion* R = cast_or_null<ElementRegion>(data);
271
272 if (!R) {
273 R = (ElementRegion*) A.Allocate<ElementRegion>();
Zhongxing Xufe483ee2009-06-16 09:55:50 +0000274 new (R) ElementRegion(T, Idx, superRegion);
Zhongxing Xu54969732008-10-21 05:27:10 +0000275 Regions.InsertNode(R, InsertPos);
276 }
277
278 return R;
279}
280
Zhongxing Xuef3fb4c2009-04-10 08:45:10 +0000281CodeTextRegion* MemRegionManager::getCodeTextRegion(const FunctionDecl* fd,
282 QualType t) {
Zhongxing Xu54cd8122009-06-23 03:50:30 +0000283 return getRegion<CodeTextRegion>(fd, t);
Zhongxing Xuef3fb4c2009-04-10 08:45:10 +0000284}
285
286CodeTextRegion* MemRegionManager::getCodeTextRegion(SymbolRef sym, QualType t) {
Zhongxing Xu54cd8122009-06-23 03:50:30 +0000287 return getRegion<CodeTextRegion>(sym, t);
Zhongxing Xuef3fb4c2009-04-10 08:45:10 +0000288}
289
Ted Kremenek38a4b4b2008-10-17 20:28:54 +0000290/// getSymbolicRegion - Retrieve or create a "symbolic" memory region.
Ted Kremenek74556a12009-03-26 03:35:11 +0000291SymbolicRegion* MemRegionManager::getSymbolicRegion(SymbolRef sym) {
Ted Kremenek1b85d8e2009-06-22 23:13:13 +0000292 return getRegion<SymbolicRegion>(sym);
Ted Kremenek38a4b4b2008-10-17 20:28:54 +0000293}
294
Ted Kremenekb15eba42008-10-04 05:50:14 +0000295FieldRegion* MemRegionManager::getFieldRegion(const FieldDecl* d,
Ted Kremenek38a4b4b2008-10-17 20:28:54 +0000296 const MemRegion* superRegion) {
Ted Kremenek31839f02009-06-22 23:34:21 +0000297 return getRegion<FieldRegion>(d, superRegion);
Ted Kremenekb15eba42008-10-04 05:50:14 +0000298}
299
Ted Kremenek38a4b4b2008-10-17 20:28:54 +0000300ObjCIvarRegion*
301MemRegionManager::getObjCIvarRegion(const ObjCIvarDecl* d,
302 const MemRegion* superRegion) {
Ted Kremenek31839f02009-06-22 23:34:21 +0000303 return getRegion<ObjCIvarRegion>(d, superRegion);
Ted Kremenekb15eba42008-10-04 05:50:14 +0000304}
305
Ted Kremenek2539c112008-10-24 20:30:08 +0000306ObjCObjectRegion*
307MemRegionManager::getObjCObjectRegion(const ObjCInterfaceDecl* d,
Ted Kremenek12218222009-06-23 00:04:09 +0000308 const MemRegion* superRegion) {
309 return getRegion<ObjCObjectRegion>(d, superRegion);
Ted Kremenek2539c112008-10-24 20:30:08 +0000310}
311
Ted Kremenek6a9b5352009-03-01 05:44:08 +0000312TypedViewRegion*
313MemRegionManager::getTypedViewRegion(QualType t, const MemRegion* superRegion) {
Ted Kremenek12218222009-06-23 00:04:09 +0000314 return getRegion<TypedViewRegion>(t, superRegion);
Zhongxing Xu8fbe7ae2008-11-16 04:07:26 +0000315}
Ted Kremenek2539c112008-10-24 20:30:08 +0000316
Ted Kremenekea9ca502008-11-02 00:34:33 +0000317AllocaRegion* MemRegionManager::getAllocaRegion(const Expr* E, unsigned cnt) {
Ted Kremenek3680b452009-06-23 00:15:41 +0000318 return getRegion<AllocaRegion>(E, cnt);
Ted Kremenekea9ca502008-11-02 00:34:33 +0000319}
320
Ted Kremenek7e5d2922009-06-23 18:17:08 +0000321
322const MemSpaceRegion *MemRegion::getMemorySpace() const {
323 const MemRegion *R = this;
Ted Kremenekdd2ec492009-06-23 18:05:21 +0000324 const SubRegion* SR = dyn_cast<SubRegion>(this);
Ted Kremenekb15eba42008-10-04 05:50:14 +0000325
Ted Kremenek38a4b4b2008-10-17 20:28:54 +0000326 while (SR) {
Ted Kremenek7e5d2922009-06-23 18:17:08 +0000327 R = SR->getSuperRegion();
328 SR = dyn_cast<SubRegion>(R);
Ted Kremenekb15eba42008-10-04 05:50:14 +0000329 }
Ted Kremenek7e5d2922009-06-23 18:17:08 +0000330
331 return dyn_cast<MemSpaceRegion>(R);
332}
333
334bool MemRegion::hasStackStorage() const {
335 if (const MemSpaceRegion *MS = getMemorySpace())
336 return MS == getMemRegionManager()->getStackRegion();
337
Ted Kremenekb15eba42008-10-04 05:50:14 +0000338 return false;
339}
Ted Kremenek8765ebc2009-04-11 00:11:10 +0000340
Ted Kremenekdd2ec492009-06-23 18:05:21 +0000341bool MemRegion::hasHeapStorage() const {
Ted Kremenek7e5d2922009-06-23 18:17:08 +0000342 if (const MemSpaceRegion *MS = getMemorySpace())
343 return MS == getMemRegionManager()->getHeapRegion();
Zhongxing Xu04b97b82009-06-23 02:51:21 +0000344
345 return false;
346}
Ted Kremenek8765ebc2009-04-11 00:11:10 +0000347
Ted Kremenek7e5d2922009-06-23 18:17:08 +0000348bool MemRegion::hasHeapOrStackStorage() const {
349 if (const MemSpaceRegion *MS = getMemorySpace()) {
350 MemRegionManager *Mgr = getMemRegionManager();
351 return MS == Mgr->getHeapRegion() || MS == Mgr->getStackRegion();
352 }
353 return false;
354}
355
Ted Kremenek8765ebc2009-04-11 00:11:10 +0000356//===----------------------------------------------------------------------===//
357// View handling.
358//===----------------------------------------------------------------------===//
359
360const MemRegion *TypedViewRegion::removeViews() const {
361 const SubRegion *SR = this;
362 const MemRegion *R = SR;
363 while (SR && isa<TypedViewRegion>(SR)) {
364 R = SR->getSuperRegion();
365 SR = dyn_cast<SubRegion>(R);
366 }
367 return R;
368}