blob: 8b4c7a6a24078f525743ab6c2f60b30761b70f51 [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"
Ted Kremenek19e1f0b2009-08-01 06:17:29 +000018#include "clang/Analysis/PathSensitive/ValueManager.h"
Ted Kremenek82cd37c2009-08-21 23:25:54 +000019#include "clang/Analysis/PathSensitive/AnalysisContext.h"
Ted Kremenek9e240492008-10-04 05:50:14 +000020
21using namespace clang;
22
Ted Kremenek25010132009-06-22 23:13:13 +000023//===----------------------------------------------------------------------===//
24// Basic methods.
25//===----------------------------------------------------------------------===//
Ted Kremenek9e240492008-10-04 05:50:14 +000026
27MemRegion::~MemRegion() {}
28
Zhongxing Xu7e5d6ed2009-01-08 13:17:14 +000029bool SubRegion::isSubRegionOf(const MemRegion* R) const {
30 const MemRegion* r = getSuperRegion();
31 while (r != 0) {
32 if (r == R)
33 return true;
34 if (const SubRegion* sr = dyn_cast<SubRegion>(r))
35 r = sr->getSuperRegion();
36 else
37 break;
38 }
39 return false;
40}
41
Ted Kremeneka43484a2009-06-23 00:46:41 +000042MemRegionManager* SubRegion::getMemRegionManager() const {
43 const SubRegion* r = this;
44 do {
45 const MemRegion *superRegion = r->getSuperRegion();
46 if (const SubRegion *sr = dyn_cast<SubRegion>(superRegion)) {
47 r = sr;
48 continue;
49 }
50 return superRegion->getMemRegionManager();
51 } while (1);
52}
53
Ted Kremenek9e240492008-10-04 05:50:14 +000054void MemSpaceRegion::Profile(llvm::FoldingSetNodeID& ID) const {
55 ID.AddInteger((unsigned)getKind());
56}
57
Mike Stump1eb44332009-09-09 15:08:12 +000058void StringRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
59 const StringLiteral* Str,
Zhongxing Xue9f4e542008-10-25 14:13:41 +000060 const MemRegion* superRegion) {
61 ID.AddInteger((unsigned) StringRegionKind);
62 ID.AddPointer(Str);
63 ID.AddPointer(superRegion);
64}
65
Ted Kremenek7090ae12008-11-02 00:34:33 +000066void AllocaRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
Ted Kremenek7ae7ad92009-06-23 00:15:41 +000067 const Expr* Ex, unsigned cnt,
68 const MemRegion *) {
Ted Kremenek7090ae12008-11-02 00:34:33 +000069 ID.AddInteger((unsigned) AllocaRegionKind);
70 ID.AddPointer(Ex);
71 ID.AddInteger(cnt);
72}
73
74void AllocaRegion::Profile(llvm::FoldingSetNodeID& ID) const {
Ted Kremenek7ae7ad92009-06-23 00:15:41 +000075 ProfileRegion(ID, Ex, Cnt, superRegion);
Ted Kremenek7090ae12008-11-02 00:34:33 +000076}
77
Ted Kremenek329d6fd2008-10-27 20:57:58 +000078void CompoundLiteralRegion::Profile(llvm::FoldingSetNodeID& ID) const {
79 CompoundLiteralRegion::ProfileRegion(ID, CL, superRegion);
80}
81
82void CompoundLiteralRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
83 const CompoundLiteralExpr* CL,
84 const MemRegion* superRegion) {
85 ID.AddInteger((unsigned) CompoundLiteralRegionKind);
86 ID.AddPointer(CL);
87 ID.AddPointer(superRegion);
88}
89
Ted Kremenek9e240492008-10-04 05:50:14 +000090void DeclRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, const Decl* D,
91 const MemRegion* superRegion, Kind k) {
92 ID.AddInteger((unsigned) k);
93 ID.AddPointer(D);
94 ID.AddPointer(superRegion);
95}
96
97void DeclRegion::Profile(llvm::FoldingSetNodeID& ID) const {
98 DeclRegion::ProfileRegion(ID, D, superRegion, getKind());
99}
100
Ted Kremenekd17da2b2009-08-21 22:28:32 +0000101void VarRegion::Profile(llvm::FoldingSetNodeID &ID) const {
102 VarRegion::ProfileRegion(ID, getDecl(), LC, superRegion);
103}
104
Ted Kremenek25010132009-06-22 23:13:13 +0000105void SymbolicRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, SymbolRef sym,
106 const MemRegion *sreg) {
Ted Kremenek993f1c72008-10-17 20:28:54 +0000107 ID.AddInteger((unsigned) MemRegion::SymbolicRegionKind);
Ted Kremenek6d0e2d22008-12-05 02:39:38 +0000108 ID.Add(sym);
Ted Kremenek25010132009-06-22 23:13:13 +0000109 ID.AddPointer(sreg);
Ted Kremenek993f1c72008-10-17 20:28:54 +0000110}
111
112void SymbolicRegion::Profile(llvm::FoldingSetNodeID& ID) const {
Ted Kremenek25010132009-06-22 23:13:13 +0000113 SymbolicRegion::ProfileRegion(ID, sym, getSuperRegion());
Ted Kremenek993f1c72008-10-17 20:28:54 +0000114}
115
Ted Kremenekf936f452009-05-04 06:18:28 +0000116void ElementRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
Mike Stump1eb44332009-09-09 15:08:12 +0000117 QualType ElementType, SVal Idx,
Zhongxing Xu511191c2008-10-21 05:27:10 +0000118 const MemRegion* superRegion) {
119 ID.AddInteger(MemRegion::ElementRegionKind);
Ted Kremenekf936f452009-05-04 06:18:28 +0000120 ID.Add(ElementType);
Zhongxing Xu511191c2008-10-21 05:27:10 +0000121 ID.AddPointer(superRegion);
122 Idx.Profile(ID);
123}
124
125void ElementRegion::Profile(llvm::FoldingSetNodeID& ID) const {
Ted Kremenekf936f452009-05-04 06:18:28 +0000126 ElementRegion::ProfileRegion(ID, ElementType, Index, superRegion);
Zhongxing Xu511191c2008-10-21 05:27:10 +0000127}
Zhongxing Xu27b57062008-10-27 13:17:02 +0000128
Ted Kremenekeb1c7a02009-11-25 01:32:22 +0000129void FunctionTextRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
130 const FunctionDecl *FD,
131 const MemRegion*) {
132 ID.AddInteger(MemRegion::FunctionTextRegionKind);
Ted Kremenekabd46e12009-08-28 04:49:15 +0000133 ID.AddPointer(FD);
Zhongxing Xuec13d922009-04-10 08:45:10 +0000134}
135
Ted Kremenekeb1c7a02009-11-25 01:32:22 +0000136void FunctionTextRegion::Profile(llvm::FoldingSetNodeID& ID) const {
137 FunctionTextRegion::ProfileRegion(ID, FD, superRegion);
138}
139
140void BlockTextRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
141 const BlockDecl *BD, CanQualType,
142 const MemRegion*) {
143 ID.AddInteger(MemRegion::BlockTextRegionKind);
144 ID.AddPointer(BD);
145}
146
147void BlockTextRegion::Profile(llvm::FoldingSetNodeID& ID) const {
148 BlockTextRegion::ProfileRegion(ID, BD, locTy, superRegion);
Zhongxing Xuec13d922009-04-10 08:45:10 +0000149}
150
Zhongxing Xu026c6632009-02-05 06:57:29 +0000151//===----------------------------------------------------------------------===//
Ted Kremenek9e240492008-10-04 05:50:14 +0000152// Region pretty-printing.
153//===----------------------------------------------------------------------===//
154
Ted Kremenek8800ad42009-07-13 23:31:04 +0000155void MemRegion::dump() const {
156 dumpToStream(llvm::errs());
Ted Kremenek7f39d292009-07-02 17:24:10 +0000157}
158
Ted Kremenek9e240492008-10-04 05:50:14 +0000159std::string MemRegion::getString() const {
160 std::string s;
161 llvm::raw_string_ostream os(s);
Ted Kremenek8800ad42009-07-13 23:31:04 +0000162 dumpToStream(os);
Ted Kremenek9e240492008-10-04 05:50:14 +0000163 return os.str();
164}
165
Ted Kremenek8800ad42009-07-13 23:31:04 +0000166void MemRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenek9e240492008-10-04 05:50:14 +0000167 os << "<Unknown Region>";
168}
169
Ted Kremenek8800ad42009-07-13 23:31:04 +0000170void AllocaRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenek7090ae12008-11-02 00:34:33 +0000171 os << "alloca{" << (void*) Ex << ',' << Cnt << '}';
172}
173
Ted Kremenekeb1c7a02009-11-25 01:32:22 +0000174void FunctionTextRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenekabd46e12009-08-28 04:49:15 +0000175 os << "code{" << getDecl()->getDeclName().getAsString() << '}';
Ted Kremenek72e03202009-04-21 19:56:58 +0000176}
177
Ted Kremenekeb1c7a02009-11-25 01:32:22 +0000178void BlockTextRegion::dumpToStream(llvm::raw_ostream& os) const {
179 os << "block{" << (void*) this << '}';
180}
181
Ted Kremenek8800ad42009-07-13 23:31:04 +0000182void CompoundLiteralRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenek5639a3e2009-04-21 18:09:22 +0000183 // FIXME: More elaborate pretty-printing.
184 os << "{ " << (void*) CL << " }";
185}
186
Ted Kremenek8800ad42009-07-13 23:31:04 +0000187void ElementRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000188 os << "element{" << superRegion << ','
189 << Index << ',' << getElementType().getAsString() << '}';
Ted Kremenek5639a3e2009-04-21 18:09:22 +0000190}
191
Ted Kremenek8800ad42009-07-13 23:31:04 +0000192void FieldRegion::dumpToStream(llvm::raw_ostream& os) const {
193 os << superRegion << "->" << getDecl()->getNameAsString();
Ted Kremenek5639a3e2009-04-21 18:09:22 +0000194}
195
Ted Kremenekbcfe03a2009-07-19 20:36:24 +0000196void ObjCIvarRegion::dumpToStream(llvm::raw_ostream& os) const {
197 os << "ivar{" << superRegion << ',' << getDecl()->getNameAsString() << '}';
198}
199
Mike Stump1eb44332009-09-09 15:08:12 +0000200void StringRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenekb27ed3d2009-07-19 20:38:24 +0000201 Str->printPretty(os, 0, PrintingPolicy(getContext().getLangOptions()));
Ted Kremenek5639a3e2009-04-21 18:09:22 +0000202}
203
Ted Kremenek8800ad42009-07-13 23:31:04 +0000204void SymbolicRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenekaef5d222009-07-13 23:38:57 +0000205 os << "SymRegion{" << sym << '}';
Ted Kremenek5639a3e2009-04-21 18:09:22 +0000206}
207
Ted Kremenek8800ad42009-07-13 23:31:04 +0000208void VarRegion::dumpToStream(llvm::raw_ostream& os) const {
Chris Lattnerd9d22dd2008-11-24 05:29:24 +0000209 os << cast<VarDecl>(D)->getNameAsString();
Ted Kremenek9e240492008-10-04 05:50:14 +0000210}
211
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000212void RegionRawOffset::dump() const {
213 dumpToStream(llvm::errs());
214}
215
216void RegionRawOffset::dumpToStream(llvm::raw_ostream& os) const {
217 os << "raw_offset{" << getRegion() << ',' << getByteOffset() << '}';
218}
219
Ted Kremenek9e240492008-10-04 05:50:14 +0000220//===----------------------------------------------------------------------===//
221// MemRegionManager methods.
222//===----------------------------------------------------------------------===//
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000223
Mike Stump1eb44332009-09-09 15:08:12 +0000224MemSpaceRegion* MemRegionManager::LazyAllocate(MemSpaceRegion*& region) {
225 if (!region) {
Ted Kremenek9e240492008-10-04 05:50:14 +0000226 region = (MemSpaceRegion*) A.Allocate<MemSpaceRegion>();
Ted Kremeneka43484a2009-06-23 00:46:41 +0000227 new (region) MemSpaceRegion(this);
Ted Kremenek9e240492008-10-04 05:50:14 +0000228 }
Ted Kremeneka43484a2009-06-23 00:46:41 +0000229
Ted Kremenek9e240492008-10-04 05:50:14 +0000230 return region;
231}
232
233MemSpaceRegion* MemRegionManager::getStackRegion() {
234 return LazyAllocate(stack);
235}
236
Ted Kremenekd05552a2009-07-02 18:14:59 +0000237MemSpaceRegion* MemRegionManager::getStackArgumentsRegion() {
238 return LazyAllocate(stackArguments);
239}
240
Ted Kremenek9e240492008-10-04 05:50:14 +0000241MemSpaceRegion* MemRegionManager::getGlobalsRegion() {
242 return LazyAllocate(globals);
243}
244
245MemSpaceRegion* MemRegionManager::getHeapRegion() {
246 return LazyAllocate(heap);
247}
248
Zhongxing Xu17892752008-10-08 02:50:44 +0000249MemSpaceRegion* MemRegionManager::getUnknownRegion() {
250 return LazyAllocate(unknown);
251}
252
Zhongxing Xuec13d922009-04-10 08:45:10 +0000253MemSpaceRegion* MemRegionManager::getCodeRegion() {
254 return LazyAllocate(code);
255}
256
Ted Kremenek25010132009-06-22 23:13:13 +0000257//===----------------------------------------------------------------------===//
258// Constructing regions.
259//===----------------------------------------------------------------------===//
260
Zhongxing Xue9f4e542008-10-25 14:13:41 +0000261StringRegion* MemRegionManager::getStringRegion(const StringLiteral* Str) {
Ted Kremenek25010132009-06-22 23:13:13 +0000262 return getRegion<StringRegion>(Str);
Zhongxing Xue9f4e542008-10-25 14:13:41 +0000263}
264
Ted Kremenek82cd37c2009-08-21 23:25:54 +0000265VarRegion* MemRegionManager::getVarRegion(const VarDecl *D,
Ted Kremenekd17da2b2009-08-21 22:28:32 +0000266 const LocationContext *LC) {
Mike Stump1eb44332009-09-09 15:08:12 +0000267
Ted Kremenek82cd37c2009-08-21 23:25:54 +0000268 // FIXME: Once we implement scope handling, we will need to properly lookup
269 // 'D' to the proper LocationContext. For now, just strip down to the
270 // StackFrame.
271 while (!isa<StackFrameContext>(LC))
272 LC = LC->getParent();
Mike Stump1eb44332009-09-09 15:08:12 +0000273
Ted Kremenekd17da2b2009-08-21 22:28:32 +0000274 return getRegion<VarRegion>(D, LC);
Ted Kremenek9e240492008-10-04 05:50:14 +0000275}
276
Ted Kremenek329d6fd2008-10-27 20:57:58 +0000277CompoundLiteralRegion*
278MemRegionManager::getCompoundLiteralRegion(const CompoundLiteralExpr* CL) {
Ted Kremenek25010132009-06-22 23:13:13 +0000279 return getRegion<CompoundLiteralRegion>(CL);
Ted Kremenek329d6fd2008-10-27 20:57:58 +0000280}
281
Ted Kremenekabb042f2008-12-13 19:24:37 +0000282ElementRegion*
Ted Kremenekf936f452009-05-04 06:18:28 +0000283MemRegionManager::getElementRegion(QualType elementType, SVal Idx,
Ted Kremenek46537392009-07-16 01:33:37 +0000284 const MemRegion* superRegion,
285 ASTContext& Ctx){
Zhongxing Xu143b2fc2009-06-16 09:55:50 +0000286
287 QualType T = Ctx.getCanonicalType(elementType);
Ted Kremenekabb042f2008-12-13 19:24:37 +0000288
Zhongxing Xu511191c2008-10-21 05:27:10 +0000289 llvm::FoldingSetNodeID ID;
Zhongxing Xu143b2fc2009-06-16 09:55:50 +0000290 ElementRegion::ProfileRegion(ID, T, Idx, superRegion);
Zhongxing Xu511191c2008-10-21 05:27:10 +0000291
292 void* InsertPos;
293 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
294 ElementRegion* R = cast_or_null<ElementRegion>(data);
295
296 if (!R) {
297 R = (ElementRegion*) A.Allocate<ElementRegion>();
Zhongxing Xu143b2fc2009-06-16 09:55:50 +0000298 new (R) ElementRegion(T, Idx, superRegion);
Zhongxing Xu511191c2008-10-21 05:27:10 +0000299 Regions.InsertNode(R, InsertPos);
300 }
301
302 return R;
303}
304
Ted Kremenekeb1c7a02009-11-25 01:32:22 +0000305FunctionTextRegion *
306MemRegionManager::getFunctionTextRegion(const FunctionDecl *FD) {
307 return getRegion<FunctionTextRegion>(FD);
Zhongxing Xuec13d922009-04-10 08:45:10 +0000308}
309
Ted Kremenekeb1c7a02009-11-25 01:32:22 +0000310BlockTextRegion *MemRegionManager::getBlockTextRegion(const BlockDecl *BD,
311 CanQualType locTy) {
312 return getRegion<BlockTextRegion>(BD, locTy);
313}
314
315
Ted Kremenek993f1c72008-10-17 20:28:54 +0000316/// getSymbolicRegion - Retrieve or create a "symbolic" memory region.
Ted Kremeneke0e4ebf2009-03-26 03:35:11 +0000317SymbolicRegion* MemRegionManager::getSymbolicRegion(SymbolRef sym) {
Ted Kremenek25010132009-06-22 23:13:13 +0000318 return getRegion<SymbolicRegion>(sym);
Ted Kremenek993f1c72008-10-17 20:28:54 +0000319}
320
Ted Kremenek9e240492008-10-04 05:50:14 +0000321FieldRegion* MemRegionManager::getFieldRegion(const FieldDecl* d,
Ted Kremenek993f1c72008-10-17 20:28:54 +0000322 const MemRegion* superRegion) {
Ted Kremenekeeea4562009-07-10 16:51:45 +0000323 return getSubRegion<FieldRegion>(d, superRegion);
Ted Kremenek9e240492008-10-04 05:50:14 +0000324}
325
Ted Kremenek993f1c72008-10-17 20:28:54 +0000326ObjCIvarRegion*
327MemRegionManager::getObjCIvarRegion(const ObjCIvarDecl* d,
328 const MemRegion* superRegion) {
Ted Kremenekeeea4562009-07-10 16:51:45 +0000329 return getSubRegion<ObjCIvarRegion>(d, superRegion);
Ted Kremenek9e240492008-10-04 05:50:14 +0000330}
331
Ted Kremeneka7f1b9e2008-10-24 20:30:08 +0000332ObjCObjectRegion*
333MemRegionManager::getObjCObjectRegion(const ObjCInterfaceDecl* d,
Ted Kremenekded12212009-06-23 00:04:09 +0000334 const MemRegion* superRegion) {
Ted Kremenekeeea4562009-07-10 16:51:45 +0000335 return getSubRegion<ObjCObjectRegion>(d, superRegion);
Ted Kremeneka7f1b9e2008-10-24 20:30:08 +0000336}
337
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 Kremenekbb7c96f2009-06-23 18:17:08 +0000342const MemSpaceRegion *MemRegion::getMemorySpace() const {
343 const MemRegion *R = this;
Ted Kremenekea20cd72009-06-23 18:05:21 +0000344 const SubRegion* SR = dyn_cast<SubRegion>(this);
Mike Stump1eb44332009-09-09 15:08:12 +0000345
Ted Kremenek993f1c72008-10-17 20:28:54 +0000346 while (SR) {
Ted Kremenekbb7c96f2009-06-23 18:17:08 +0000347 R = SR->getSuperRegion();
348 SR = dyn_cast<SubRegion>(R);
Ted Kremenek9e240492008-10-04 05:50:14 +0000349 }
Mike Stump1eb44332009-09-09 15:08:12 +0000350
Ted Kremenekbb7c96f2009-06-23 18:17:08 +0000351 return dyn_cast<MemSpaceRegion>(R);
352}
353
354bool MemRegion::hasStackStorage() const {
Ted Kremenekd05552a2009-07-02 18:14:59 +0000355 if (const MemSpaceRegion *MS = getMemorySpace()) {
356 MemRegionManager *Mgr = getMemRegionManager();
357 return MS == Mgr->getStackRegion() || MS == Mgr->getStackArgumentsRegion();
358 }
Ted Kremenekbb7c96f2009-06-23 18:17:08 +0000359
Ted Kremenek9e240492008-10-04 05:50:14 +0000360 return false;
361}
Ted Kremenek1670e402009-04-11 00:11:10 +0000362
Ted Kremenekea20cd72009-06-23 18:05:21 +0000363bool MemRegion::hasHeapStorage() const {
Ted Kremenekbb7c96f2009-06-23 18:17:08 +0000364 if (const MemSpaceRegion *MS = getMemorySpace())
365 return MS == getMemRegionManager()->getHeapRegion();
Zhongxing Xudd198f02009-06-23 02:51:21 +0000366
367 return false;
368}
Ted Kremenek1670e402009-04-11 00:11:10 +0000369
Ted Kremenekbb7c96f2009-06-23 18:17:08 +0000370bool MemRegion::hasHeapOrStackStorage() const {
371 if (const MemSpaceRegion *MS = getMemorySpace()) {
372 MemRegionManager *Mgr = getMemRegionManager();
Ted Kremenekd05552a2009-07-02 18:14:59 +0000373 return MS == Mgr->getHeapRegion()
374 || MS == Mgr->getStackRegion()
375 || MS == Mgr->getStackArgumentsRegion();
Ted Kremenekbb7c96f2009-06-23 18:17:08 +0000376 }
377 return false;
Ted Kremenek15086362009-07-02 18:25:09 +0000378}
379
380bool MemRegion::hasGlobalsStorage() const {
381 if (const MemSpaceRegion *MS = getMemorySpace())
382 return MS == getMemRegionManager()->getGlobalsRegion();
383
384 return false;
385}
386
Ted Kremenekdc147262009-07-02 22:02:15 +0000387bool MemRegion::hasParametersStorage() const {
388 if (const MemSpaceRegion *MS = getMemorySpace())
389 return MS == getMemRegionManager()->getStackArgumentsRegion();
Mike Stump1eb44332009-09-09 15:08:12 +0000390
Ted Kremenekdc147262009-07-02 22:02:15 +0000391 return false;
392}
393
Ted Kremenek15086362009-07-02 18:25:09 +0000394bool MemRegion::hasGlobalsOrParametersStorage() const {
395 if (const MemSpaceRegion *MS = getMemorySpace()) {
396 MemRegionManager *Mgr = getMemRegionManager();
397 return MS == Mgr->getGlobalsRegion()
398 || MS == Mgr->getStackArgumentsRegion();
399 }
400 return false;
401}
Ted Kremenekbb7c96f2009-06-23 18:17:08 +0000402
Zhongxing Xuadca2712009-11-10 02:37:53 +0000403// getBaseRegion strips away all elements and fields, and get the base region
404// of them.
405const MemRegion *MemRegion::getBaseRegion() const {
406 const MemRegion *R = this;
407 while (true) {
408 if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) {
409 R = ER->getSuperRegion();
410 continue;
411 }
412 if (const FieldRegion *FR = dyn_cast<FieldRegion>(R)) {
413 R = FR->getSuperRegion();
414 continue;
415 }
416 break;
417 }
418 return R;
419}
420
Ted Kremenek1670e402009-04-11 00:11:10 +0000421//===----------------------------------------------------------------------===//
422// View handling.
423//===----------------------------------------------------------------------===//
424
Zhongxing Xu479529e2009-11-10 02:17:20 +0000425const MemRegion *MemRegion::StripCasts() const {
Ted Kremenek0e3ec3f2009-07-29 18:14:27 +0000426 const MemRegion *R = this;
427 while (true) {
Mike Stump1eb44332009-09-09 15:08:12 +0000428 if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) {
Ted Kremenek0e3ec3f2009-07-29 18:14:27 +0000429 // FIXME: generalize. Essentially we want to strip away ElementRegions
430 // that were layered on a symbolic region because of casts. We only
431 // want to strip away ElementRegions, however, where the index is 0.
432 SVal index = ER->getIndex();
433 if (nonloc::ConcreteInt *CI = dyn_cast<nonloc::ConcreteInt>(&index)) {
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000434 if (CI->getValue().getSExtValue() == 0) {
Ted Kremenek0e3ec3f2009-07-29 18:14:27 +0000435 R = ER->getSuperRegion();
436 continue;
437 }
438 }
439 }
440 break;
441 }
442 return R;
443}
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000444
445// FIXME: Merge with the implementation of the same method in Store.cpp
446static bool IsCompleteType(ASTContext &Ctx, QualType Ty) {
447 if (const RecordType *RT = Ty->getAs<RecordType>()) {
448 const RecordDecl *D = RT->getDecl();
449 if (!D->getDefinition(Ctx))
450 return false;
451 }
452
453 return true;
454}
455
456RegionRawOffset ElementRegion::getAsRawOffset() const {
457 int64_t offset = 0;
458 const ElementRegion *ER = this;
459 const MemRegion *superR = NULL;
460 ASTContext &C = getContext();
Mike Stump1eb44332009-09-09 15:08:12 +0000461
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000462 // FIXME: Handle multi-dimensional arrays.
463
464 while (ER) {
465 superR = ER->getSuperRegion();
Mike Stump1eb44332009-09-09 15:08:12 +0000466
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000467 // FIXME: generalize to symbolic offsets.
468 SVal index = ER->getIndex();
469 if (nonloc::ConcreteInt *CI = dyn_cast<nonloc::ConcreteInt>(&index)) {
470 // Update the offset.
471 int64_t i = CI->getValue().getSExtValue();
Mike Stump1eb44332009-09-09 15:08:12 +0000472
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000473 if (i != 0) {
474 QualType elemType = ER->getElementType();
Mike Stump1eb44332009-09-09 15:08:12 +0000475
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000476 // If we are pointing to an incomplete type, go no further.
477 if (!IsCompleteType(C, elemType)) {
478 superR = ER;
479 break;
480 }
Mike Stump1eb44332009-09-09 15:08:12 +0000481
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000482 int64_t size = (int64_t) (C.getTypeSize(elemType) / 8);
483 offset += (i * size);
484 }
485
486 // Go to the next ElementRegion (if any).
487 ER = dyn_cast<ElementRegion>(superR);
488 continue;
489 }
Mike Stump1eb44332009-09-09 15:08:12 +0000490
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000491 return NULL;
492 }
Mike Stump1eb44332009-09-09 15:08:12 +0000493
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000494 assert(superR && "super region cannot be NULL");
495 return RegionRawOffset(superR, offset);
496}
497