blob: 3c174df2820b19dae0035218fbfae338df230418 [file] [log] [blame]
Ted Kremenekb15eba42008-10-04 05:50:14 +00001//== MemRegion.cpp - Abstract memory regions for static analysis --*- C++ -*--//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines MemRegion and its subclasses. MemRegion defines a
11// partially-typed abstraction of memory useful for path-sensitive dataflow
12// analyses.
13//
14//===----------------------------------------------------------------------===//
15
16#include "llvm/Support/raw_ostream.h"
17#include "clang/Analysis/PathSensitive/MemRegion.h"
18
19using namespace clang;
20
Ted Kremenek1b85d8e2009-06-22 23:13:13 +000021//===----------------------------------------------------------------------===//
22// Basic methods.
23//===----------------------------------------------------------------------===//
Ted Kremenekb15eba42008-10-04 05:50:14 +000024
25MemRegion::~MemRegion() {}
26
Zhongxing Xub287b212009-01-08 13:17:14 +000027bool SubRegion::isSubRegionOf(const MemRegion* R) const {
28 const MemRegion* r = getSuperRegion();
29 while (r != 0) {
30 if (r == R)
31 return true;
32 if (const SubRegion* sr = dyn_cast<SubRegion>(r))
33 r = sr->getSuperRegion();
34 else
35 break;
36 }
37 return false;
38}
39
Ted Kremenekd8f4cef2009-06-23 00:46:41 +000040
41MemRegionManager* SubRegion::getMemRegionManager() const {
42 const SubRegion* r = this;
43 do {
44 const MemRegion *superRegion = r->getSuperRegion();
45 if (const SubRegion *sr = dyn_cast<SubRegion>(superRegion)) {
46 r = sr;
47 continue;
48 }
49 return superRegion->getMemRegionManager();
50 } while (1);
51}
52
Ted Kremenekb15eba42008-10-04 05:50:14 +000053void MemSpaceRegion::Profile(llvm::FoldingSetNodeID& ID) const {
54 ID.AddInteger((unsigned)getKind());
55}
56
Zhongxing Xu73507bd2008-10-25 14:13:41 +000057void StringRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
58 const StringLiteral* Str,
59 const MemRegion* superRegion) {
60 ID.AddInteger((unsigned) StringRegionKind);
61 ID.AddPointer(Str);
62 ID.AddPointer(superRegion);
63}
64
Ted Kremenekea9ca502008-11-02 00:34:33 +000065void AllocaRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
Ted Kremenek3680b452009-06-23 00:15:41 +000066 const Expr* Ex, unsigned cnt,
67 const MemRegion *) {
Ted Kremenekea9ca502008-11-02 00:34:33 +000068 ID.AddInteger((unsigned) AllocaRegionKind);
69 ID.AddPointer(Ex);
70 ID.AddInteger(cnt);
71}
72
73void AllocaRegion::Profile(llvm::FoldingSetNodeID& ID) const {
Ted Kremenek3680b452009-06-23 00:15:41 +000074 ProfileRegion(ID, Ex, Cnt, superRegion);
Ted Kremenekea9ca502008-11-02 00:34:33 +000075}
76
Ted Kremenek6bc91b92008-10-27 20:57:58 +000077void CompoundLiteralRegion::Profile(llvm::FoldingSetNodeID& ID) const {
78 CompoundLiteralRegion::ProfileRegion(ID, CL, superRegion);
79}
80
81void CompoundLiteralRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
82 const CompoundLiteralExpr* CL,
83 const MemRegion* superRegion) {
84 ID.AddInteger((unsigned) CompoundLiteralRegionKind);
85 ID.AddPointer(CL);
86 ID.AddPointer(superRegion);
87}
88
Ted Kremenekb15eba42008-10-04 05:50:14 +000089void DeclRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, const Decl* D,
90 const MemRegion* superRegion, Kind k) {
91 ID.AddInteger((unsigned) k);
92 ID.AddPointer(D);
93 ID.AddPointer(superRegion);
94}
95
96void DeclRegion::Profile(llvm::FoldingSetNodeID& ID) const {
97 DeclRegion::ProfileRegion(ID, D, superRegion, getKind());
98}
99
Ted Kremenek1b85d8e2009-06-22 23:13:13 +0000100void SymbolicRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, SymbolRef sym,
101 const MemRegion *sreg) {
Ted Kremenek38a4b4b2008-10-17 20:28:54 +0000102 ID.AddInteger((unsigned) MemRegion::SymbolicRegionKind);
Ted Kremeneke8993f12008-12-05 02:39:38 +0000103 ID.Add(sym);
Ted Kremenek1b85d8e2009-06-22 23:13:13 +0000104 ID.AddPointer(sreg);
Ted Kremenek38a4b4b2008-10-17 20:28:54 +0000105}
106
107void SymbolicRegion::Profile(llvm::FoldingSetNodeID& ID) const {
Ted Kremenek1b85d8e2009-06-22 23:13:13 +0000108 SymbolicRegion::ProfileRegion(ID, sym, getSuperRegion());
Ted Kremenek38a4b4b2008-10-17 20:28:54 +0000109}
110
Ted Kremenekaf81ece2009-05-04 06:18:28 +0000111void ElementRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
112 QualType ElementType, SVal Idx,
Zhongxing Xu54969732008-10-21 05:27:10 +0000113 const MemRegion* superRegion) {
114 ID.AddInteger(MemRegion::ElementRegionKind);
Ted Kremenekaf81ece2009-05-04 06:18:28 +0000115 ID.Add(ElementType);
Zhongxing Xu54969732008-10-21 05:27:10 +0000116 ID.AddPointer(superRegion);
117 Idx.Profile(ID);
118}
119
120void ElementRegion::Profile(llvm::FoldingSetNodeID& ID) const {
Ted Kremenekaf81ece2009-05-04 06:18:28 +0000121 ElementRegion::ProfileRegion(ID, ElementType, Index, superRegion);
Zhongxing Xu54969732008-10-21 05:27:10 +0000122}
Zhongxing Xu1a563da2008-10-27 13:17:02 +0000123
Zhongxing Xuef3fb4c2009-04-10 08:45:10 +0000124void CodeTextRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, const void* data,
Zhongxing Xu54cd8122009-06-23 03:50:30 +0000125 QualType t, const MemRegion*) {
Zhongxing Xuef3fb4c2009-04-10 08:45:10 +0000126 ID.AddInteger(MemRegion::CodeTextRegionKind);
127 ID.AddPointer(data);
128 ID.Add(t);
129}
130
131void CodeTextRegion::Profile(llvm::FoldingSetNodeID& ID) const {
Zhongxing Xu54cd8122009-06-23 03:50:30 +0000132 CodeTextRegion::ProfileRegion(ID, Data, LocationType, superRegion);
Zhongxing Xuef3fb4c2009-04-10 08:45:10 +0000133}
134
Zhongxing Xu93b80662009-02-05 06:57:29 +0000135//===----------------------------------------------------------------------===//
Ted Kremenekb15eba42008-10-04 05:50:14 +0000136// Region pretty-printing.
137//===----------------------------------------------------------------------===//
138
Ted Kremenekfaf94872009-07-13 23:31:04 +0000139void MemRegion::dump() const {
140 dumpToStream(llvm::errs());
Ted Kremenekb80d8572009-07-02 17:24:10 +0000141}
142
Ted Kremenekb15eba42008-10-04 05:50:14 +0000143std::string MemRegion::getString() const {
144 std::string s;
145 llvm::raw_string_ostream os(s);
Ted Kremenekfaf94872009-07-13 23:31:04 +0000146 dumpToStream(os);
Ted Kremenekb15eba42008-10-04 05:50:14 +0000147 return os.str();
148}
149
Ted Kremenekfaf94872009-07-13 23:31:04 +0000150void MemRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenekb15eba42008-10-04 05:50:14 +0000151 os << "<Unknown Region>";
152}
153
Ted Kremenekfaf94872009-07-13 23:31:04 +0000154void AllocaRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenekea9ca502008-11-02 00:34:33 +0000155 os << "alloca{" << (void*) Ex << ',' << Cnt << '}';
156}
157
Ted Kremenekfaf94872009-07-13 23:31:04 +0000158void CodeTextRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenek398efb52009-04-21 19:56:58 +0000159 os << "code{";
160 if (isDeclared())
Ted Kremenekb895ed22009-04-29 15:37:24 +0000161 os << getDecl()->getDeclName().getAsString();
Ted Kremenek398efb52009-04-21 19:56:58 +0000162 else
163 os << '$' << getSymbol();
164
165 os << '}';
166}
167
Ted Kremenekfaf94872009-07-13 23:31:04 +0000168void CompoundLiteralRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenek3a4beb52009-04-21 18:09:22 +0000169 // FIXME: More elaborate pretty-printing.
170 os << "{ " << (void*) CL << " }";
171}
172
Ted Kremenekfaf94872009-07-13 23:31:04 +0000173void ElementRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenek42d8d0e2009-07-13 23:53:06 +0000174 os << superRegion << '[' << Index << ']';
Ted Kremenek3a4beb52009-04-21 18:09:22 +0000175}
176
Ted Kremenekfaf94872009-07-13 23:31:04 +0000177void FieldRegion::dumpToStream(llvm::raw_ostream& os) const {
178 os << superRegion << "->" << getDecl()->getNameAsString();
Ted Kremenek3a4beb52009-04-21 18:09:22 +0000179}
180
Ted Kremenekd6fee632009-07-19 20:36:24 +0000181void ObjCIvarRegion::dumpToStream(llvm::raw_ostream& os) const {
182 os << "ivar{" << superRegion << ',' << getDecl()->getNameAsString() << '}';
183}
184
Ted Kremenekb99af2f2009-07-19 20:38:24 +0000185void StringRegion::dumpToStream(llvm::raw_ostream& os) const {
186 Str->printPretty(os, 0, PrintingPolicy(getContext().getLangOptions()));
Ted Kremenek3a4beb52009-04-21 18:09:22 +0000187}
188
Ted Kremenekfaf94872009-07-13 23:31:04 +0000189void SymbolicRegion::dumpToStream(llvm::raw_ostream& os) const {
Ted Kremenekfd3ad732009-07-13 23:38:57 +0000190 os << "SymRegion{" << sym << '}';
Ted Kremenek3a4beb52009-04-21 18:09:22 +0000191}
192
Ted Kremenekfaf94872009-07-13 23:31:04 +0000193void VarRegion::dumpToStream(llvm::raw_ostream& os) const {
Chris Lattner271d4c22008-11-24 05:29:24 +0000194 os << cast<VarDecl>(D)->getNameAsString();
Ted Kremenekb15eba42008-10-04 05:50:14 +0000195}
196
197//===----------------------------------------------------------------------===//
198// MemRegionManager methods.
199//===----------------------------------------------------------------------===//
200
Ted Kremenekd8f4cef2009-06-23 00:46:41 +0000201MemSpaceRegion* MemRegionManager::LazyAllocate(MemSpaceRegion*& region) {
Ted Kremenekb15eba42008-10-04 05:50:14 +0000202 if (!region) {
203 region = (MemSpaceRegion*) A.Allocate<MemSpaceRegion>();
Ted Kremenekd8f4cef2009-06-23 00:46:41 +0000204 new (region) MemSpaceRegion(this);
Ted Kremenekb15eba42008-10-04 05:50:14 +0000205 }
Ted Kremenekd8f4cef2009-06-23 00:46:41 +0000206
Ted Kremenekb15eba42008-10-04 05:50:14 +0000207 return region;
208}
209
210MemSpaceRegion* MemRegionManager::getStackRegion() {
211 return LazyAllocate(stack);
212}
213
Ted Kremenek4f8ae752009-07-02 18:14:59 +0000214MemSpaceRegion* MemRegionManager::getStackArgumentsRegion() {
215 return LazyAllocate(stackArguments);
216}
217
Ted Kremenekb15eba42008-10-04 05:50:14 +0000218MemSpaceRegion* MemRegionManager::getGlobalsRegion() {
219 return LazyAllocate(globals);
220}
221
222MemSpaceRegion* MemRegionManager::getHeapRegion() {
223 return LazyAllocate(heap);
224}
225
Zhongxing Xu79c57f82008-10-08 02:50:44 +0000226MemSpaceRegion* MemRegionManager::getUnknownRegion() {
227 return LazyAllocate(unknown);
228}
229
Zhongxing Xuef3fb4c2009-04-10 08:45:10 +0000230MemSpaceRegion* MemRegionManager::getCodeRegion() {
231 return LazyAllocate(code);
232}
233
Ted Kremenek1b85d8e2009-06-22 23:13:13 +0000234//===----------------------------------------------------------------------===//
235// Constructing regions.
236//===----------------------------------------------------------------------===//
237
Zhongxing Xu73507bd2008-10-25 14:13:41 +0000238StringRegion* MemRegionManager::getStringRegion(const StringLiteral* Str) {
Ted Kremenek1b85d8e2009-06-22 23:13:13 +0000239 return getRegion<StringRegion>(Str);
Zhongxing Xu73507bd2008-10-25 14:13:41 +0000240}
241
Ted Kremenek81329ab2008-10-27 21:01:26 +0000242VarRegion* MemRegionManager::getVarRegion(const VarDecl* d) {
Ted Kremenek1b85d8e2009-06-22 23:13:13 +0000243 return getRegion<VarRegion>(d);
Ted Kremenekb15eba42008-10-04 05:50:14 +0000244}
245
Ted Kremenek6bc91b92008-10-27 20:57:58 +0000246CompoundLiteralRegion*
247MemRegionManager::getCompoundLiteralRegion(const CompoundLiteralExpr* CL) {
Ted Kremenek1b85d8e2009-06-22 23:13:13 +0000248 return getRegion<CompoundLiteralRegion>(CL);
Ted Kremenek6bc91b92008-10-27 20:57:58 +0000249}
250
Ted Kremenek2c0de352008-12-13 19:24:37 +0000251ElementRegion*
Ted Kremenekaf81ece2009-05-04 06:18:28 +0000252MemRegionManager::getElementRegion(QualType elementType, SVal Idx,
Ted Kremenek369239c2009-07-16 01:33:37 +0000253 const MemRegion* superRegion,
254 ASTContext& Ctx){
Zhongxing Xufe483ee2009-06-16 09:55:50 +0000255
256 QualType T = Ctx.getCanonicalType(elementType);
Ted Kremenek2c0de352008-12-13 19:24:37 +0000257
Zhongxing Xu54969732008-10-21 05:27:10 +0000258 llvm::FoldingSetNodeID ID;
Zhongxing Xufe483ee2009-06-16 09:55:50 +0000259 ElementRegion::ProfileRegion(ID, T, Idx, superRegion);
Zhongxing Xu54969732008-10-21 05:27:10 +0000260
261 void* InsertPos;
262 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
263 ElementRegion* R = cast_or_null<ElementRegion>(data);
264
265 if (!R) {
266 R = (ElementRegion*) A.Allocate<ElementRegion>();
Zhongxing Xufe483ee2009-06-16 09:55:50 +0000267 new (R) ElementRegion(T, Idx, superRegion);
Zhongxing Xu54969732008-10-21 05:27:10 +0000268 Regions.InsertNode(R, InsertPos);
269 }
270
271 return R;
272}
273
Zhongxing Xuef3fb4c2009-04-10 08:45:10 +0000274CodeTextRegion* MemRegionManager::getCodeTextRegion(const FunctionDecl* fd,
275 QualType t) {
Zhongxing Xu54cd8122009-06-23 03:50:30 +0000276 return getRegion<CodeTextRegion>(fd, t);
Zhongxing Xuef3fb4c2009-04-10 08:45:10 +0000277}
278
279CodeTextRegion* MemRegionManager::getCodeTextRegion(SymbolRef sym, QualType t) {
Zhongxing Xu54cd8122009-06-23 03:50:30 +0000280 return getRegion<CodeTextRegion>(sym, t);
Zhongxing Xuef3fb4c2009-04-10 08:45:10 +0000281}
282
Ted Kremenek38a4b4b2008-10-17 20:28:54 +0000283/// getSymbolicRegion - Retrieve or create a "symbolic" memory region.
Ted Kremenek74556a12009-03-26 03:35:11 +0000284SymbolicRegion* MemRegionManager::getSymbolicRegion(SymbolRef sym) {
Ted Kremenek1b85d8e2009-06-22 23:13:13 +0000285 return getRegion<SymbolicRegion>(sym);
Ted Kremenek38a4b4b2008-10-17 20:28:54 +0000286}
287
Ted Kremenekb15eba42008-10-04 05:50:14 +0000288FieldRegion* MemRegionManager::getFieldRegion(const FieldDecl* d,
Ted Kremenek38a4b4b2008-10-17 20:28:54 +0000289 const MemRegion* superRegion) {
Ted Kremenek72d1f392009-07-10 16:51:45 +0000290 return getSubRegion<FieldRegion>(d, superRegion);
Ted Kremenekb15eba42008-10-04 05:50:14 +0000291}
292
Ted Kremenek38a4b4b2008-10-17 20:28:54 +0000293ObjCIvarRegion*
294MemRegionManager::getObjCIvarRegion(const ObjCIvarDecl* d,
295 const MemRegion* superRegion) {
Ted Kremenek72d1f392009-07-10 16:51:45 +0000296 return getSubRegion<ObjCIvarRegion>(d, superRegion);
Ted Kremenekb15eba42008-10-04 05:50:14 +0000297}
298
Ted Kremenek2539c112008-10-24 20:30:08 +0000299ObjCObjectRegion*
300MemRegionManager::getObjCObjectRegion(const ObjCInterfaceDecl* d,
Ted Kremenek12218222009-06-23 00:04:09 +0000301 const MemRegion* superRegion) {
Ted Kremenek72d1f392009-07-10 16:51:45 +0000302 return getSubRegion<ObjCObjectRegion>(d, superRegion);
Ted Kremenek2539c112008-10-24 20:30:08 +0000303}
304
Ted Kremenekea9ca502008-11-02 00:34:33 +0000305AllocaRegion* MemRegionManager::getAllocaRegion(const Expr* E, unsigned cnt) {
Ted Kremenek3680b452009-06-23 00:15:41 +0000306 return getRegion<AllocaRegion>(E, cnt);
Ted Kremenekea9ca502008-11-02 00:34:33 +0000307}
308
Ted Kremenek7e5d2922009-06-23 18:17:08 +0000309
310const MemSpaceRegion *MemRegion::getMemorySpace() const {
311 const MemRegion *R = this;
Ted Kremenekdd2ec492009-06-23 18:05:21 +0000312 const SubRegion* SR = dyn_cast<SubRegion>(this);
Ted Kremenekb15eba42008-10-04 05:50:14 +0000313
Ted Kremenek38a4b4b2008-10-17 20:28:54 +0000314 while (SR) {
Ted Kremenek7e5d2922009-06-23 18:17:08 +0000315 R = SR->getSuperRegion();
316 SR = dyn_cast<SubRegion>(R);
Ted Kremenekb15eba42008-10-04 05:50:14 +0000317 }
Ted Kremenek7e5d2922009-06-23 18:17:08 +0000318
319 return dyn_cast<MemSpaceRegion>(R);
320}
321
322bool MemRegion::hasStackStorage() const {
Ted Kremenek4f8ae752009-07-02 18:14:59 +0000323 if (const MemSpaceRegion *MS = getMemorySpace()) {
324 MemRegionManager *Mgr = getMemRegionManager();
325 return MS == Mgr->getStackRegion() || MS == Mgr->getStackArgumentsRegion();
326 }
Ted Kremenek7e5d2922009-06-23 18:17:08 +0000327
Ted Kremenekb15eba42008-10-04 05:50:14 +0000328 return false;
329}
Ted Kremenek8765ebc2009-04-11 00:11:10 +0000330
Ted Kremenekdd2ec492009-06-23 18:05:21 +0000331bool MemRegion::hasHeapStorage() const {
Ted Kremenek7e5d2922009-06-23 18:17:08 +0000332 if (const MemSpaceRegion *MS = getMemorySpace())
333 return MS == getMemRegionManager()->getHeapRegion();
Zhongxing Xu04b97b82009-06-23 02:51:21 +0000334
335 return false;
336}
Ted Kremenek8765ebc2009-04-11 00:11:10 +0000337
Ted Kremenek7e5d2922009-06-23 18:17:08 +0000338bool MemRegion::hasHeapOrStackStorage() const {
339 if (const MemSpaceRegion *MS = getMemorySpace()) {
340 MemRegionManager *Mgr = getMemRegionManager();
Ted Kremenek4f8ae752009-07-02 18:14:59 +0000341 return MS == Mgr->getHeapRegion()
342 || MS == Mgr->getStackRegion()
343 || MS == Mgr->getStackArgumentsRegion();
Ted Kremenek7e5d2922009-06-23 18:17:08 +0000344 }
345 return false;
Ted Kremenek8f1e3732009-07-02 18:25:09 +0000346}
347
348bool MemRegion::hasGlobalsStorage() const {
349 if (const MemSpaceRegion *MS = getMemorySpace())
350 return MS == getMemRegionManager()->getGlobalsRegion();
351
352 return false;
353}
354
Ted Kremenek17eb5622009-07-02 22:02:15 +0000355bool MemRegion::hasParametersStorage() const {
356 if (const MemSpaceRegion *MS = getMemorySpace())
357 return MS == getMemRegionManager()->getStackArgumentsRegion();
358
359 return false;
360}
361
Ted Kremenek8f1e3732009-07-02 18:25:09 +0000362bool MemRegion::hasGlobalsOrParametersStorage() const {
363 if (const MemSpaceRegion *MS = getMemorySpace()) {
364 MemRegionManager *Mgr = getMemRegionManager();
365 return MS == Mgr->getGlobalsRegion()
366 || MS == Mgr->getStackArgumentsRegion();
367 }
368 return false;
369}
Ted Kremenek7e5d2922009-06-23 18:17:08 +0000370
Ted Kremenek8765ebc2009-04-11 00:11:10 +0000371//===----------------------------------------------------------------------===//
372// View handling.
373//===----------------------------------------------------------------------===//
374
Ted Kremenekce563192009-07-29 18:14:27 +0000375const MemRegion *MemRegion::getBaseRegion() const {
376 const MemRegion *R = this;
377 while (true) {
378 if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) {
379 // FIXME: generalize. Essentially we want to strip away ElementRegions
380 // that were layered on a symbolic region because of casts. We only
381 // want to strip away ElementRegions, however, where the index is 0.
382 SVal index = ER->getIndex();
383 if (nonloc::ConcreteInt *CI = dyn_cast<nonloc::ConcreteInt>(&index)) {
384 if (CI->getValue().getZExtValue() == 0) {
385 R = ER->getSuperRegion();
386 continue;
387 }
388 }
389 }
390 break;
391 }
392 return R;
393}