blob: f2a4e0dd2c52a12fd7777f77a6f3bce6471a09e1 [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
Ted Kremenek1309f9a2010-01-25 04:41:41 +000016#include "clang/Checker/PathSensitive/MemRegion.h"
Jordy Rose32f26562010-07-04 00:00:41 +000017#include "clang/Checker/PathSensitive/ValueManager.h"
Benjamin Kramer5e2d2c22010-03-27 21:19:47 +000018#include "clang/Analysis/AnalysisContext.h"
19#include "clang/Analysis/Support/BumpVector.h"
Ken Dyck199c3d62010-01-11 17:06:35 +000020#include "clang/AST/CharUnits.h"
Zhongxing Xu7caf9b32010-08-02 04:56:14 +000021#include "clang/AST/RecordLayout.h"
Ted Kremenek1309f9a2010-01-25 04:41:41 +000022#include "llvm/Support/raw_ostream.h"
Ted Kremenek9e240492008-10-04 05:50:14 +000023
24using namespace clang;
25
Ted Kremenek25010132009-06-22 23:13:13 +000026//===----------------------------------------------------------------------===//
Ted Kremenekbcd7f9f2009-12-04 00:05:57 +000027// MemRegion Construction.
28//===----------------------------------------------------------------------===//
29
30template<typename RegionTy> struct MemRegionManagerTrait;
31
32template <typename RegionTy, typename A1>
33RegionTy* MemRegionManager::getRegion(const A1 a1) {
Ted Kremenekdcee3ce2010-07-01 20:16:50 +000034
Ted Kremenekbcd7f9f2009-12-04 00:05:57 +000035 const typename MemRegionManagerTrait<RegionTy>::SuperRegionTy *superRegion =
36 MemRegionManagerTrait<RegionTy>::getSuperRegion(*this, a1);
Ted Kremenekdcee3ce2010-07-01 20:16:50 +000037
Ted Kremenekbcd7f9f2009-12-04 00:05:57 +000038 llvm::FoldingSetNodeID ID;
39 RegionTy::ProfileRegion(ID, a1, superRegion);
40 void* InsertPos;
41 RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
42 InsertPos));
Ted Kremenekdcee3ce2010-07-01 20:16:50 +000043
Ted Kremenekbcd7f9f2009-12-04 00:05:57 +000044 if (!R) {
45 R = (RegionTy*) A.Allocate<RegionTy>();
46 new (R) RegionTy(a1, superRegion);
47 Regions.InsertNode(R, InsertPos);
48 }
Ted Kremenekdcee3ce2010-07-01 20:16:50 +000049
Ted Kremenekbcd7f9f2009-12-04 00:05:57 +000050 return R;
51}
52
53template <typename RegionTy, typename A1>
54RegionTy* MemRegionManager::getSubRegion(const A1 a1,
55 const MemRegion *superRegion) {
56 llvm::FoldingSetNodeID ID;
57 RegionTy::ProfileRegion(ID, a1, superRegion);
58 void* InsertPos;
59 RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
60 InsertPos));
Ted Kremenekdcee3ce2010-07-01 20:16:50 +000061
Ted Kremenekbcd7f9f2009-12-04 00:05:57 +000062 if (!R) {
63 R = (RegionTy*) A.Allocate<RegionTy>();
64 new (R) RegionTy(a1, superRegion);
65 Regions.InsertNode(R, InsertPos);
66 }
Ted Kremenekdcee3ce2010-07-01 20:16:50 +000067
Ted Kremenekbcd7f9f2009-12-04 00:05:57 +000068 return R;
69}
70
71template <typename RegionTy, typename A1, typename A2>
72RegionTy* MemRegionManager::getRegion(const A1 a1, const A2 a2) {
Ted Kremenekdcee3ce2010-07-01 20:16:50 +000073
Ted Kremenekbcd7f9f2009-12-04 00:05:57 +000074 const typename MemRegionManagerTrait<RegionTy>::SuperRegionTy *superRegion =
75 MemRegionManagerTrait<RegionTy>::getSuperRegion(*this, a1, a2);
Ted Kremenekdcee3ce2010-07-01 20:16:50 +000076
Ted Kremenekbcd7f9f2009-12-04 00:05:57 +000077 llvm::FoldingSetNodeID ID;
78 RegionTy::ProfileRegion(ID, a1, a2, superRegion);
79 void* InsertPos;
80 RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
81 InsertPos));
Ted Kremenekdcee3ce2010-07-01 20:16:50 +000082
Ted Kremenekbcd7f9f2009-12-04 00:05:57 +000083 if (!R) {
84 R = (RegionTy*) A.Allocate<RegionTy>();
85 new (R) RegionTy(a1, a2, superRegion);
86 Regions.InsertNode(R, InsertPos);
87 }
Ted Kremenekdcee3ce2010-07-01 20:16:50 +000088
Ted Kremenekbcd7f9f2009-12-04 00:05:57 +000089 return R;
90}
91
92template <typename RegionTy, typename A1, typename A2>
93RegionTy* MemRegionManager::getSubRegion(const A1 a1, const A2 a2,
94 const MemRegion *superRegion) {
Ted Kremenekdcee3ce2010-07-01 20:16:50 +000095
Ted Kremenekbcd7f9f2009-12-04 00:05:57 +000096 llvm::FoldingSetNodeID ID;
97 RegionTy::ProfileRegion(ID, a1, a2, superRegion);
98 void* InsertPos;
99 RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
100 InsertPos));
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000101
Ted Kremenekbcd7f9f2009-12-04 00:05:57 +0000102 if (!R) {
103 R = (RegionTy*) A.Allocate<RegionTy>();
104 new (R) RegionTy(a1, a2, superRegion);
105 Regions.InsertNode(R, InsertPos);
106 }
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000107
Ted Kremenekbcd7f9f2009-12-04 00:05:57 +0000108 return R;
109}
110
Ted Kremenek67d12872009-12-07 22:05:27 +0000111template <typename RegionTy, typename A1, typename A2, typename A3>
112RegionTy* MemRegionManager::getSubRegion(const A1 a1, const A2 a2, const A3 a3,
113 const MemRegion *superRegion) {
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000114
Ted Kremenek67d12872009-12-07 22:05:27 +0000115 llvm::FoldingSetNodeID ID;
116 RegionTy::ProfileRegion(ID, a1, a2, a3, superRegion);
117 void* InsertPos;
118 RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
119 InsertPos));
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000120
Ted Kremenek67d12872009-12-07 22:05:27 +0000121 if (!R) {
122 R = (RegionTy*) A.Allocate<RegionTy>();
123 new (R) RegionTy(a1, a2, a3, superRegion);
124 Regions.InsertNode(R, InsertPos);
Ted Kremenekbcd7f9f2009-12-04 00:05:57 +0000125 }
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000126
Ted Kremenek67d12872009-12-07 22:05:27 +0000127 return R;
128}
Ted Kremenekbcd7f9f2009-12-04 00:05:57 +0000129
130//===----------------------------------------------------------------------===//
Ted Kremenek42400962009-11-26 02:34:36 +0000131// Object destruction.
Ted Kremenek25010132009-06-22 23:13:13 +0000132//===----------------------------------------------------------------------===//
Ted Kremenek9e240492008-10-04 05:50:14 +0000133
134MemRegion::~MemRegion() {}
135
Ted Kremenek42400962009-11-26 02:34:36 +0000136MemRegionManager::~MemRegionManager() {
137 // All regions and their data are BumpPtrAllocated. No need to call
138 // their destructors.
139}
140
141//===----------------------------------------------------------------------===//
142// Basic methods.
143//===----------------------------------------------------------------------===//
144
Zhongxing Xu7e5d6ed2009-01-08 13:17:14 +0000145bool SubRegion::isSubRegionOf(const MemRegion* R) const {
146 const MemRegion* r = getSuperRegion();
147 while (r != 0) {
148 if (r == R)
149 return true;
150 if (const SubRegion* sr = dyn_cast<SubRegion>(r))
151 r = sr->getSuperRegion();
152 else
153 break;
154 }
155 return false;
156}
157
Ted Kremeneka43484a2009-06-23 00:46:41 +0000158MemRegionManager* SubRegion::getMemRegionManager() const {
159 const SubRegion* r = this;
160 do {
161 const MemRegion *superRegion = r->getSuperRegion();
162 if (const SubRegion *sr = dyn_cast<SubRegion>(superRegion)) {
163 r = sr;
164 continue;
165 }
166 return superRegion->getMemRegionManager();
167 } while (1);
168}
169
Ted Kremenek5348f942009-12-14 22:15:06 +0000170const StackFrameContext *VarRegion::getStackFrame() const {
171 const StackSpaceRegion *SSR = dyn_cast<StackSpaceRegion>(getMemorySpace());
172 return SSR ? SSR->getStackFrame() : NULL;
173}
174
175//===----------------------------------------------------------------------===//
Jordy Rose32f26562010-07-04 00:00:41 +0000176// Region extents.
177//===----------------------------------------------------------------------===//
178
179DefinedOrUnknownSVal DeclRegion::getExtent(ValueManager& ValMgr) const {
180 ASTContext& Ctx = ValMgr.getContext();
Zhongxing Xu018220c2010-08-11 06:10:55 +0000181 QualType T = getDesugaredValueType();
Jordy Rose32f26562010-07-04 00:00:41 +0000182
Jordy Rose52e04c52010-07-05 00:50:15 +0000183 if (isa<VariableArrayType>(T))
184 return nonloc::SymbolVal(ValMgr.getSymbolManager().getExtentSymbol(this));
185 if (isa<IncompleteArrayType>(T))
Jordy Rose32f26562010-07-04 00:00:41 +0000186 return UnknownVal();
187
188 CharUnits Size = Ctx.getTypeSizeInChars(T);
189 QualType SizeTy = Ctx.getSizeType();
190 return ValMgr.makeIntVal(Size.getQuantity(), SizeTy);
191}
192
193DefinedOrUnknownSVal FieldRegion::getExtent(ValueManager& ValMgr) const {
194 DefinedOrUnknownSVal Extent = DeclRegion::getExtent(ValMgr);
195
196 // A zero-length array at the end of a struct often stands for dynamically-
197 // allocated extra memory.
198 if (Extent.isZeroConstant()) {
Zhongxing Xu018220c2010-08-11 06:10:55 +0000199 QualType T = getDesugaredValueType();
Jordy Rose32f26562010-07-04 00:00:41 +0000200
201 if (isa<ConstantArrayType>(T))
202 return UnknownVal();
203 }
204
205 return Extent;
206}
207
208DefinedOrUnknownSVal AllocaRegion::getExtent(ValueManager& ValMgr) const {
209 return nonloc::SymbolVal(ValMgr.getSymbolManager().getExtentSymbol(this));
210}
211
212DefinedOrUnknownSVal SymbolicRegion::getExtent(ValueManager& ValMgr) const {
213 return nonloc::SymbolVal(ValMgr.getSymbolManager().getExtentSymbol(this));
214}
215
216DefinedOrUnknownSVal StringRegion::getExtent(ValueManager& ValMgr) const {
217 QualType SizeTy = ValMgr.getContext().getSizeType();
218 return ValMgr.makeIntVal(getStringLiteral()->getByteLength()+1, SizeTy);
219}
220
Zhongxing Xu4fd56812010-11-26 08:21:53 +0000221QualType CXXBaseObjectRegion::getValueType() const {
222 return QualType(decl->getTypeForDecl(), 0);
223}
224
Jordy Rose32f26562010-07-04 00:00:41 +0000225//===----------------------------------------------------------------------===//
Ted Kremenek5348f942009-12-14 22:15:06 +0000226// FoldingSet profiling.
227//===----------------------------------------------------------------------===//
228
Ted Kremenek9e240492008-10-04 05:50:14 +0000229void MemSpaceRegion::Profile(llvm::FoldingSetNodeID& ID) const {
230 ID.AddInteger((unsigned)getKind());
231}
232
Ted Kremenek67d12872009-12-07 22:05:27 +0000233void StackSpaceRegion::Profile(llvm::FoldingSetNodeID &ID) const {
234 ID.AddInteger((unsigned)getKind());
235 ID.AddPointer(getStackFrame());
236}
237
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000238void StaticGlobalSpaceRegion::Profile(llvm::FoldingSetNodeID &ID) const {
239 ID.AddInteger((unsigned)getKind());
240 ID.AddPointer(getCodeRegion());
241}
242
Mike Stump1eb44332009-09-09 15:08:12 +0000243void StringRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
244 const StringLiteral* Str,
Zhongxing Xue9f4e542008-10-25 14:13:41 +0000245 const MemRegion* superRegion) {
246 ID.AddInteger((unsigned) StringRegionKind);
247 ID.AddPointer(Str);
248 ID.AddPointer(superRegion);
249}
250
Ted Kremenek7090ae12008-11-02 00:34:33 +0000251void AllocaRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
Ted Kremenek7ae7ad92009-06-23 00:15:41 +0000252 const Expr* Ex, unsigned cnt,
253 const MemRegion *) {
Ted Kremenek7090ae12008-11-02 00:34:33 +0000254 ID.AddInteger((unsigned) AllocaRegionKind);
255 ID.AddPointer(Ex);
256 ID.AddInteger(cnt);
257}
258
259void AllocaRegion::Profile(llvm::FoldingSetNodeID& ID) const {
Ted Kremenek7ae7ad92009-06-23 00:15:41 +0000260 ProfileRegion(ID, Ex, Cnt, superRegion);
Ted Kremenek7090ae12008-11-02 00:34:33 +0000261}
262
Ted Kremenek329d6fd2008-10-27 20:57:58 +0000263void CompoundLiteralRegion::Profile(llvm::FoldingSetNodeID& ID) const {
264 CompoundLiteralRegion::ProfileRegion(ID, CL, superRegion);
265}
266
267void CompoundLiteralRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
268 const CompoundLiteralExpr* CL,
269 const MemRegion* superRegion) {
270 ID.AddInteger((unsigned) CompoundLiteralRegionKind);
271 ID.AddPointer(CL);
272 ID.AddPointer(superRegion);
273}
274
Ted Kremenekde0d2632010-01-05 02:18:06 +0000275void CXXThisRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
276 const PointerType *PT,
277 const MemRegion *sRegion) {
278 ID.AddInteger((unsigned) CXXThisRegionKind);
279 ID.AddPointer(PT);
280 ID.AddPointer(sRegion);
281}
282
283void CXXThisRegion::Profile(llvm::FoldingSetNodeID &ID) const {
284 CXXThisRegion::ProfileRegion(ID, ThisPointerTy, superRegion);
285}
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000286
Ted Kremenek9e240492008-10-04 05:50:14 +0000287void DeclRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, const Decl* D,
288 const MemRegion* superRegion, Kind k) {
289 ID.AddInteger((unsigned) k);
290 ID.AddPointer(D);
291 ID.AddPointer(superRegion);
292}
293
294void DeclRegion::Profile(llvm::FoldingSetNodeID& ID) const {
295 DeclRegion::ProfileRegion(ID, D, superRegion, getKind());
296}
297
Ted Kremenekd17da2b2009-08-21 22:28:32 +0000298void VarRegion::Profile(llvm::FoldingSetNodeID &ID) const {
Ted Kremenek67d12872009-12-07 22:05:27 +0000299 VarRegion::ProfileRegion(ID, getDecl(), superRegion);
Ted Kremenekd17da2b2009-08-21 22:28:32 +0000300}
301
Ted Kremenek25010132009-06-22 23:13:13 +0000302void SymbolicRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, SymbolRef sym,
303 const MemRegion *sreg) {
Ted Kremenek993f1c72008-10-17 20:28:54 +0000304 ID.AddInteger((unsigned) MemRegion::SymbolicRegionKind);
Ted Kremenek6d0e2d22008-12-05 02:39:38 +0000305 ID.Add(sym);
Ted Kremenek25010132009-06-22 23:13:13 +0000306 ID.AddPointer(sreg);
Ted Kremenek993f1c72008-10-17 20:28:54 +0000307}
308
309void SymbolicRegion::Profile(llvm::FoldingSetNodeID& ID) const {
Ted Kremenek25010132009-06-22 23:13:13 +0000310 SymbolicRegion::ProfileRegion(ID, sym, getSuperRegion());
Ted Kremenek993f1c72008-10-17 20:28:54 +0000311}
312
Ted Kremenekf936f452009-05-04 06:18:28 +0000313void ElementRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
Mike Stump1eb44332009-09-09 15:08:12 +0000314 QualType ElementType, SVal Idx,
Zhongxing Xu511191c2008-10-21 05:27:10 +0000315 const MemRegion* superRegion) {
316 ID.AddInteger(MemRegion::ElementRegionKind);
Ted Kremenekf936f452009-05-04 06:18:28 +0000317 ID.Add(ElementType);
Zhongxing Xu511191c2008-10-21 05:27:10 +0000318 ID.AddPointer(superRegion);
319 Idx.Profile(ID);
320}
321
322void ElementRegion::Profile(llvm::FoldingSetNodeID& ID) const {
Ted Kremenekf936f452009-05-04 06:18:28 +0000323 ElementRegion::ProfileRegion(ID, ElementType, Index, superRegion);
Zhongxing Xu511191c2008-10-21 05:27:10 +0000324}
Zhongxing Xu27b57062008-10-27 13:17:02 +0000325
Ted Kremenekeb1c7a02009-11-25 01:32:22 +0000326void FunctionTextRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
327 const FunctionDecl *FD,
328 const MemRegion*) {
329 ID.AddInteger(MemRegion::FunctionTextRegionKind);
Ted Kremenekabd46e12009-08-28 04:49:15 +0000330 ID.AddPointer(FD);
Zhongxing Xuec13d922009-04-10 08:45:10 +0000331}
332
Ted Kremenekeb1c7a02009-11-25 01:32:22 +0000333void FunctionTextRegion::Profile(llvm::FoldingSetNodeID& ID) const {
334 FunctionTextRegion::ProfileRegion(ID, FD, superRegion);
335}
336
337void BlockTextRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
Ted Kremenek67d12872009-12-07 22:05:27 +0000338 const BlockDecl *BD, CanQualType,
339 const AnalysisContext *AC,
340 const MemRegion*) {
Ted Kremenekeb1c7a02009-11-25 01:32:22 +0000341 ID.AddInteger(MemRegion::BlockTextRegionKind);
342 ID.AddPointer(BD);
343}
344
345void BlockTextRegion::Profile(llvm::FoldingSetNodeID& ID) const {
Ted Kremenek67d12872009-12-07 22:05:27 +0000346 BlockTextRegion::ProfileRegion(ID, BD, locTy, AC, superRegion);
Zhongxing Xuec13d922009-04-10 08:45:10 +0000347}
348
Ted Kremenek0a8112a2009-11-25 23:53:07 +0000349void BlockDataRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
350 const BlockTextRegion *BC,
351 const LocationContext *LC,
Ted Kremenek67d12872009-12-07 22:05:27 +0000352 const MemRegion *sReg) {
Ted Kremenek0a8112a2009-11-25 23:53:07 +0000353 ID.AddInteger(MemRegion::BlockDataRegionKind);
354 ID.AddPointer(BC);
355 ID.AddPointer(LC);
Ted Kremenek67d12872009-12-07 22:05:27 +0000356 ID.AddPointer(sReg);
Ted Kremenek0a8112a2009-11-25 23:53:07 +0000357}
358
359void BlockDataRegion::Profile(llvm::FoldingSetNodeID& ID) const {
Ted Kremenek67d12872009-12-07 22:05:27 +0000360 BlockDataRegion::ProfileRegion(ID, BC, LC, getSuperRegion());
Ted Kremenek0a8112a2009-11-25 23:53:07 +0000361}
362
Zhongxing Xu02fe28c2010-11-26 08:52:48 +0000363void CXXTempObjectRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
364 Expr const *Ex,
365 const MemRegion *sReg) {
Zhongxing Xubc37b8d2010-01-09 09:16:47 +0000366 ID.AddPointer(Ex);
Zhongxing Xubb141212009-12-16 11:27:52 +0000367 ID.AddPointer(sReg);
368}
369
Zhongxing Xu02fe28c2010-11-26 08:52:48 +0000370void CXXTempObjectRegion::Profile(llvm::FoldingSetNodeID &ID) const {
Zhongxing Xubc37b8d2010-01-09 09:16:47 +0000371 ProfileRegion(ID, Ex, getSuperRegion());
Zhongxing Xubb141212009-12-16 11:27:52 +0000372}
373
Zhongxing Xu4fd56812010-11-26 08:21:53 +0000374void CXXBaseObjectRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
375 const CXXRecordDecl *decl,
376 const MemRegion *sReg) {
377 ID.AddPointer(decl);
378 ID.AddPointer(sReg);
379}
380
381void CXXBaseObjectRegion::Profile(llvm::FoldingSetNodeID &ID) const {
382 ProfileRegion(ID, decl, superRegion);
383}
384
Zhongxing Xu026c6632009-02-05 06:57:29 +0000385//===----------------------------------------------------------------------===//
Ted Kremenek9e240492008-10-04 05:50:14 +0000386// Region pretty-printing.
387//===----------------------------------------------------------------------===//
388
Ted Kremenek8800ad42009-07-13 23:31:04 +0000389void MemRegion::dump() const {
390 dumpToStream(llvm::errs());
Ted Kremenek7f39d292009-07-02 17:24:10 +0000391}
392
Ted Kremenek9e240492008-10-04 05:50:14 +0000393std::string MemRegion::getString() const {
394 std::string s;
395 llvm::raw_string_ostream os(s);
Ted Kremenek8800ad42009-07-13 23:31:04 +0000396 dumpToStream(os);
Ted Kremenek9e240492008-10-04 05:50:14 +0000397 return os.str();
398}
399
Ted Kremenek8800ad42009-07-13 23:31:04 +0000400void MemRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenek9e240492008-10-04 05:50:14 +0000401 os << "<Unknown Region>";
402}
403
Ted Kremenek8800ad42009-07-13 23:31:04 +0000404void AllocaRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenek7090ae12008-11-02 00:34:33 +0000405 os << "alloca{" << (void*) Ex << ',' << Cnt << '}';
406}
407
Ted Kremenekeb1c7a02009-11-25 01:32:22 +0000408void FunctionTextRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenekabd46e12009-08-28 04:49:15 +0000409 os << "code{" << getDecl()->getDeclName().getAsString() << '}';
Ted Kremenek72e03202009-04-21 19:56:58 +0000410}
411
Ted Kremenekeb1c7a02009-11-25 01:32:22 +0000412void BlockTextRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenek0a8112a2009-11-25 23:53:07 +0000413 os << "block_code{" << (void*) this << '}';
Ted Kremenekeb1c7a02009-11-25 01:32:22 +0000414}
415
Ted Kremenek0a8112a2009-11-25 23:53:07 +0000416void BlockDataRegion::dumpToStream(llvm::raw_ostream& os) const {
417 os << "block_data{" << BC << '}';
418}
419
Ted Kremenek8800ad42009-07-13 23:31:04 +0000420void CompoundLiteralRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenek5639a3e2009-04-21 18:09:22 +0000421 // FIXME: More elaborate pretty-printing.
422 os << "{ " << (void*) CL << " }";
423}
424
Zhongxing Xu02fe28c2010-11-26 08:52:48 +0000425void CXXTempObjectRegion::dumpToStream(llvm::raw_ostream &os) const {
Zhongxing Xue1aeb132010-11-25 02:07:24 +0000426 os << "temp_object";
427}
428
Zhongxing Xu4fd56812010-11-26 08:21:53 +0000429void CXXBaseObjectRegion::dumpToStream(llvm::raw_ostream &os) const {
430 os << "base " << decl->getName();
431}
432
Ted Kremenekde0d2632010-01-05 02:18:06 +0000433void CXXThisRegion::dumpToStream(llvm::raw_ostream &os) const {
434 os << "this";
435}
436
Ted Kremenek8800ad42009-07-13 23:31:04 +0000437void ElementRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000438 os << "element{" << superRegion << ','
439 << Index << ',' << getElementType().getAsString() << '}';
Ted Kremenek5639a3e2009-04-21 18:09:22 +0000440}
441
Ted Kremenek8800ad42009-07-13 23:31:04 +0000442void FieldRegion::dumpToStream(llvm::raw_ostream& os) const {
Benjamin Kramer900fc632010-04-17 09:33:03 +0000443 os << superRegion << "->" << getDecl();
Ted Kremenek5639a3e2009-04-21 18:09:22 +0000444}
445
Ted Kremenekfa87d812010-07-06 23:37:21 +0000446void NonStaticGlobalSpaceRegion::dumpToStream(llvm::raw_ostream &os) const {
447 os << "NonStaticGlobalSpaceRegion";
448}
449
Ted Kremenekbcfe03a2009-07-19 20:36:24 +0000450void ObjCIvarRegion::dumpToStream(llvm::raw_ostream& os) const {
Benjamin Kramer900fc632010-04-17 09:33:03 +0000451 os << "ivar{" << superRegion << ',' << getDecl() << '}';
Ted Kremenekbcfe03a2009-07-19 20:36:24 +0000452}
453
Mike Stump1eb44332009-09-09 15:08:12 +0000454void StringRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenekb27ed3d2009-07-19 20:38:24 +0000455 Str->printPretty(os, 0, PrintingPolicy(getContext().getLangOptions()));
Ted Kremenek5639a3e2009-04-21 18:09:22 +0000456}
457
Ted Kremenek8800ad42009-07-13 23:31:04 +0000458void SymbolicRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenekaef5d222009-07-13 23:38:57 +0000459 os << "SymRegion{" << sym << '}';
Ted Kremenek5639a3e2009-04-21 18:09:22 +0000460}
461
Ted Kremenek8800ad42009-07-13 23:31:04 +0000462void VarRegion::dumpToStream(llvm::raw_ostream& os) const {
Benjamin Kramer900fc632010-04-17 09:33:03 +0000463 os << cast<VarDecl>(D);
Ted Kremenek9e240492008-10-04 05:50:14 +0000464}
465
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000466void RegionRawOffset::dump() const {
467 dumpToStream(llvm::errs());
468}
469
470void RegionRawOffset::dumpToStream(llvm::raw_ostream& os) const {
471 os << "raw_offset{" << getRegion() << ',' << getByteOffset() << '}';
472}
473
Ted Kremenekfa87d812010-07-06 23:37:21 +0000474void StaticGlobalSpaceRegion::dumpToStream(llvm::raw_ostream &os) const {
475 os << "StaticGlobalsMemSpace{" << CR << '}';
476}
477
Ted Kremenek9e240492008-10-04 05:50:14 +0000478//===----------------------------------------------------------------------===//
479// MemRegionManager methods.
480//===----------------------------------------------------------------------===//
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000481
Ted Kremenek67d12872009-12-07 22:05:27 +0000482template <typename REG>
483const REG *MemRegionManager::LazyAllocate(REG*& region) {
Mike Stump1eb44332009-09-09 15:08:12 +0000484 if (!region) {
Ted Kremenek67d12872009-12-07 22:05:27 +0000485 region = (REG*) A.Allocate<REG>();
486 new (region) REG(this);
Ted Kremenek9e240492008-10-04 05:50:14 +0000487 }
Ted Kremeneka43484a2009-06-23 00:46:41 +0000488
Ted Kremenek9e240492008-10-04 05:50:14 +0000489 return region;
490}
491
Ted Kremenek67d12872009-12-07 22:05:27 +0000492template <typename REG, typename ARG>
493const REG *MemRegionManager::LazyAllocate(REG*& region, ARG a) {
494 if (!region) {
495 region = (REG*) A.Allocate<REG>();
496 new (region) REG(this, a);
497 }
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000498
Ted Kremenek67d12872009-12-07 22:05:27 +0000499 return region;
Ted Kremenek9e240492008-10-04 05:50:14 +0000500}
501
Ted Kremenek67d12872009-12-07 22:05:27 +0000502const StackLocalsSpaceRegion*
Ted Kremenek2b87ae42009-12-11 06:43:27 +0000503MemRegionManager::getStackLocalsRegion(const StackFrameContext *STC) {
504 assert(STC);
Zhongxing Xuc30470d2010-02-17 08:46:50 +0000505 StackLocalsSpaceRegion *&R = StackLocalsSpaceRegions[STC];
506
507 if (R)
508 return R;
509
510 R = A.Allocate<StackLocalsSpaceRegion>();
511 new (R) StackLocalsSpaceRegion(this, STC);
512 return R;
Ted Kremenekd05552a2009-07-02 18:14:59 +0000513}
514
Ted Kremenek67d12872009-12-07 22:05:27 +0000515const StackArgumentsSpaceRegion *
516MemRegionManager::getStackArgumentsRegion(const StackFrameContext *STC) {
Ted Kremenek2b87ae42009-12-11 06:43:27 +0000517 assert(STC);
Zhongxing Xuc30470d2010-02-17 08:46:50 +0000518 StackArgumentsSpaceRegion *&R = StackArgumentsSpaceRegions[STC];
519
520 if (R)
521 return R;
522
523 R = A.Allocate<StackArgumentsSpaceRegion>();
524 new (R) StackArgumentsSpaceRegion(this, STC);
525 return R;
Ted Kremenek67d12872009-12-07 22:05:27 +0000526}
527
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000528const GlobalsSpaceRegion
529*MemRegionManager::getGlobalsRegion(const CodeTextRegion *CR) {
530 if (!CR)
531 return LazyAllocate(globals);
532
533 StaticGlobalSpaceRegion *&R = StaticsGlobalSpaceRegions[CR];
534 if (R)
535 return R;
536
537 R = A.Allocate<StaticGlobalSpaceRegion>();
538 new (R) StaticGlobalSpaceRegion(this, CR);
539 return R;
Ted Kremenek9e240492008-10-04 05:50:14 +0000540}
541
Ted Kremenek67d12872009-12-07 22:05:27 +0000542const HeapSpaceRegion *MemRegionManager::getHeapRegion() {
Ted Kremenek9e240492008-10-04 05:50:14 +0000543 return LazyAllocate(heap);
544}
545
Ted Kremenekb48ad642009-12-04 00:26:31 +0000546const MemSpaceRegion *MemRegionManager::getUnknownRegion() {
Zhongxing Xu17892752008-10-08 02:50:44 +0000547 return LazyAllocate(unknown);
548}
549
Ted Kremenekb48ad642009-12-04 00:26:31 +0000550const MemSpaceRegion *MemRegionManager::getCodeRegion() {
Zhongxing Xuec13d922009-04-10 08:45:10 +0000551 return LazyAllocate(code);
552}
553
Ted Kremenek25010132009-06-22 23:13:13 +0000554//===----------------------------------------------------------------------===//
555// Constructing regions.
556//===----------------------------------------------------------------------===//
557
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000558const StringRegion* MemRegionManager::getStringRegion(const StringLiteral* Str){
Ted Kremenek67d12872009-12-07 22:05:27 +0000559 return getSubRegion<StringRegion>(Str, getGlobalsRegion());
Zhongxing Xue9f4e542008-10-25 14:13:41 +0000560}
561
Ted Kremenekb48ad642009-12-04 00:26:31 +0000562const VarRegion* MemRegionManager::getVarRegion(const VarDecl *D,
563 const LocationContext *LC) {
Ted Kremenek67d12872009-12-07 22:05:27 +0000564 const MemRegion *sReg = 0;
Mike Stump1eb44332009-09-09 15:08:12 +0000565
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000566 if (D->hasGlobalStorage() && !D->isStaticLocal())
567 sReg = getGlobalsRegion();
568 else {
Ted Kremenek67d12872009-12-07 22:05:27 +0000569 // FIXME: Once we implement scope handling, we will need to properly lookup
570 // 'D' to the proper LocationContext.
Ted Kremenek2b87ae42009-12-11 06:43:27 +0000571 const DeclContext *DC = D->getDeclContext();
572 const StackFrameContext *STC = LC->getStackFrameForDeclContext(DC);
Mike Stump1eb44332009-09-09 15:08:12 +0000573
Ted Kremenek2b87ae42009-12-11 06:43:27 +0000574 if (!STC)
575 sReg = getUnknownRegion();
576 else {
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000577 if (D->hasLocalStorage()) {
578 sReg = isa<ParmVarDecl>(D) || isa<ImplicitParamDecl>(D)
579 ? static_cast<const MemRegion*>(getStackArgumentsRegion(STC))
580 : static_cast<const MemRegion*>(getStackLocalsRegion(STC));
581 }
582 else {
583 assert(D->isStaticLocal());
584 const Decl *D = STC->getDecl();
585 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
586 sReg = getGlobalsRegion(getFunctionTextRegion(FD));
587 else if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) {
588 const BlockTextRegion *BTR =
589 getBlockTextRegion(BD,
590 C.getCanonicalType(BD->getSignatureAsWritten()->getType()),
591 STC->getAnalysisContext());
592 sReg = getGlobalsRegion(BTR);
593 }
594 else {
595 // FIXME: For ObjC-methods, we need a new CodeTextRegion. For now
596 // just use the main global memspace.
597 sReg = getGlobalsRegion();
598 }
599 }
Ted Kremenek2b87ae42009-12-11 06:43:27 +0000600 }
Ted Kremenek67d12872009-12-07 22:05:27 +0000601 }
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000602
Ted Kremenek67d12872009-12-07 22:05:27 +0000603 return getSubRegion<VarRegion>(D, sReg);
604}
605
606const VarRegion *MemRegionManager::getVarRegion(const VarDecl *D,
607 const MemRegion *superR) {
608 return getSubRegion<VarRegion>(D, superR);
Ted Kremenek9e240492008-10-04 05:50:14 +0000609}
610
Ted Kremenekb48ad642009-12-04 00:26:31 +0000611const BlockDataRegion *
612MemRegionManager::getBlockDataRegion(const BlockTextRegion *BC,
613 const LocationContext *LC) {
Ted Kremenek67d12872009-12-07 22:05:27 +0000614 const MemRegion *sReg = 0;
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000615
616 if (LC) {
Ted Kremenek67d12872009-12-07 22:05:27 +0000617 // FIXME: Once we implement scope handling, we want the parent region
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000618 // to be the scope.
Ted Kremenek67d12872009-12-07 22:05:27 +0000619 const StackFrameContext *STC = LC->getCurrentStackFrame();
620 assert(STC);
621 sReg = getStackLocalsRegion(STC);
622 }
623 else {
624 // We allow 'LC' to be NULL for cases where want BlockDataRegions
625 // without context-sensitivity.
626 sReg = getUnknownRegion();
627 }
628
629 return getSubRegion<BlockDataRegion>(BC, LC, sReg);
Ted Kremenek0a8112a2009-11-25 23:53:07 +0000630}
631
Ted Kremenekb48ad642009-12-04 00:26:31 +0000632const CompoundLiteralRegion*
Ted Kremenek67d12872009-12-07 22:05:27 +0000633MemRegionManager::getCompoundLiteralRegion(const CompoundLiteralExpr* CL,
634 const LocationContext *LC) {
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000635
Ted Kremenek67d12872009-12-07 22:05:27 +0000636 const MemRegion *sReg = 0;
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000637
Ted Kremenek67d12872009-12-07 22:05:27 +0000638 if (CL->isFileScope())
639 sReg = getGlobalsRegion();
640 else {
641 const StackFrameContext *STC = LC->getCurrentStackFrame();
642 assert(STC);
643 sReg = getStackLocalsRegion(STC);
644 }
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000645
Ted Kremenek67d12872009-12-07 22:05:27 +0000646 return getSubRegion<CompoundLiteralRegion>(CL, sReg);
Ted Kremenek329d6fd2008-10-27 20:57:58 +0000647}
648
Ted Kremenekb48ad642009-12-04 00:26:31 +0000649const ElementRegion*
Ted Kremenek02282ac2010-09-15 03:13:30 +0000650MemRegionManager::getElementRegion(QualType elementType, NonLoc Idx,
Ted Kremenek46537392009-07-16 01:33:37 +0000651 const MemRegion* superRegion,
652 ASTContext& Ctx){
Zhongxing Xu143b2fc2009-06-16 09:55:50 +0000653
Ted Kremenek32f90102010-05-27 00:29:00 +0000654 QualType T = Ctx.getCanonicalType(elementType).getUnqualifiedType();
Ted Kremenekabb042f2008-12-13 19:24:37 +0000655
Zhongxing Xu511191c2008-10-21 05:27:10 +0000656 llvm::FoldingSetNodeID ID;
Zhongxing Xu143b2fc2009-06-16 09:55:50 +0000657 ElementRegion::ProfileRegion(ID, T, Idx, superRegion);
Zhongxing Xu511191c2008-10-21 05:27:10 +0000658
659 void* InsertPos;
660 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
661 ElementRegion* R = cast_or_null<ElementRegion>(data);
662
663 if (!R) {
664 R = (ElementRegion*) A.Allocate<ElementRegion>();
Zhongxing Xu143b2fc2009-06-16 09:55:50 +0000665 new (R) ElementRegion(T, Idx, superRegion);
Zhongxing Xu511191c2008-10-21 05:27:10 +0000666 Regions.InsertNode(R, InsertPos);
667 }
668
669 return R;
670}
671
Ted Kremenekb48ad642009-12-04 00:26:31 +0000672const FunctionTextRegion *
Ted Kremenekeb1c7a02009-11-25 01:32:22 +0000673MemRegionManager::getFunctionTextRegion(const FunctionDecl *FD) {
Ted Kremenek67d12872009-12-07 22:05:27 +0000674 return getSubRegion<FunctionTextRegion>(FD, getCodeRegion());
Zhongxing Xuec13d922009-04-10 08:45:10 +0000675}
676
Ted Kremenekb48ad642009-12-04 00:26:31 +0000677const BlockTextRegion *
Ted Kremenek67d12872009-12-07 22:05:27 +0000678MemRegionManager::getBlockTextRegion(const BlockDecl *BD, CanQualType locTy,
679 AnalysisContext *AC) {
680 return getSubRegion<BlockTextRegion>(BD, locTy, AC, getCodeRegion());
Ted Kremenekeb1c7a02009-11-25 01:32:22 +0000681}
682
683
Ted Kremenek993f1c72008-10-17 20:28:54 +0000684/// getSymbolicRegion - Retrieve or create a "symbolic" memory region.
Ted Kremenekb48ad642009-12-04 00:26:31 +0000685const SymbolicRegion *MemRegionManager::getSymbolicRegion(SymbolRef sym) {
Ted Kremenek67d12872009-12-07 22:05:27 +0000686 return getSubRegion<SymbolicRegion>(sym, getUnknownRegion());
Ted Kremenek993f1c72008-10-17 20:28:54 +0000687}
688
Ted Kremenekde0d2632010-01-05 02:18:06 +0000689const FieldRegion*
Ted Kremenekb48ad642009-12-04 00:26:31 +0000690MemRegionManager::getFieldRegion(const FieldDecl* d,
691 const MemRegion* superRegion){
Ted Kremenekeeea4562009-07-10 16:51:45 +0000692 return getSubRegion<FieldRegion>(d, superRegion);
Ted Kremenek9e240492008-10-04 05:50:14 +0000693}
694
Ted Kremenekb48ad642009-12-04 00:26:31 +0000695const ObjCIvarRegion*
Ted Kremenek993f1c72008-10-17 20:28:54 +0000696MemRegionManager::getObjCIvarRegion(const ObjCIvarDecl* d,
697 const MemRegion* superRegion) {
Ted Kremenekeeea4562009-07-10 16:51:45 +0000698 return getSubRegion<ObjCIvarRegion>(d, superRegion);
Ted Kremenek9e240492008-10-04 05:50:14 +0000699}
700
Zhongxing Xu02fe28c2010-11-26 08:52:48 +0000701const CXXTempObjectRegion*
702MemRegionManager::getCXXTempObjectRegion(Expr const *E,
703 LocationContext const *LC) {
Zhongxing Xubc37b8d2010-01-09 09:16:47 +0000704 const StackFrameContext *SFC = LC->getCurrentStackFrame();
705 assert(SFC);
Zhongxing Xu02fe28c2010-11-26 08:52:48 +0000706 return getSubRegion<CXXTempObjectRegion>(E, getStackLocalsRegion(SFC));
Zhongxing Xubb141212009-12-16 11:27:52 +0000707}
708
Zhongxing Xu4fd56812010-11-26 08:21:53 +0000709const CXXBaseObjectRegion *
710MemRegionManager::getCXXBaseObjectRegion(const CXXRecordDecl *decl,
711 const MemRegion *superRegion) {
712 return getSubRegion<CXXBaseObjectRegion>(decl, superRegion);
713}
714
Ted Kremenekde0d2632010-01-05 02:18:06 +0000715const CXXThisRegion*
716MemRegionManager::getCXXThisRegion(QualType thisPointerTy,
717 const LocationContext *LC) {
718 const StackFrameContext *STC = LC->getCurrentStackFrame();
719 assert(STC);
720 const PointerType *PT = thisPointerTy->getAs<PointerType>();
721 assert(PT);
722 return getSubRegion<CXXThisRegion>(PT, getStackArgumentsRegion(STC));
723}
724
Ted Kremenekb48ad642009-12-04 00:26:31 +0000725const AllocaRegion*
Ted Kremenek67d12872009-12-07 22:05:27 +0000726MemRegionManager::getAllocaRegion(const Expr* E, unsigned cnt,
727 const LocationContext *LC) {
728 const StackFrameContext *STC = LC->getCurrentStackFrame();
729 assert(STC);
730 return getSubRegion<AllocaRegion>(E, cnt, getStackLocalsRegion(STC));
Ted Kremenek7090ae12008-11-02 00:34:33 +0000731}
732
Ted Kremenekbb7c96f2009-06-23 18:17:08 +0000733const MemSpaceRegion *MemRegion::getMemorySpace() const {
734 const MemRegion *R = this;
Ted Kremenekea20cd72009-06-23 18:05:21 +0000735 const SubRegion* SR = dyn_cast<SubRegion>(this);
Mike Stump1eb44332009-09-09 15:08:12 +0000736
Ted Kremenek993f1c72008-10-17 20:28:54 +0000737 while (SR) {
Ted Kremenekbb7c96f2009-06-23 18:17:08 +0000738 R = SR->getSuperRegion();
739 SR = dyn_cast<SubRegion>(R);
Ted Kremenek9e240492008-10-04 05:50:14 +0000740 }
Mike Stump1eb44332009-09-09 15:08:12 +0000741
Ted Kremenekbb7c96f2009-06-23 18:17:08 +0000742 return dyn_cast<MemSpaceRegion>(R);
743}
744
745bool MemRegion::hasStackStorage() const {
Ted Kremenek67d12872009-12-07 22:05:27 +0000746 return isa<StackSpaceRegion>(getMemorySpace());
Ted Kremenek9e240492008-10-04 05:50:14 +0000747}
Ted Kremenek1670e402009-04-11 00:11:10 +0000748
Ted Kremenekde0d2632010-01-05 02:18:06 +0000749bool MemRegion::hasStackNonParametersStorage() const {
750 return isa<StackLocalsSpaceRegion>(getMemorySpace());
Zhongxing Xudd198f02009-06-23 02:51:21 +0000751}
Ted Kremenek1670e402009-04-11 00:11:10 +0000752
Ted Kremenekde0d2632010-01-05 02:18:06 +0000753bool MemRegion::hasStackParametersStorage() const {
Ted Kremenek67d12872009-12-07 22:05:27 +0000754 return isa<StackArgumentsSpaceRegion>(getMemorySpace());
Ted Kremenekdc147262009-07-02 22:02:15 +0000755}
756
Ted Kremenek15086362009-07-02 18:25:09 +0000757bool MemRegion::hasGlobalsOrParametersStorage() const {
Ted Kremenek67d12872009-12-07 22:05:27 +0000758 const MemSpaceRegion *MS = getMemorySpace();
759 return isa<StackArgumentsSpaceRegion>(MS) ||
760 isa<GlobalsSpaceRegion>(MS);
Ted Kremenek15086362009-07-02 18:25:09 +0000761}
Ted Kremenekbb7c96f2009-06-23 18:17:08 +0000762
Zhongxing Xuadca2712009-11-10 02:37:53 +0000763// getBaseRegion strips away all elements and fields, and get the base region
764// of them.
765const MemRegion *MemRegion::getBaseRegion() const {
766 const MemRegion *R = this;
767 while (true) {
Ted Kremenek68b9a592010-04-06 22:06:03 +0000768 switch (R->getKind()) {
769 case MemRegion::ElementRegionKind:
770 case MemRegion::FieldRegionKind:
771 case MemRegion::ObjCIvarRegionKind:
772 R = cast<SubRegion>(R)->getSuperRegion();
773 continue;
774 default:
775 break;
Zhongxing Xuadca2712009-11-10 02:37:53 +0000776 }
777 break;
778 }
779 return R;
780}
781
Ted Kremenek1670e402009-04-11 00:11:10 +0000782//===----------------------------------------------------------------------===//
783// View handling.
784//===----------------------------------------------------------------------===//
785
Zhongxing Xu479529e2009-11-10 02:17:20 +0000786const MemRegion *MemRegion::StripCasts() const {
Ted Kremenek0e3ec3f2009-07-29 18:14:27 +0000787 const MemRegion *R = this;
788 while (true) {
Mike Stump1eb44332009-09-09 15:08:12 +0000789 if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) {
Ted Kremenek0e3ec3f2009-07-29 18:14:27 +0000790 // FIXME: generalize. Essentially we want to strip away ElementRegions
791 // that were layered on a symbolic region because of casts. We only
792 // want to strip away ElementRegions, however, where the index is 0.
793 SVal index = ER->getIndex();
794 if (nonloc::ConcreteInt *CI = dyn_cast<nonloc::ConcreteInt>(&index)) {
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000795 if (CI->getValue().getSExtValue() == 0) {
Ted Kremenek0e3ec3f2009-07-29 18:14:27 +0000796 R = ER->getSuperRegion();
797 continue;
798 }
799 }
800 }
801 break;
802 }
803 return R;
804}
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000805
806// FIXME: Merge with the implementation of the same method in Store.cpp
807static bool IsCompleteType(ASTContext &Ctx, QualType Ty) {
808 if (const RecordType *RT = Ty->getAs<RecordType>()) {
809 const RecordDecl *D = RT->getDecl();
Douglas Gregor952b0172010-02-11 01:04:33 +0000810 if (!D->getDefinition())
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000811 return false;
812 }
813
814 return true;
815}
816
Zhongxing Xu7caf9b32010-08-02 04:56:14 +0000817RegionRawOffset ElementRegion::getAsArrayOffset() const {
Ken Dyck199c3d62010-01-11 17:06:35 +0000818 CharUnits offset = CharUnits::Zero();
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000819 const ElementRegion *ER = this;
820 const MemRegion *superR = NULL;
821 ASTContext &C = getContext();
Mike Stump1eb44332009-09-09 15:08:12 +0000822
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000823 // FIXME: Handle multi-dimensional arrays.
824
825 while (ER) {
826 superR = ER->getSuperRegion();
Mike Stump1eb44332009-09-09 15:08:12 +0000827
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000828 // FIXME: generalize to symbolic offsets.
829 SVal index = ER->getIndex();
830 if (nonloc::ConcreteInt *CI = dyn_cast<nonloc::ConcreteInt>(&index)) {
831 // Update the offset.
832 int64_t i = CI->getValue().getSExtValue();
Mike Stump1eb44332009-09-09 15:08:12 +0000833
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000834 if (i != 0) {
835 QualType elemType = ER->getElementType();
Mike Stump1eb44332009-09-09 15:08:12 +0000836
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000837 // If we are pointing to an incomplete type, go no further.
838 if (!IsCompleteType(C, elemType)) {
839 superR = ER;
840 break;
841 }
Mike Stump1eb44332009-09-09 15:08:12 +0000842
Ken Dyck199c3d62010-01-11 17:06:35 +0000843 CharUnits size = C.getTypeSizeInChars(elemType);
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000844 offset += (i * size);
845 }
846
847 // Go to the next ElementRegion (if any).
848 ER = dyn_cast<ElementRegion>(superR);
849 continue;
850 }
Mike Stump1eb44332009-09-09 15:08:12 +0000851
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000852 return NULL;
853 }
Mike Stump1eb44332009-09-09 15:08:12 +0000854
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000855 assert(superR && "super region cannot be NULL");
Ken Dyck199c3d62010-01-11 17:06:35 +0000856 return RegionRawOffset(superR, offset.getQuantity());
Ted Kremenek19e1f0b2009-08-01 06:17:29 +0000857}
858
Zhongxing Xue8882332010-08-03 04:52:05 +0000859RegionOffset MemRegion::getAsOffset() const {
860 const MemRegion *R = this;
Zhongxing Xue3273e72010-08-03 06:34:25 +0000861 int64_t Offset = 0;
Zhongxing Xu7caf9b32010-08-02 04:56:14 +0000862
Zhongxing Xue8882332010-08-03 04:52:05 +0000863 while (1) {
864 switch (R->getKind()) {
865 default:
866 return RegionOffset(0);
867 case SymbolicRegionKind:
868 case AllocaRegionKind:
869 case CompoundLiteralRegionKind:
870 case CXXThisRegionKind:
871 case StringRegionKind:
872 case VarRegionKind:
Zhongxing Xu02fe28c2010-11-26 08:52:48 +0000873 case CXXTempObjectRegionKind:
Zhongxing Xue8882332010-08-03 04:52:05 +0000874 goto Finish;
875 case ElementRegionKind: {
876 const ElementRegion *ER = cast<ElementRegion>(R);
Zhongxing Xu018220c2010-08-11 06:10:55 +0000877 QualType EleTy = ER->getValueType();
Zhongxing Xu7caf9b32010-08-02 04:56:14 +0000878
Zhongxing Xue8882332010-08-03 04:52:05 +0000879 if (!IsCompleteType(getContext(), EleTy))
880 return RegionOffset(0);
881
882 SVal Index = ER->getIndex();
883 if (const nonloc::ConcreteInt *CI=dyn_cast<nonloc::ConcreteInt>(&Index)) {
884 int64_t i = CI->getValue().getSExtValue();
Zhongxing Xue8882332010-08-03 04:52:05 +0000885 CharUnits Size = getContext().getTypeSizeInChars(EleTy);
886 Offset += i * Size.getQuantity() * 8;
887 } else {
888 // We cannot compute offset for non-concrete index.
889 return RegionOffset(0);
890 }
891 R = ER->getSuperRegion();
Zhongxing Xu7caf9b32010-08-02 04:56:14 +0000892 break;
Zhongxing Xue8882332010-08-03 04:52:05 +0000893 }
894 case FieldRegionKind: {
895 const FieldRegion *FR = cast<FieldRegion>(R);
896 const RecordDecl *RD = FR->getDecl()->getParent();
897 if (!RD->isDefinition())
898 // We cannot compute offset for incomplete type.
899 return RegionOffset(0);
900 // Get the field number.
901 unsigned idx = 0;
902 for (RecordDecl::field_iterator FI = RD->field_begin(),
903 FE = RD->field_end(); FI != FE; ++FI, ++idx)
904 if (FR->getDecl() == *FI)
905 break;
Zhongxing Xu7caf9b32010-08-02 04:56:14 +0000906
Zhongxing Xue8882332010-08-03 04:52:05 +0000907 const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD);
908 // This is offset in bits.
909 Offset += Layout.getFieldOffset(idx);
910 R = FR->getSuperRegion();
911 break;
912 }
913 }
914 }
Zhongxing Xu7caf9b32010-08-02 04:56:14 +0000915
Zhongxing Xue8882332010-08-03 04:52:05 +0000916 Finish:
917 return RegionOffset(R, Offset);
Zhongxing Xu7caf9b32010-08-02 04:56:14 +0000918}
919
Ted Kremenek42400962009-11-26 02:34:36 +0000920//===----------------------------------------------------------------------===//
921// BlockDataRegion
922//===----------------------------------------------------------------------===//
923
924void BlockDataRegion::LazyInitializeReferencedVars() {
925 if (ReferencedVars)
926 return;
927
Ted Kremenek67d12872009-12-07 22:05:27 +0000928 AnalysisContext *AC = getCodeRegion()->getAnalysisContext();
Ted Kremenek42400962009-11-26 02:34:36 +0000929 AnalysisContext::referenced_decls_iterator I, E;
930 llvm::tie(I, E) = AC->getReferencedBlockVars(BC->getDecl());
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000931
Ted Kremenek42400962009-11-26 02:34:36 +0000932 if (I == E) {
933 ReferencedVars = (void*) 0x1;
934 return;
935 }
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000936
Ted Kremenek42400962009-11-26 02:34:36 +0000937 MemRegionManager &MemMgr = *getMemRegionManager();
938 llvm::BumpPtrAllocator &A = MemMgr.getAllocator();
939 BumpVectorContext BC(A);
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000940
Ted Kremenek42400962009-11-26 02:34:36 +0000941 typedef BumpVector<const MemRegion*> VarVec;
942 VarVec *BV = (VarVec*) A.Allocate<VarVec>();
Ted Kremenek02b1df62009-12-01 22:12:34 +0000943 new (BV) VarVec(BC, E - I);
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000944
Ted Kremenek67d12872009-12-07 22:05:27 +0000945 for ( ; I != E; ++I) {
946 const VarDecl *VD = *I;
947 const VarRegion *VR = 0;
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000948
Ted Kremenek85248732010-02-06 00:30:00 +0000949 if (!VD->getAttr<BlocksAttr>() && VD->hasLocalStorage())
Ted Kremenek67d12872009-12-07 22:05:27 +0000950 VR = MemMgr.getVarRegion(VD, this);
951 else {
952 if (LC)
953 VR = MemMgr.getVarRegion(VD, LC);
954 else {
955 VR = MemMgr.getVarRegion(VD, MemMgr.getUnknownRegion());
956 }
957 }
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000958
Ted Kremenek67d12872009-12-07 22:05:27 +0000959 assert(VR);
960 BV->push_back(VR, BC);
961 }
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000962
Ted Kremenek42400962009-11-26 02:34:36 +0000963 ReferencedVars = BV;
964}
965
966BlockDataRegion::referenced_vars_iterator
967BlockDataRegion::referenced_vars_begin() const {
968 const_cast<BlockDataRegion*>(this)->LazyInitializeReferencedVars();
969
970 BumpVector<const MemRegion*> *Vec =
971 static_cast<BumpVector<const MemRegion*>*>(ReferencedVars);
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000972
Ted Kremenek81cef582009-12-03 08:09:21 +0000973 return BlockDataRegion::referenced_vars_iterator(Vec == (void*) 0x1 ?
974 NULL : Vec->begin());
Ted Kremenek42400962009-11-26 02:34:36 +0000975}
976
977BlockDataRegion::referenced_vars_iterator
978BlockDataRegion::referenced_vars_end() const {
979 const_cast<BlockDataRegion*>(this)->LazyInitializeReferencedVars();
980
981 BumpVector<const MemRegion*> *Vec =
982 static_cast<BumpVector<const MemRegion*>*>(ReferencedVars);
Ted Kremenekdcee3ce2010-07-01 20:16:50 +0000983
Ted Kremenek81cef582009-12-03 08:09:21 +0000984 return BlockDataRegion::referenced_vars_iterator(Vec == (void*) 0x1 ?
985 NULL : Vec->end());
Ted Kremenek42400962009-11-26 02:34:36 +0000986}