blob: 747d2f681816ffa11ca8e4efb5476a0d7b36b544 [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
21
22MemRegion::~MemRegion() {}
23
24void MemSpaceRegion::Profile(llvm::FoldingSetNodeID& ID) const {
25 ID.AddInteger((unsigned)getKind());
26}
27
28void AnonTypedRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, QualType T,
29 const MemRegion* superRegion) {
30 ID.AddInteger((unsigned) AnonTypedRegionKind);
31 ID.Add(T);
32 ID.AddPointer(superRegion);
33}
34
Zhongxing Xu79c57f82008-10-08 02:50:44 +000035void AnonPointeeRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
36 const VarDecl* VD, QualType T,
37 const MemRegion* superRegion) {
38 ID.AddInteger((unsigned) AnonPointeeRegionKind);
39 ID.Add(T);
40 ID.AddPointer(VD);
41 ID.AddPointer(superRegion);
42}
43
Ted Kremenekb15eba42008-10-04 05:50:14 +000044void AnonTypedRegion::Profile(llvm::FoldingSetNodeID& ID) const {
45 AnonTypedRegion::ProfileRegion(ID, T, superRegion);
46}
47
48void DeclRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, const Decl* D,
49 const MemRegion* superRegion, Kind k) {
50 ID.AddInteger((unsigned) k);
51 ID.AddPointer(D);
52 ID.AddPointer(superRegion);
53}
54
55void DeclRegion::Profile(llvm::FoldingSetNodeID& ID) const {
56 DeclRegion::ProfileRegion(ID, D, superRegion, getKind());
57}
58
59//===----------------------------------------------------------------------===//
60// Region pretty-printing.
61//===----------------------------------------------------------------------===//
62
63std::string MemRegion::getString() const {
64 std::string s;
65 llvm::raw_string_ostream os(s);
66 print(os);
67 return os.str();
68}
69
70void MemRegion::print(llvm::raw_ostream& os) const {
71 os << "<Unknown Region>";
72}
73
74void VarRegion::print(llvm::raw_ostream& os) const {
75 os << cast<VarDecl>(D)->getName();
76}
77
78//===----------------------------------------------------------------------===//
79// MemRegionManager methods.
80//===----------------------------------------------------------------------===//
81
82MemSpaceRegion* MemRegionManager::LazyAllocate(MemSpaceRegion*& region) {
83
84 if (!region) {
85 region = (MemSpaceRegion*) A.Allocate<MemSpaceRegion>();
86 new (region) MemSpaceRegion();
87 }
88
89 return region;
90}
91
92MemSpaceRegion* MemRegionManager::getStackRegion() {
93 return LazyAllocate(stack);
94}
95
96MemSpaceRegion* MemRegionManager::getGlobalsRegion() {
97 return LazyAllocate(globals);
98}
99
100MemSpaceRegion* MemRegionManager::getHeapRegion() {
101 return LazyAllocate(heap);
102}
103
Zhongxing Xu79c57f82008-10-08 02:50:44 +0000104MemSpaceRegion* MemRegionManager::getUnknownRegion() {
105 return LazyAllocate(unknown);
106}
107
Ted Kremenekb15eba42008-10-04 05:50:14 +0000108VarRegion* MemRegionManager::getVarRegion(const VarDecl* d,
109 MemRegion* superRegion) {
110 llvm::FoldingSetNodeID ID;
111 DeclRegion::ProfileRegion(ID, d, superRegion, MemRegion::VarRegionKind);
112
113 void* InsertPos;
114 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
115 VarRegion* R = cast_or_null<VarRegion>(data);
116
117 if (!R) {
118 R = (VarRegion*) A.Allocate<VarRegion>();
119 new (R) VarRegion(d, superRegion);
120 Regions.InsertNode(R, InsertPos);
121 }
122
123 return R;
124}
125
126FieldRegion* MemRegionManager::getFieldRegion(const FieldDecl* d,
127 MemRegion* superRegion) {
128 llvm::FoldingSetNodeID ID;
129 DeclRegion::ProfileRegion(ID, d, superRegion, MemRegion::FieldRegionKind);
130
131 void* InsertPos;
132 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
133 FieldRegion* R = cast_or_null<FieldRegion>(data);
134
135 if (!R) {
136 R = (FieldRegion*) A.Allocate<FieldRegion>();
137 new (R) FieldRegion(d, superRegion);
138 Regions.InsertNode(R, InsertPos);
139 }
140
141 return R;
142}
143
144ObjCIvarRegion* MemRegionManager::getObjCIvarRegion(const ObjCIvarDecl* d,
145 MemRegion* superRegion) {
146 llvm::FoldingSetNodeID ID;
147 DeclRegion::ProfileRegion(ID, d, superRegion, MemRegion::ObjCIvarRegionKind);
148
149 void* InsertPos;
150 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
151 ObjCIvarRegion* R = cast_or_null<ObjCIvarRegion>(data);
152
153 if (!R) {
Zhongxing Xu7a861e82008-10-06 03:03:33 +0000154 R = (ObjCIvarRegion*) A.Allocate<ObjCIvarRegion>();
155 new (R) ObjCIvarRegion(d, superRegion);
Ted Kremenekb15eba42008-10-04 05:50:14 +0000156 Regions.InsertNode(R, InsertPos);
157 }
158
159 return R;
160}
161
Zhongxing Xu79c57f82008-10-08 02:50:44 +0000162AnonPointeeRegion* MemRegionManager::getAnonPointeeRegion(const VarDecl* d) {
163 llvm::FoldingSetNodeID ID;
164 QualType T = d->getType();
165 QualType PointeeType = cast<PointerType>(T.getTypePtr())->getPointeeType();
166 MemRegion* superRegion = getUnknownRegion();
167
168 AnonPointeeRegion::ProfileRegion(ID, d, PointeeType, superRegion);
169
170 void* InsertPos;
171 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
172 AnonPointeeRegion* R = cast_or_null<AnonPointeeRegion>(data);
173
174 if (!R) {
175 R = (AnonPointeeRegion*) A.Allocate<AnonPointeeRegion>();
176 new (R) AnonPointeeRegion(d, PointeeType, superRegion);
177 Regions.InsertNode(R, InsertPos);
178 }
179
180 return R;
181}
182
Ted Kremenekb15eba42008-10-04 05:50:14 +0000183bool MemRegionManager::hasStackStorage(const MemRegion* R) {
184 MemSpaceRegion* S = getStackRegion();
185
186 while (R) {
187 if (R == S) return true;
188 R = R->getSuperRegion();
189 }
190
191 return false;
192}