blob: ac633060fddd1494bdfe02cd454bc6a1badd2cae [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"
Ted Kremenek98137f72009-08-01 06:17:29 +000018#include "clang/Analysis/PathSensitive/ValueManager.h"
Ted Kremenekb15eba42008-10-04 05:50:14 +000019
20using namespace clang;
21
Ted Kremenek1b85d8e2009-06-22 23:13:13 +000022//===----------------------------------------------------------------------===//
23// Basic methods.
24//===----------------------------------------------------------------------===//
Ted Kremenekb15eba42008-10-04 05:50:14 +000025
26MemRegion::~MemRegion() {}
27
Zhongxing Xub287b212009-01-08 13:17:14 +000028bool SubRegion::isSubRegionOf(const MemRegion* R) const {
29 const MemRegion* r = getSuperRegion();
30 while (r != 0) {
31 if (r == R)
32 return true;
33 if (const SubRegion* sr = dyn_cast<SubRegion>(r))
34 r = sr->getSuperRegion();
35 else
36 break;
37 }
38 return false;
39}
40
Ted Kremenekd8f4cef2009-06-23 00:46:41 +000041
42MemRegionManager* 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 Kremenekb15eba42008-10-04 05:50:14 +000054void MemSpaceRegion::Profile(llvm::FoldingSetNodeID& ID) const {
55 ID.AddInteger((unsigned)getKind());
56}
57
Zhongxing Xu73507bd2008-10-25 14:13:41 +000058void StringRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
59 const StringLiteral* Str,
60 const MemRegion* superRegion) {
61 ID.AddInteger((unsigned) StringRegionKind);
62 ID.AddPointer(Str);
63 ID.AddPointer(superRegion);
64}
65
Ted Kremenekea9ca502008-11-02 00:34:33 +000066void AllocaRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
Ted Kremenek3680b452009-06-23 00:15:41 +000067 const Expr* Ex, unsigned cnt,
68 const MemRegion *) {
Ted Kremenekea9ca502008-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 Kremenek3680b452009-06-23 00:15:41 +000075 ProfileRegion(ID, Ex, Cnt, superRegion);
Ted Kremenekea9ca502008-11-02 00:34:33 +000076}
77
Ted Kremenek6bc91b92008-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 Kremenekb15eba42008-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 Kremenek1b85d8e2009-06-22 23:13:13 +0000101void SymbolicRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, SymbolRef sym,
102 const MemRegion *sreg) {
Ted Kremenek38a4b4b2008-10-17 20:28:54 +0000103 ID.AddInteger((unsigned) MemRegion::SymbolicRegionKind);
Ted Kremeneke8993f12008-12-05 02:39:38 +0000104 ID.Add(sym);
Ted Kremenek1b85d8e2009-06-22 23:13:13 +0000105 ID.AddPointer(sreg);
Ted Kremenek38a4b4b2008-10-17 20:28:54 +0000106}
107
108void SymbolicRegion::Profile(llvm::FoldingSetNodeID& ID) const {
Ted Kremenek1b85d8e2009-06-22 23:13:13 +0000109 SymbolicRegion::ProfileRegion(ID, sym, getSuperRegion());
Ted Kremenek38a4b4b2008-10-17 20:28:54 +0000110}
111
Ted Kremenekaf81ece2009-05-04 06:18:28 +0000112void ElementRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
113 QualType ElementType, SVal Idx,
Zhongxing Xu54969732008-10-21 05:27:10 +0000114 const MemRegion* superRegion) {
115 ID.AddInteger(MemRegion::ElementRegionKind);
Ted Kremenekaf81ece2009-05-04 06:18:28 +0000116 ID.Add(ElementType);
Zhongxing Xu54969732008-10-21 05:27:10 +0000117 ID.AddPointer(superRegion);
118 Idx.Profile(ID);
119}
120
121void ElementRegion::Profile(llvm::FoldingSetNodeID& ID) const {
Ted Kremenekaf81ece2009-05-04 06:18:28 +0000122 ElementRegion::ProfileRegion(ID, ElementType, Index, superRegion);
Zhongxing Xu54969732008-10-21 05:27:10 +0000123}
Zhongxing Xu1a563da2008-10-27 13:17:02 +0000124
Zhongxing Xuef3fb4c2009-04-10 08:45:10 +0000125void CodeTextRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, const void* data,
Zhongxing Xu54cd8122009-06-23 03:50:30 +0000126 QualType t, const MemRegion*) {
Zhongxing Xuef3fb4c2009-04-10 08:45:10 +0000127 ID.AddInteger(MemRegion::CodeTextRegionKind);
128 ID.AddPointer(data);
129 ID.Add(t);
130}
131
132void CodeTextRegion::Profile(llvm::FoldingSetNodeID& ID) const {
Zhongxing Xu54cd8122009-06-23 03:50:30 +0000133 CodeTextRegion::ProfileRegion(ID, Data, LocationType, superRegion);
Zhongxing Xuef3fb4c2009-04-10 08:45:10 +0000134}
135
Zhongxing Xu93b80662009-02-05 06:57:29 +0000136//===----------------------------------------------------------------------===//
Ted Kremenekb15eba42008-10-04 05:50:14 +0000137// Region pretty-printing.
138//===----------------------------------------------------------------------===//
139
Ted Kremenekfaf94872009-07-13 23:31:04 +0000140void MemRegion::dump() const {
141 dumpToStream(llvm::errs());
Ted Kremenekb80d8572009-07-02 17:24:10 +0000142}
143
Ted Kremenekb15eba42008-10-04 05:50:14 +0000144std::string MemRegion::getString() const {
145 std::string s;
146 llvm::raw_string_ostream os(s);
Ted Kremenekfaf94872009-07-13 23:31:04 +0000147 dumpToStream(os);
Ted Kremenekb15eba42008-10-04 05:50:14 +0000148 return os.str();
149}
150
Ted Kremenekfaf94872009-07-13 23:31:04 +0000151void MemRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenekb15eba42008-10-04 05:50:14 +0000152 os << "<Unknown Region>";
153}
154
Ted Kremenekfaf94872009-07-13 23:31:04 +0000155void AllocaRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenekea9ca502008-11-02 00:34:33 +0000156 os << "alloca{" << (void*) Ex << ',' << Cnt << '}';
157}
158
Ted Kremenekfaf94872009-07-13 23:31:04 +0000159void CodeTextRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenek398efb52009-04-21 19:56:58 +0000160 os << "code{";
161 if (isDeclared())
Ted Kremenekb895ed22009-04-29 15:37:24 +0000162 os << getDecl()->getDeclName().getAsString();
Ted Kremenek398efb52009-04-21 19:56:58 +0000163 else
164 os << '$' << getSymbol();
165
166 os << '}';
167}
168
Ted Kremenekfaf94872009-07-13 23:31:04 +0000169void CompoundLiteralRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenek3a4beb52009-04-21 18:09:22 +0000170 // FIXME: More elaborate pretty-printing.
171 os << "{ " << (void*) CL << " }";
172}
173
Ted Kremenekfaf94872009-07-13 23:31:04 +0000174void ElementRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenek98137f72009-08-01 06:17:29 +0000175 os << "element{" << superRegion << ','
176 << Index << ',' << getElementType().getAsString() << '}';
Ted Kremenek3a4beb52009-04-21 18:09:22 +0000177}
178
Ted Kremenekfaf94872009-07-13 23:31:04 +0000179void FieldRegion::dumpToStream(llvm::raw_ostream& os) const {
180 os << superRegion << "->" << getDecl()->getNameAsString();
Ted Kremenek3a4beb52009-04-21 18:09:22 +0000181}
182
Ted Kremenekd6fee632009-07-19 20:36:24 +0000183void ObjCIvarRegion::dumpToStream(llvm::raw_ostream& os) const {
184 os << "ivar{" << superRegion << ',' << getDecl()->getNameAsString() << '}';
185}
186
Ted Kremenekb99af2f2009-07-19 20:38:24 +0000187void StringRegion::dumpToStream(llvm::raw_ostream& os) const {
188 Str->printPretty(os, 0, PrintingPolicy(getContext().getLangOptions()));
Ted Kremenek3a4beb52009-04-21 18:09:22 +0000189}
190
Ted Kremenekfaf94872009-07-13 23:31:04 +0000191void SymbolicRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenekfd3ad732009-07-13 23:38:57 +0000192 os << "SymRegion{" << sym << '}';
Ted Kremenek3a4beb52009-04-21 18:09:22 +0000193}
194
Ted Kremenekfaf94872009-07-13 23:31:04 +0000195void VarRegion::dumpToStream(llvm::raw_ostream& os) const {
Chris Lattner271d4c22008-11-24 05:29:24 +0000196 os << cast<VarDecl>(D)->getNameAsString();
Ted Kremenekb15eba42008-10-04 05:50:14 +0000197}
198
Ted Kremenek98137f72009-08-01 06:17:29 +0000199void RegionRawOffset::dump() const {
200 dumpToStream(llvm::errs());
201}
202
203void RegionRawOffset::dumpToStream(llvm::raw_ostream& os) const {
204 os << "raw_offset{" << getRegion() << ',' << getByteOffset() << '}';
205}
206
Ted Kremenekb15eba42008-10-04 05:50:14 +0000207//===----------------------------------------------------------------------===//
208// MemRegionManager methods.
209//===----------------------------------------------------------------------===//
Ted Kremenek98137f72009-08-01 06:17:29 +0000210
Ted Kremenekd8f4cef2009-06-23 00:46:41 +0000211MemSpaceRegion* MemRegionManager::LazyAllocate(MemSpaceRegion*& region) {
Ted Kremenekb15eba42008-10-04 05:50:14 +0000212 if (!region) {
213 region = (MemSpaceRegion*) A.Allocate<MemSpaceRegion>();
Ted Kremenekd8f4cef2009-06-23 00:46:41 +0000214 new (region) MemSpaceRegion(this);
Ted Kremenekb15eba42008-10-04 05:50:14 +0000215 }
Ted Kremenekd8f4cef2009-06-23 00:46:41 +0000216
Ted Kremenekb15eba42008-10-04 05:50:14 +0000217 return region;
218}
219
220MemSpaceRegion* MemRegionManager::getStackRegion() {
221 return LazyAllocate(stack);
222}
223
Ted Kremenek4f8ae752009-07-02 18:14:59 +0000224MemSpaceRegion* MemRegionManager::getStackArgumentsRegion() {
225 return LazyAllocate(stackArguments);
226}
227
Ted Kremenekb15eba42008-10-04 05:50:14 +0000228MemSpaceRegion* MemRegionManager::getGlobalsRegion() {
229 return LazyAllocate(globals);
230}
231
232MemSpaceRegion* MemRegionManager::getHeapRegion() {
233 return LazyAllocate(heap);
234}
235
Zhongxing Xu79c57f82008-10-08 02:50:44 +0000236MemSpaceRegion* MemRegionManager::getUnknownRegion() {
237 return LazyAllocate(unknown);
238}
239
Zhongxing Xuef3fb4c2009-04-10 08:45:10 +0000240MemSpaceRegion* MemRegionManager::getCodeRegion() {
241 return LazyAllocate(code);
242}
243
Ted Kremenek1b85d8e2009-06-22 23:13:13 +0000244//===----------------------------------------------------------------------===//
245// Constructing regions.
246//===----------------------------------------------------------------------===//
247
Zhongxing Xu73507bd2008-10-25 14:13:41 +0000248StringRegion* MemRegionManager::getStringRegion(const StringLiteral* Str) {
Ted Kremenek1b85d8e2009-06-22 23:13:13 +0000249 return getRegion<StringRegion>(Str);
Zhongxing Xu73507bd2008-10-25 14:13:41 +0000250}
251
Ted Kremenek81329ab2008-10-27 21:01:26 +0000252VarRegion* MemRegionManager::getVarRegion(const VarDecl* d) {
Ted Kremenek1b85d8e2009-06-22 23:13:13 +0000253 return getRegion<VarRegion>(d);
Ted Kremenekb15eba42008-10-04 05:50:14 +0000254}
255
Ted Kremenek6bc91b92008-10-27 20:57:58 +0000256CompoundLiteralRegion*
257MemRegionManager::getCompoundLiteralRegion(const CompoundLiteralExpr* CL) {
Ted Kremenek1b85d8e2009-06-22 23:13:13 +0000258 return getRegion<CompoundLiteralRegion>(CL);
Ted Kremenek6bc91b92008-10-27 20:57:58 +0000259}
260
Ted Kremenek2c0de352008-12-13 19:24:37 +0000261ElementRegion*
Ted Kremenekaf81ece2009-05-04 06:18:28 +0000262MemRegionManager::getElementRegion(QualType elementType, SVal Idx,
Ted Kremenek369239c2009-07-16 01:33:37 +0000263 const MemRegion* superRegion,
264 ASTContext& Ctx){
Zhongxing Xufe483ee2009-06-16 09:55:50 +0000265
266 QualType T = Ctx.getCanonicalType(elementType);
Ted Kremenek2c0de352008-12-13 19:24:37 +0000267
Zhongxing Xu54969732008-10-21 05:27:10 +0000268 llvm::FoldingSetNodeID ID;
Zhongxing Xufe483ee2009-06-16 09:55:50 +0000269 ElementRegion::ProfileRegion(ID, T, Idx, superRegion);
Zhongxing Xu54969732008-10-21 05:27:10 +0000270
271 void* InsertPos;
272 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
273 ElementRegion* R = cast_or_null<ElementRegion>(data);
274
275 if (!R) {
276 R = (ElementRegion*) A.Allocate<ElementRegion>();
Zhongxing Xufe483ee2009-06-16 09:55:50 +0000277 new (R) ElementRegion(T, Idx, superRegion);
Zhongxing Xu54969732008-10-21 05:27:10 +0000278 Regions.InsertNode(R, InsertPos);
279 }
280
281 return R;
282}
283
Zhongxing Xuef3fb4c2009-04-10 08:45:10 +0000284CodeTextRegion* MemRegionManager::getCodeTextRegion(const FunctionDecl* fd,
285 QualType t) {
Zhongxing Xu54cd8122009-06-23 03:50:30 +0000286 return getRegion<CodeTextRegion>(fd, t);
Zhongxing Xuef3fb4c2009-04-10 08:45:10 +0000287}
288
289CodeTextRegion* MemRegionManager::getCodeTextRegion(SymbolRef sym, QualType t) {
Zhongxing Xu54cd8122009-06-23 03:50:30 +0000290 return getRegion<CodeTextRegion>(sym, t);
Zhongxing Xuef3fb4c2009-04-10 08:45:10 +0000291}
292
Ted Kremenek38a4b4b2008-10-17 20:28:54 +0000293/// getSymbolicRegion - Retrieve or create a "symbolic" memory region.
Ted Kremenek74556a12009-03-26 03:35:11 +0000294SymbolicRegion* MemRegionManager::getSymbolicRegion(SymbolRef sym) {
Ted Kremenek1b85d8e2009-06-22 23:13:13 +0000295 return getRegion<SymbolicRegion>(sym);
Ted Kremenek38a4b4b2008-10-17 20:28:54 +0000296}
297
Ted Kremenekb15eba42008-10-04 05:50:14 +0000298FieldRegion* MemRegionManager::getFieldRegion(const FieldDecl* d,
Ted Kremenek38a4b4b2008-10-17 20:28:54 +0000299 const MemRegion* superRegion) {
Ted Kremenek72d1f392009-07-10 16:51:45 +0000300 return getSubRegion<FieldRegion>(d, superRegion);
Ted Kremenekb15eba42008-10-04 05:50:14 +0000301}
302
Ted Kremenek38a4b4b2008-10-17 20:28:54 +0000303ObjCIvarRegion*
304MemRegionManager::getObjCIvarRegion(const ObjCIvarDecl* d,
305 const MemRegion* superRegion) {
Ted Kremenek72d1f392009-07-10 16:51:45 +0000306 return getSubRegion<ObjCIvarRegion>(d, superRegion);
Ted Kremenekb15eba42008-10-04 05:50:14 +0000307}
308
Ted Kremenek2539c112008-10-24 20:30:08 +0000309ObjCObjectRegion*
310MemRegionManager::getObjCObjectRegion(const ObjCInterfaceDecl* d,
Ted Kremenek12218222009-06-23 00:04:09 +0000311 const MemRegion* superRegion) {
Ted Kremenek72d1f392009-07-10 16:51:45 +0000312 return getSubRegion<ObjCObjectRegion>(d, superRegion);
Ted Kremenek2539c112008-10-24 20:30:08 +0000313}
314
Ted Kremenekea9ca502008-11-02 00:34:33 +0000315AllocaRegion* MemRegionManager::getAllocaRegion(const Expr* E, unsigned cnt) {
Ted Kremenek3680b452009-06-23 00:15:41 +0000316 return getRegion<AllocaRegion>(E, cnt);
Ted Kremenekea9ca502008-11-02 00:34:33 +0000317}
318
Ted Kremenek7e5d2922009-06-23 18:17:08 +0000319const MemSpaceRegion *MemRegion::getMemorySpace() const {
320 const MemRegion *R = this;
Ted Kremenekdd2ec492009-06-23 18:05:21 +0000321 const SubRegion* SR = dyn_cast<SubRegion>(this);
Ted Kremenekb15eba42008-10-04 05:50:14 +0000322
Ted Kremenek38a4b4b2008-10-17 20:28:54 +0000323 while (SR) {
Ted Kremenek7e5d2922009-06-23 18:17:08 +0000324 R = SR->getSuperRegion();
325 SR = dyn_cast<SubRegion>(R);
Ted Kremenekb15eba42008-10-04 05:50:14 +0000326 }
Ted Kremenek7e5d2922009-06-23 18:17:08 +0000327
328 return dyn_cast<MemSpaceRegion>(R);
329}
330
331bool MemRegion::hasStackStorage() const {
Ted Kremenek4f8ae752009-07-02 18:14:59 +0000332 if (const MemSpaceRegion *MS = getMemorySpace()) {
333 MemRegionManager *Mgr = getMemRegionManager();
334 return MS == Mgr->getStackRegion() || MS == Mgr->getStackArgumentsRegion();
335 }
Ted Kremenek7e5d2922009-06-23 18:17:08 +0000336
Ted Kremenekb15eba42008-10-04 05:50:14 +0000337 return false;
338}
Ted Kremenek8765ebc2009-04-11 00:11:10 +0000339
Ted Kremenekdd2ec492009-06-23 18:05:21 +0000340bool MemRegion::hasHeapStorage() const {
Ted Kremenek7e5d2922009-06-23 18:17:08 +0000341 if (const MemSpaceRegion *MS = getMemorySpace())
342 return MS == getMemRegionManager()->getHeapRegion();
Zhongxing Xu04b97b82009-06-23 02:51:21 +0000343
344 return false;
345}
Ted Kremenek8765ebc2009-04-11 00:11:10 +0000346
Ted Kremenek7e5d2922009-06-23 18:17:08 +0000347bool MemRegion::hasHeapOrStackStorage() const {
348 if (const MemSpaceRegion *MS = getMemorySpace()) {
349 MemRegionManager *Mgr = getMemRegionManager();
Ted Kremenek4f8ae752009-07-02 18:14:59 +0000350 return MS == Mgr->getHeapRegion()
351 || MS == Mgr->getStackRegion()
352 || MS == Mgr->getStackArgumentsRegion();
Ted Kremenek7e5d2922009-06-23 18:17:08 +0000353 }
354 return false;
Ted Kremenek8f1e3732009-07-02 18:25:09 +0000355}
356
357bool MemRegion::hasGlobalsStorage() const {
358 if (const MemSpaceRegion *MS = getMemorySpace())
359 return MS == getMemRegionManager()->getGlobalsRegion();
360
361 return false;
362}
363
Ted Kremenek17eb5622009-07-02 22:02:15 +0000364bool MemRegion::hasParametersStorage() const {
365 if (const MemSpaceRegion *MS = getMemorySpace())
366 return MS == getMemRegionManager()->getStackArgumentsRegion();
367
368 return false;
369}
370
Ted Kremenek8f1e3732009-07-02 18:25:09 +0000371bool MemRegion::hasGlobalsOrParametersStorage() const {
372 if (const MemSpaceRegion *MS = getMemorySpace()) {
373 MemRegionManager *Mgr = getMemRegionManager();
374 return MS == Mgr->getGlobalsRegion()
375 || MS == Mgr->getStackArgumentsRegion();
376 }
377 return false;
378}
Ted Kremenek7e5d2922009-06-23 18:17:08 +0000379
Ted Kremenek8765ebc2009-04-11 00:11:10 +0000380//===----------------------------------------------------------------------===//
381// View handling.
382//===----------------------------------------------------------------------===//
383
Ted Kremenekce563192009-07-29 18:14:27 +0000384const MemRegion *MemRegion::getBaseRegion() const {
385 const MemRegion *R = this;
386 while (true) {
387 if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) {
388 // FIXME: generalize. Essentially we want to strip away ElementRegions
389 // that were layered on a symbolic region because of casts. We only
390 // want to strip away ElementRegions, however, where the index is 0.
391 SVal index = ER->getIndex();
392 if (nonloc::ConcreteInt *CI = dyn_cast<nonloc::ConcreteInt>(&index)) {
Ted Kremenek98137f72009-08-01 06:17:29 +0000393 if (CI->getValue().getSExtValue() == 0) {
Ted Kremenekce563192009-07-29 18:14:27 +0000394 R = ER->getSuperRegion();
395 continue;
396 }
397 }
398 }
399 break;
400 }
401 return R;
402}
Ted Kremenek98137f72009-08-01 06:17:29 +0000403
404// FIXME: Merge with the implementation of the same method in Store.cpp
405static bool IsCompleteType(ASTContext &Ctx, QualType Ty) {
406 if (const RecordType *RT = Ty->getAs<RecordType>()) {
407 const RecordDecl *D = RT->getDecl();
408 if (!D->getDefinition(Ctx))
409 return false;
410 }
411
412 return true;
413}
414
415RegionRawOffset ElementRegion::getAsRawOffset() const {
416 int64_t offset = 0;
417 const ElementRegion *ER = this;
418 const MemRegion *superR = NULL;
419 ASTContext &C = getContext();
420
421 // FIXME: Handle multi-dimensional arrays.
422
423 while (ER) {
424 superR = ER->getSuperRegion();
425
426 // FIXME: generalize to symbolic offsets.
427 SVal index = ER->getIndex();
428 if (nonloc::ConcreteInt *CI = dyn_cast<nonloc::ConcreteInt>(&index)) {
429 // Update the offset.
430 int64_t i = CI->getValue().getSExtValue();
431
432 if (i != 0) {
433 QualType elemType = ER->getElementType();
434
435 // If we are pointing to an incomplete type, go no further.
436 if (!IsCompleteType(C, elemType)) {
437 superR = ER;
438 break;
439 }
440
441 int64_t size = (int64_t) (C.getTypeSize(elemType) / 8);
442 offset += (i * size);
443 }
444
445 // Go to the next ElementRegion (if any).
446 ER = dyn_cast<ElementRegion>(superR);
447 continue;
448 }
449
450 return NULL;
451 }
452
453 assert(superR && "super region cannot be NULL");
454 return RegionRawOffset(superR, offset);
455}
456