blob: 9cf3196aae1ef4a1d2371712e48d8b6c456a3d5a [file] [log] [blame]
Ted Kremenek5ca90a22008-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"
Ted Kremenek1f22aa72009-08-01 06:17:29 +000018#include "clang/Analysis/PathSensitive/ValueManager.h"
Ted Kremenek608677a2009-08-21 23:25:54 +000019#include "clang/Analysis/PathSensitive/AnalysisContext.h"
Ted Kremenek3378b612009-11-26 02:34:36 +000020#include "clang/AST/StmtVisitor.h"
Ted Kremenek5ca90a22008-10-04 05:50:14 +000021
22using namespace clang;
23
Ted Kremeneke5e8b0b2009-06-22 23:13:13 +000024//===----------------------------------------------------------------------===//
Ted Kremenek3378b612009-11-26 02:34:36 +000025// Object destruction.
Ted Kremeneke5e8b0b2009-06-22 23:13:13 +000026//===----------------------------------------------------------------------===//
Ted Kremenek5ca90a22008-10-04 05:50:14 +000027
28MemRegion::~MemRegion() {}
29
Ted Kremenek3378b612009-11-26 02:34:36 +000030MemRegionManager::~MemRegionManager() {
31 // All regions and their data are BumpPtrAllocated. No need to call
32 // their destructors.
33}
34
35//===----------------------------------------------------------------------===//
36// Basic methods.
37//===----------------------------------------------------------------------===//
38
Zhongxing Xu550c1c42009-01-08 13:17:14 +000039bool SubRegion::isSubRegionOf(const MemRegion* R) const {
40 const MemRegion* r = getSuperRegion();
41 while (r != 0) {
42 if (r == R)
43 return true;
44 if (const SubRegion* sr = dyn_cast<SubRegion>(r))
45 r = sr->getSuperRegion();
46 else
47 break;
48 }
49 return false;
50}
51
Ted Kremenekfb87e302009-06-23 00:46:41 +000052MemRegionManager* SubRegion::getMemRegionManager() const {
53 const SubRegion* r = this;
54 do {
55 const MemRegion *superRegion = r->getSuperRegion();
56 if (const SubRegion *sr = dyn_cast<SubRegion>(superRegion)) {
57 r = sr;
58 continue;
59 }
60 return superRegion->getMemRegionManager();
61 } while (1);
62}
63
Ted Kremenek5ca90a22008-10-04 05:50:14 +000064void MemSpaceRegion::Profile(llvm::FoldingSetNodeID& ID) const {
65 ID.AddInteger((unsigned)getKind());
66}
67
Mike Stump11289f42009-09-09 15:08:12 +000068void StringRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
69 const StringLiteral* Str,
Zhongxing Xud1aac352008-10-25 14:13:41 +000070 const MemRegion* superRegion) {
71 ID.AddInteger((unsigned) StringRegionKind);
72 ID.AddPointer(Str);
73 ID.AddPointer(superRegion);
74}
75
Ted Kremenek16783cf2008-11-02 00:34:33 +000076void AllocaRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
Ted Kremenek8bae3002009-06-23 00:15:41 +000077 const Expr* Ex, unsigned cnt,
78 const MemRegion *) {
Ted Kremenek16783cf2008-11-02 00:34:33 +000079 ID.AddInteger((unsigned) AllocaRegionKind);
80 ID.AddPointer(Ex);
81 ID.AddInteger(cnt);
82}
83
84void AllocaRegion::Profile(llvm::FoldingSetNodeID& ID) const {
Ted Kremenek8bae3002009-06-23 00:15:41 +000085 ProfileRegion(ID, Ex, Cnt, superRegion);
Ted Kremenek16783cf2008-11-02 00:34:33 +000086}
87
Ted Kremenekbc48caf2008-10-27 20:57:58 +000088void CompoundLiteralRegion::Profile(llvm::FoldingSetNodeID& ID) const {
89 CompoundLiteralRegion::ProfileRegion(ID, CL, superRegion);
90}
91
92void CompoundLiteralRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
93 const CompoundLiteralExpr* CL,
94 const MemRegion* superRegion) {
95 ID.AddInteger((unsigned) CompoundLiteralRegionKind);
96 ID.AddPointer(CL);
97 ID.AddPointer(superRegion);
98}
99
Ted Kremenek5ca90a22008-10-04 05:50:14 +0000100void DeclRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, const Decl* D,
101 const MemRegion* superRegion, Kind k) {
102 ID.AddInteger((unsigned) k);
103 ID.AddPointer(D);
104 ID.AddPointer(superRegion);
105}
106
107void DeclRegion::Profile(llvm::FoldingSetNodeID& ID) const {
108 DeclRegion::ProfileRegion(ID, D, superRegion, getKind());
109}
110
Ted Kremenek14536f62009-08-21 22:28:32 +0000111void VarRegion::Profile(llvm::FoldingSetNodeID &ID) const {
112 VarRegion::ProfileRegion(ID, getDecl(), LC, superRegion);
113}
114
Ted Kremeneke5e8b0b2009-06-22 23:13:13 +0000115void SymbolicRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, SymbolRef sym,
116 const MemRegion *sreg) {
Ted Kremenek8b103c62008-10-17 20:28:54 +0000117 ID.AddInteger((unsigned) MemRegion::SymbolicRegionKind);
Ted Kremenek3cb81db2008-12-05 02:39:38 +0000118 ID.Add(sym);
Ted Kremeneke5e8b0b2009-06-22 23:13:13 +0000119 ID.AddPointer(sreg);
Ted Kremenek8b103c62008-10-17 20:28:54 +0000120}
121
122void SymbolicRegion::Profile(llvm::FoldingSetNodeID& ID) const {
Ted Kremeneke5e8b0b2009-06-22 23:13:13 +0000123 SymbolicRegion::ProfileRegion(ID, sym, getSuperRegion());
Ted Kremenek8b103c62008-10-17 20:28:54 +0000124}
125
Ted Kremenek02e50892009-05-04 06:18:28 +0000126void ElementRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
Mike Stump11289f42009-09-09 15:08:12 +0000127 QualType ElementType, SVal Idx,
Zhongxing Xud8fe46b2008-10-21 05:27:10 +0000128 const MemRegion* superRegion) {
129 ID.AddInteger(MemRegion::ElementRegionKind);
Ted Kremenek02e50892009-05-04 06:18:28 +0000130 ID.Add(ElementType);
Zhongxing Xud8fe46b2008-10-21 05:27:10 +0000131 ID.AddPointer(superRegion);
132 Idx.Profile(ID);
133}
134
135void ElementRegion::Profile(llvm::FoldingSetNodeID& ID) const {
Ted Kremenek02e50892009-05-04 06:18:28 +0000136 ElementRegion::ProfileRegion(ID, ElementType, Index, superRegion);
Zhongxing Xud8fe46b2008-10-21 05:27:10 +0000137}
Zhongxing Xu7b700572008-10-27 13:17:02 +0000138
Ted Kremenek10a50e72009-11-25 01:32:22 +0000139void FunctionTextRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
140 const FunctionDecl *FD,
141 const MemRegion*) {
142 ID.AddInteger(MemRegion::FunctionTextRegionKind);
Ted Kremenek198a8c52009-08-28 04:49:15 +0000143 ID.AddPointer(FD);
Zhongxing Xu1aced0c2009-04-10 08:45:10 +0000144}
145
Ted Kremenek10a50e72009-11-25 01:32:22 +0000146void FunctionTextRegion::Profile(llvm::FoldingSetNodeID& ID) const {
147 FunctionTextRegion::ProfileRegion(ID, FD, superRegion);
148}
149
150void BlockTextRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
151 const BlockDecl *BD, CanQualType,
152 const MemRegion*) {
153 ID.AddInteger(MemRegion::BlockTextRegionKind);
154 ID.AddPointer(BD);
155}
156
157void BlockTextRegion::Profile(llvm::FoldingSetNodeID& ID) const {
158 BlockTextRegion::ProfileRegion(ID, BD, locTy, superRegion);
Zhongxing Xu1aced0c2009-04-10 08:45:10 +0000159}
160
Ted Kremenekb63ad7a2009-11-25 23:53:07 +0000161void BlockDataRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
162 const BlockTextRegion *BC,
163 const LocationContext *LC,
164 const MemRegion *) {
165 ID.AddInteger(MemRegion::BlockDataRegionKind);
166 ID.AddPointer(BC);
167 ID.AddPointer(LC);
168}
169
170void BlockDataRegion::Profile(llvm::FoldingSetNodeID& ID) const {
171 BlockDataRegion::ProfileRegion(ID, BC, LC, NULL);
172}
173
Zhongxing Xu9103df12009-02-05 06:57:29 +0000174//===----------------------------------------------------------------------===//
Ted Kremenek5ca90a22008-10-04 05:50:14 +0000175// Region pretty-printing.
176//===----------------------------------------------------------------------===//
177
Ted Kremenekeabdd982009-07-13 23:31:04 +0000178void MemRegion::dump() const {
179 dumpToStream(llvm::errs());
Ted Kremenekdf15d292009-07-02 17:24:10 +0000180}
181
Ted Kremenek5ca90a22008-10-04 05:50:14 +0000182std::string MemRegion::getString() const {
183 std::string s;
184 llvm::raw_string_ostream os(s);
Ted Kremenekeabdd982009-07-13 23:31:04 +0000185 dumpToStream(os);
Ted Kremenek5ca90a22008-10-04 05:50:14 +0000186 return os.str();
187}
188
Ted Kremenekeabdd982009-07-13 23:31:04 +0000189void MemRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenek5ca90a22008-10-04 05:50:14 +0000190 os << "<Unknown Region>";
191}
192
Ted Kremenekeabdd982009-07-13 23:31:04 +0000193void AllocaRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenek16783cf2008-11-02 00:34:33 +0000194 os << "alloca{" << (void*) Ex << ',' << Cnt << '}';
195}
196
Ted Kremenek10a50e72009-11-25 01:32:22 +0000197void FunctionTextRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenek198a8c52009-08-28 04:49:15 +0000198 os << "code{" << getDecl()->getDeclName().getAsString() << '}';
Ted Kremenek9bb660c2009-04-21 19:56:58 +0000199}
200
Ted Kremenek10a50e72009-11-25 01:32:22 +0000201void BlockTextRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenekb63ad7a2009-11-25 23:53:07 +0000202 os << "block_code{" << (void*) this << '}';
Ted Kremenek10a50e72009-11-25 01:32:22 +0000203}
204
Ted Kremenekb63ad7a2009-11-25 23:53:07 +0000205void BlockDataRegion::dumpToStream(llvm::raw_ostream& os) const {
206 os << "block_data{" << BC << '}';
207}
208
209
Ted Kremenekeabdd982009-07-13 23:31:04 +0000210void CompoundLiteralRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenek7421c012009-04-21 18:09:22 +0000211 // FIXME: More elaborate pretty-printing.
212 os << "{ " << (void*) CL << " }";
213}
214
Ted Kremenekeabdd982009-07-13 23:31:04 +0000215void ElementRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenek1f22aa72009-08-01 06:17:29 +0000216 os << "element{" << superRegion << ','
217 << Index << ',' << getElementType().getAsString() << '}';
Ted Kremenek7421c012009-04-21 18:09:22 +0000218}
219
Ted Kremenekeabdd982009-07-13 23:31:04 +0000220void FieldRegion::dumpToStream(llvm::raw_ostream& os) const {
221 os << superRegion << "->" << getDecl()->getNameAsString();
Ted Kremenek7421c012009-04-21 18:09:22 +0000222}
223
Ted Kremenek291e8f72009-07-19 20:36:24 +0000224void ObjCIvarRegion::dumpToStream(llvm::raw_ostream& os) const {
225 os << "ivar{" << superRegion << ',' << getDecl()->getNameAsString() << '}';
226}
227
Mike Stump11289f42009-09-09 15:08:12 +0000228void StringRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenek7d3a3342009-07-19 20:38:24 +0000229 Str->printPretty(os, 0, PrintingPolicy(getContext().getLangOptions()));
Ted Kremenek7421c012009-04-21 18:09:22 +0000230}
231
Ted Kremenekeabdd982009-07-13 23:31:04 +0000232void SymbolicRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenekc8d67462009-07-13 23:38:57 +0000233 os << "SymRegion{" << sym << '}';
Ted Kremenek7421c012009-04-21 18:09:22 +0000234}
235
Ted Kremenekeabdd982009-07-13 23:31:04 +0000236void VarRegion::dumpToStream(llvm::raw_ostream& os) const {
Chris Lattnerf3d3fae2008-11-24 05:29:24 +0000237 os << cast<VarDecl>(D)->getNameAsString();
Ted Kremenek5ca90a22008-10-04 05:50:14 +0000238}
239
Ted Kremenek1f22aa72009-08-01 06:17:29 +0000240void RegionRawOffset::dump() const {
241 dumpToStream(llvm::errs());
242}
243
244void RegionRawOffset::dumpToStream(llvm::raw_ostream& os) const {
245 os << "raw_offset{" << getRegion() << ',' << getByteOffset() << '}';
246}
247
Ted Kremenek5ca90a22008-10-04 05:50:14 +0000248//===----------------------------------------------------------------------===//
249// MemRegionManager methods.
250//===----------------------------------------------------------------------===//
Ted Kremenek1f22aa72009-08-01 06:17:29 +0000251
Mike Stump11289f42009-09-09 15:08:12 +0000252MemSpaceRegion* MemRegionManager::LazyAllocate(MemSpaceRegion*& region) {
253 if (!region) {
Ted Kremenek5ca90a22008-10-04 05:50:14 +0000254 region = (MemSpaceRegion*) A.Allocate<MemSpaceRegion>();
Ted Kremenekfb87e302009-06-23 00:46:41 +0000255 new (region) MemSpaceRegion(this);
Ted Kremenek5ca90a22008-10-04 05:50:14 +0000256 }
Ted Kremenekfb87e302009-06-23 00:46:41 +0000257
Ted Kremenek5ca90a22008-10-04 05:50:14 +0000258 return region;
259}
260
261MemSpaceRegion* MemRegionManager::getStackRegion() {
262 return LazyAllocate(stack);
263}
264
Ted Kremenek7e4a9a02009-07-02 18:14:59 +0000265MemSpaceRegion* MemRegionManager::getStackArgumentsRegion() {
266 return LazyAllocate(stackArguments);
267}
268
Ted Kremenek5ca90a22008-10-04 05:50:14 +0000269MemSpaceRegion* MemRegionManager::getGlobalsRegion() {
270 return LazyAllocate(globals);
271}
272
273MemSpaceRegion* MemRegionManager::getHeapRegion() {
274 return LazyAllocate(heap);
275}
276
Zhongxing Xud9959ae2008-10-08 02:50:44 +0000277MemSpaceRegion* MemRegionManager::getUnknownRegion() {
278 return LazyAllocate(unknown);
279}
280
Zhongxing Xu1aced0c2009-04-10 08:45:10 +0000281MemSpaceRegion* MemRegionManager::getCodeRegion() {
282 return LazyAllocate(code);
283}
284
Ted Kremeneke5e8b0b2009-06-22 23:13:13 +0000285//===----------------------------------------------------------------------===//
286// Constructing regions.
287//===----------------------------------------------------------------------===//
288
Zhongxing Xud1aac352008-10-25 14:13:41 +0000289StringRegion* MemRegionManager::getStringRegion(const StringLiteral* Str) {
Ted Kremeneke5e8b0b2009-06-22 23:13:13 +0000290 return getRegion<StringRegion>(Str);
Zhongxing Xud1aac352008-10-25 14:13:41 +0000291}
292
Ted Kremenek608677a2009-08-21 23:25:54 +0000293VarRegion* MemRegionManager::getVarRegion(const VarDecl *D,
Ted Kremenek14536f62009-08-21 22:28:32 +0000294 const LocationContext *LC) {
Mike Stump11289f42009-09-09 15:08:12 +0000295
Ted Kremenek608677a2009-08-21 23:25:54 +0000296 // FIXME: Once we implement scope handling, we will need to properly lookup
297 // 'D' to the proper LocationContext. For now, just strip down to the
298 // StackFrame.
299 while (!isa<StackFrameContext>(LC))
300 LC = LC->getParent();
Mike Stump11289f42009-09-09 15:08:12 +0000301
Ted Kremenek14536f62009-08-21 22:28:32 +0000302 return getRegion<VarRegion>(D, LC);
Ted Kremenek5ca90a22008-10-04 05:50:14 +0000303}
304
Ted Kremenekb63ad7a2009-11-25 23:53:07 +0000305BlockDataRegion *MemRegionManager::getBlockDataRegion(const BlockTextRegion *BC,
306 const LocationContext *LC)
307{
308 // FIXME: Once we implement scope handling, we will need to properly lookup
309 // 'D' to the proper LocationContext. For now, just strip down to the
310 // StackFrame.
311 while (!isa<StackFrameContext>(LC))
312 LC = LC->getParent();
313
314 return getSubRegion<BlockDataRegion>(BC, LC, getStackRegion());
315}
316
Ted Kremenekbc48caf2008-10-27 20:57:58 +0000317CompoundLiteralRegion*
318MemRegionManager::getCompoundLiteralRegion(const CompoundLiteralExpr* CL) {
Ted Kremeneke5e8b0b2009-06-22 23:13:13 +0000319 return getRegion<CompoundLiteralRegion>(CL);
Ted Kremenekbc48caf2008-10-27 20:57:58 +0000320}
321
Ted Kremenekf065b152008-12-13 19:24:37 +0000322ElementRegion*
Ted Kremenek02e50892009-05-04 06:18:28 +0000323MemRegionManager::getElementRegion(QualType elementType, SVal Idx,
Ted Kremenekc7b1dad2009-07-16 01:33:37 +0000324 const MemRegion* superRegion,
325 ASTContext& Ctx){
Zhongxing Xu838a0db2009-06-16 09:55:50 +0000326
327 QualType T = Ctx.getCanonicalType(elementType);
Ted Kremenekf065b152008-12-13 19:24:37 +0000328
Zhongxing Xud8fe46b2008-10-21 05:27:10 +0000329 llvm::FoldingSetNodeID ID;
Zhongxing Xu838a0db2009-06-16 09:55:50 +0000330 ElementRegion::ProfileRegion(ID, T, Idx, superRegion);
Zhongxing Xud8fe46b2008-10-21 05:27:10 +0000331
332 void* InsertPos;
333 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
334 ElementRegion* R = cast_or_null<ElementRegion>(data);
335
336 if (!R) {
337 R = (ElementRegion*) A.Allocate<ElementRegion>();
Zhongxing Xu838a0db2009-06-16 09:55:50 +0000338 new (R) ElementRegion(T, Idx, superRegion);
Zhongxing Xud8fe46b2008-10-21 05:27:10 +0000339 Regions.InsertNode(R, InsertPos);
340 }
341
342 return R;
343}
344
Ted Kremenek10a50e72009-11-25 01:32:22 +0000345FunctionTextRegion *
346MemRegionManager::getFunctionTextRegion(const FunctionDecl *FD) {
347 return getRegion<FunctionTextRegion>(FD);
Zhongxing Xu1aced0c2009-04-10 08:45:10 +0000348}
349
Ted Kremenek10a50e72009-11-25 01:32:22 +0000350BlockTextRegion *MemRegionManager::getBlockTextRegion(const BlockDecl *BD,
351 CanQualType locTy) {
352 return getRegion<BlockTextRegion>(BD, locTy);
353}
354
355
Ted Kremenek8b103c62008-10-17 20:28:54 +0000356/// getSymbolicRegion - Retrieve or create a "symbolic" memory region.
Ted Kremenek3e31c262009-03-26 03:35:11 +0000357SymbolicRegion* MemRegionManager::getSymbolicRegion(SymbolRef sym) {
Ted Kremeneke5e8b0b2009-06-22 23:13:13 +0000358 return getRegion<SymbolicRegion>(sym);
Ted Kremenek8b103c62008-10-17 20:28:54 +0000359}
360
Ted Kremenek5ca90a22008-10-04 05:50:14 +0000361FieldRegion* MemRegionManager::getFieldRegion(const FieldDecl* d,
Ted Kremenek8b103c62008-10-17 20:28:54 +0000362 const MemRegion* superRegion) {
Ted Kremenekda98f732009-07-10 16:51:45 +0000363 return getSubRegion<FieldRegion>(d, superRegion);
Ted Kremenek5ca90a22008-10-04 05:50:14 +0000364}
365
Ted Kremenek8b103c62008-10-17 20:28:54 +0000366ObjCIvarRegion*
367MemRegionManager::getObjCIvarRegion(const ObjCIvarDecl* d,
368 const MemRegion* superRegion) {
Ted Kremenekda98f732009-07-10 16:51:45 +0000369 return getSubRegion<ObjCIvarRegion>(d, superRegion);
Ted Kremenek5ca90a22008-10-04 05:50:14 +0000370}
371
Ted Kremenek8921d932008-10-24 20:30:08 +0000372ObjCObjectRegion*
373MemRegionManager::getObjCObjectRegion(const ObjCInterfaceDecl* d,
Ted Kremenek22666402009-06-23 00:04:09 +0000374 const MemRegion* superRegion) {
Ted Kremenekda98f732009-07-10 16:51:45 +0000375 return getSubRegion<ObjCObjectRegion>(d, superRegion);
Ted Kremenek8921d932008-10-24 20:30:08 +0000376}
377
Ted Kremenek16783cf2008-11-02 00:34:33 +0000378AllocaRegion* MemRegionManager::getAllocaRegion(const Expr* E, unsigned cnt) {
Ted Kremenek8bae3002009-06-23 00:15:41 +0000379 return getRegion<AllocaRegion>(E, cnt);
Ted Kremenek16783cf2008-11-02 00:34:33 +0000380}
381
Ted Kremenek2d99f972009-06-23 18:17:08 +0000382const MemSpaceRegion *MemRegion::getMemorySpace() const {
383 const MemRegion *R = this;
Ted Kremenek404b1322009-06-23 18:05:21 +0000384 const SubRegion* SR = dyn_cast<SubRegion>(this);
Mike Stump11289f42009-09-09 15:08:12 +0000385
Ted Kremenek8b103c62008-10-17 20:28:54 +0000386 while (SR) {
Ted Kremenek2d99f972009-06-23 18:17:08 +0000387 R = SR->getSuperRegion();
388 SR = dyn_cast<SubRegion>(R);
Ted Kremenek5ca90a22008-10-04 05:50:14 +0000389 }
Mike Stump11289f42009-09-09 15:08:12 +0000390
Ted Kremenek2d99f972009-06-23 18:17:08 +0000391 return dyn_cast<MemSpaceRegion>(R);
392}
393
394bool MemRegion::hasStackStorage() const {
Ted Kremenek7e4a9a02009-07-02 18:14:59 +0000395 if (const MemSpaceRegion *MS = getMemorySpace()) {
396 MemRegionManager *Mgr = getMemRegionManager();
397 return MS == Mgr->getStackRegion() || MS == Mgr->getStackArgumentsRegion();
398 }
Ted Kremenek2d99f972009-06-23 18:17:08 +0000399
Ted Kremenek5ca90a22008-10-04 05:50:14 +0000400 return false;
401}
Ted Kremenekdf240002009-04-11 00:11:10 +0000402
Ted Kremenek404b1322009-06-23 18:05:21 +0000403bool MemRegion::hasHeapStorage() const {
Ted Kremenek2d99f972009-06-23 18:17:08 +0000404 if (const MemSpaceRegion *MS = getMemorySpace())
405 return MS == getMemRegionManager()->getHeapRegion();
Zhongxing Xu1a195b22009-06-23 02:51:21 +0000406
407 return false;
408}
Ted Kremenekdf240002009-04-11 00:11:10 +0000409
Ted Kremenek2d99f972009-06-23 18:17:08 +0000410bool MemRegion::hasHeapOrStackStorage() const {
411 if (const MemSpaceRegion *MS = getMemorySpace()) {
412 MemRegionManager *Mgr = getMemRegionManager();
Ted Kremenek7e4a9a02009-07-02 18:14:59 +0000413 return MS == Mgr->getHeapRegion()
414 || MS == Mgr->getStackRegion()
415 || MS == Mgr->getStackArgumentsRegion();
Ted Kremenek2d99f972009-06-23 18:17:08 +0000416 }
417 return false;
Ted Kremenekdf67d422009-07-02 18:25:09 +0000418}
419
420bool MemRegion::hasGlobalsStorage() const {
421 if (const MemSpaceRegion *MS = getMemorySpace())
422 return MS == getMemRegionManager()->getGlobalsRegion();
423
424 return false;
425}
426
Ted Kremenek725b4a32009-07-02 22:02:15 +0000427bool MemRegion::hasParametersStorage() const {
428 if (const MemSpaceRegion *MS = getMemorySpace())
429 return MS == getMemRegionManager()->getStackArgumentsRegion();
Mike Stump11289f42009-09-09 15:08:12 +0000430
Ted Kremenek725b4a32009-07-02 22:02:15 +0000431 return false;
432}
433
Ted Kremenekdf67d422009-07-02 18:25:09 +0000434bool MemRegion::hasGlobalsOrParametersStorage() const {
435 if (const MemSpaceRegion *MS = getMemorySpace()) {
436 MemRegionManager *Mgr = getMemRegionManager();
437 return MS == Mgr->getGlobalsRegion()
438 || MS == Mgr->getStackArgumentsRegion();
439 }
440 return false;
441}
Ted Kremenek2d99f972009-06-23 18:17:08 +0000442
Zhongxing Xu80bbc6d2009-11-10 02:37:53 +0000443// getBaseRegion strips away all elements and fields, and get the base region
444// of them.
445const MemRegion *MemRegion::getBaseRegion() const {
446 const MemRegion *R = this;
447 while (true) {
448 if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) {
449 R = ER->getSuperRegion();
450 continue;
451 }
452 if (const FieldRegion *FR = dyn_cast<FieldRegion>(R)) {
453 R = FR->getSuperRegion();
454 continue;
455 }
456 break;
457 }
458 return R;
459}
460
Ted Kremenekdf240002009-04-11 00:11:10 +0000461//===----------------------------------------------------------------------===//
462// View handling.
463//===----------------------------------------------------------------------===//
464
Zhongxing Xuf8f3f9d2009-11-10 02:17:20 +0000465const MemRegion *MemRegion::StripCasts() const {
Ted Kremenekccf33352009-07-29 18:14:27 +0000466 const MemRegion *R = this;
467 while (true) {
Mike Stump11289f42009-09-09 15:08:12 +0000468 if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) {
Ted Kremenekccf33352009-07-29 18:14:27 +0000469 // FIXME: generalize. Essentially we want to strip away ElementRegions
470 // that were layered on a symbolic region because of casts. We only
471 // want to strip away ElementRegions, however, where the index is 0.
472 SVal index = ER->getIndex();
473 if (nonloc::ConcreteInt *CI = dyn_cast<nonloc::ConcreteInt>(&index)) {
Ted Kremenek1f22aa72009-08-01 06:17:29 +0000474 if (CI->getValue().getSExtValue() == 0) {
Ted Kremenekccf33352009-07-29 18:14:27 +0000475 R = ER->getSuperRegion();
476 continue;
477 }
478 }
479 }
480 break;
481 }
482 return R;
483}
Ted Kremenek1f22aa72009-08-01 06:17:29 +0000484
485// FIXME: Merge with the implementation of the same method in Store.cpp
486static bool IsCompleteType(ASTContext &Ctx, QualType Ty) {
487 if (const RecordType *RT = Ty->getAs<RecordType>()) {
488 const RecordDecl *D = RT->getDecl();
489 if (!D->getDefinition(Ctx))
490 return false;
491 }
492
493 return true;
494}
495
496RegionRawOffset ElementRegion::getAsRawOffset() const {
497 int64_t offset = 0;
498 const ElementRegion *ER = this;
499 const MemRegion *superR = NULL;
500 ASTContext &C = getContext();
Mike Stump11289f42009-09-09 15:08:12 +0000501
Ted Kremenek1f22aa72009-08-01 06:17:29 +0000502 // FIXME: Handle multi-dimensional arrays.
503
504 while (ER) {
505 superR = ER->getSuperRegion();
Mike Stump11289f42009-09-09 15:08:12 +0000506
Ted Kremenek1f22aa72009-08-01 06:17:29 +0000507 // FIXME: generalize to symbolic offsets.
508 SVal index = ER->getIndex();
509 if (nonloc::ConcreteInt *CI = dyn_cast<nonloc::ConcreteInt>(&index)) {
510 // Update the offset.
511 int64_t i = CI->getValue().getSExtValue();
Mike Stump11289f42009-09-09 15:08:12 +0000512
Ted Kremenek1f22aa72009-08-01 06:17:29 +0000513 if (i != 0) {
514 QualType elemType = ER->getElementType();
Mike Stump11289f42009-09-09 15:08:12 +0000515
Ted Kremenek1f22aa72009-08-01 06:17:29 +0000516 // If we are pointing to an incomplete type, go no further.
517 if (!IsCompleteType(C, elemType)) {
518 superR = ER;
519 break;
520 }
Mike Stump11289f42009-09-09 15:08:12 +0000521
Ted Kremenek1f22aa72009-08-01 06:17:29 +0000522 int64_t size = (int64_t) (C.getTypeSize(elemType) / 8);
523 offset += (i * size);
524 }
525
526 // Go to the next ElementRegion (if any).
527 ER = dyn_cast<ElementRegion>(superR);
528 continue;
529 }
Mike Stump11289f42009-09-09 15:08:12 +0000530
Ted Kremenek1f22aa72009-08-01 06:17:29 +0000531 return NULL;
532 }
Mike Stump11289f42009-09-09 15:08:12 +0000533
Ted Kremenek1f22aa72009-08-01 06:17:29 +0000534 assert(superR && "super region cannot be NULL");
535 return RegionRawOffset(superR, offset);
536}
537
Ted Kremenek3378b612009-11-26 02:34:36 +0000538//===----------------------------------------------------------------------===//
539// BlockDataRegion
540//===----------------------------------------------------------------------===//
541
542void BlockDataRegion::LazyInitializeReferencedVars() {
543 if (ReferencedVars)
544 return;
545
546 AnalysisContext *AC = LC->getAnalysisContext();
547 AnalysisContext::referenced_decls_iterator I, E;
548 llvm::tie(I, E) = AC->getReferencedBlockVars(BC->getDecl());
549
550 if (I == E) {
551 ReferencedVars = (void*) 0x1;
552 return;
553 }
554
555 MemRegionManager &MemMgr = *getMemRegionManager();
556 llvm::BumpPtrAllocator &A = MemMgr.getAllocator();
557 BumpVectorContext BC(A);
558
559 typedef BumpVector<const MemRegion*> VarVec;
560 VarVec *BV = (VarVec*) A.Allocate<VarVec>();
Ted Kremenek117e4722009-12-01 22:12:34 +0000561 new (BV) VarVec(BC, E - I);
Ted Kremenek3378b612009-11-26 02:34:36 +0000562
563 for ( ; I != E; ++I)
564 BV->push_back(MemMgr.getVarRegion(*I, LC), BC);
565
566 ReferencedVars = BV;
567}
568
569BlockDataRegion::referenced_vars_iterator
570BlockDataRegion::referenced_vars_begin() const {
571 const_cast<BlockDataRegion*>(this)->LazyInitializeReferencedVars();
572
573 BumpVector<const MemRegion*> *Vec =
574 static_cast<BumpVector<const MemRegion*>*>(ReferencedVars);
575
576 return Vec == (void*) 0x1 ? NULL : Vec->begin();
577}
578
579BlockDataRegion::referenced_vars_iterator
580BlockDataRegion::referenced_vars_end() const {
581 const_cast<BlockDataRegion*>(this)->LazyInitializeReferencedVars();
582
583 BumpVector<const MemRegion*> *Vec =
584 static_cast<BumpVector<const MemRegion*>*>(ReferencedVars);
585
586 return Vec == (void*) 0x1 ? NULL : Vec->end();
587}