 |
|
 |
|
| Files: |
1 |
|
Branches Taken: |
48.0% |
36 / 75 |
| Generated: |
2010-02-10 01:31 |
|
Branches Executed: |
58.7% |
44 / 75 |
| |
|
Line Coverage: |
54.2% |
71 / 131 |
| |
 |
|
 |
1 : //== SymbolManager.h - Management of Symbolic Values ------------*- 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 SymbolManager, a class that manages symbolic values
11 : // created for use by GRExprEngine and related classes.
12 : //
13 : //===----------------------------------------------------------------------===//
14 :
15 : #include "clang/Checker/PathSensitive/SymbolManager.h"
16 : #include "clang/Checker/PathSensitive/MemRegion.h"
17 : #include "llvm/Support/raw_ostream.h"
18 :
19 : using namespace clang;
20 :
21 0: void SymExpr::dump() const {
22 0: dumpToStream(llvm::errs());
23 0: }
24 :
25 0: static void print(llvm::raw_ostream& os, BinaryOperator::Opcode Op) {
0: branch 0 not taken
0: branch 1 not taken
0: branch 2 not taken
0: branch 3 not taken
0: branch 4 not taken
0: branch 5 not taken
0: branch 6 not taken
0: branch 7 not taken
0: branch 8 not taken
0: branch 9 not taken
0: branch 10 not taken
0: branch 11 not taken
0: branch 12 not taken
0: branch 13 not taken
0: branch 14 not taken
0: branch 15 not taken
0: branch 16 not taken
26 0: switch (Op) {
27 : default:
28 0: assert(false && "operator printing not implemented");
29 : break;
30 0: case BinaryOperator::Mul: os << '*' ; break;
31 0: case BinaryOperator::Div: os << '/' ; break;
32 0: case BinaryOperator::Rem: os << '%' ; break;
33 0: case BinaryOperator::Add: os << '+' ; break;
34 0: case BinaryOperator::Sub: os << '-' ; break;
35 0: case BinaryOperator::Shl: os << "<<" ; break;
36 0: case BinaryOperator::Shr: os << ">>" ; break;
37 0: case BinaryOperator::LT: os << "<" ; break;
38 0: case BinaryOperator::GT: os << '>' ; break;
39 0: case BinaryOperator::LE: os << "<=" ; break;
40 0: case BinaryOperator::GE: os << ">=" ; break;
41 0: case BinaryOperator::EQ: os << "==" ; break;
42 0: case BinaryOperator::NE: os << "!=" ; break;
43 0: case BinaryOperator::And: os << '&' ; break;
44 0: case BinaryOperator::Xor: os << '^' ; break;
45 0: case BinaryOperator::Or: os << '|' ; break;
46 : }
47 0: }
48 :
49 0: void SymIntExpr::dumpToStream(llvm::raw_ostream& os) const {
50 0: os << '(';
51 0: getLHS()->dumpToStream(os);
52 0: os << ") ";
53 0: print(os, getOpcode());
54 0: os << ' ' << getRHS().getZExtValue();
0: branch 2 not taken
0: branch 3 not taken
55 0: if (getRHS().isUnsigned()) os << 'U';
56 0: }
57 :
58 0: void SymSymExpr::dumpToStream(llvm::raw_ostream& os) const {
59 0: os << '(';
60 0: getLHS()->dumpToStream(os);
61 0: os << ") ";
62 0: os << '(';
63 0: getRHS()->dumpToStream(os);
64 0: os << ')';
65 0: }
66 :
67 0: void SymbolConjured::dumpToStream(llvm::raw_ostream& os) const {
68 0: os << "conj_$" << getSymbolID() << '{' << T.getAsString() << '}';
69 0: }
70 :
71 0: void SymbolDerived::dumpToStream(llvm::raw_ostream& os) const {
72 : os << "derived_$" << getSymbolID() << '{'
73 0: << getParentSymbol() << ',' << getRegion() << '}';
74 0: }
75 :
76 0: void SymbolRegionValue::dumpToStream(llvm::raw_ostream& os) const {
77 0: os << "reg_$" << getSymbolID() << "<" << R << ">";
78 0: }
79 :
80 : const SymbolRegionValue*
81 2594: SymbolManager::getRegionValueSymbol(const MemRegion* R, QualType T) {
82 2594: llvm::FoldingSetNodeID profile;
83 2594: SymbolRegionValue::Profile(profile, R, T);
84 : void* InsertPos;
85 2594: SymExpr *SD = DataSet.FindNodeOrInsertPos(profile, InsertPos);
1714: branch 0 taken
880: branch 1 taken
86 2594: if (!SD) {
87 1714: SD = (SymExpr*) BPAlloc.Allocate<SymbolRegionValue>();
1714: branch 1 taken
0: branch 2 not taken
88 1714: new (SD) SymbolRegionValue(SymbolCounter, R, T);
1714: branch 0 taken
0: branch 1 not taken
89 1714: DataSet.InsertNode(SD, InsertPos);
90 1714: ++SymbolCounter;
91 : }
92 :
93 2594: return cast<SymbolRegionValue>(SD);
94 : }
95 :
96 : const SymbolConjured*
97 : SymbolManager::getConjuredSymbol(const Stmt* E, QualType T, unsigned Count,
98 2378: const void* SymbolTag) {
99 :
100 2378: llvm::FoldingSetNodeID profile;
101 2378: SymbolConjured::Profile(profile, E, T, Count, SymbolTag);
102 : void* InsertPos;
103 2378: SymExpr *SD = DataSet.FindNodeOrInsertPos(profile, InsertPos);
2272: branch 0 taken
106: branch 1 taken
104 2378: if (!SD) {
105 2272: SD = (SymExpr*) BPAlloc.Allocate<SymbolConjured>();
2272: branch 1 taken
0: branch 2 not taken
106 2272: new (SD) SymbolConjured(SymbolCounter, E, T, Count, SymbolTag);
2272: branch 0 taken
0: branch 1 not taken
107 2272: DataSet.InsertNode(SD, InsertPos);
108 2272: ++SymbolCounter;
109 : }
110 :
111 2378: return cast<SymbolConjured>(SD);
112 : }
113 :
114 : const SymbolDerived*
115 : SymbolManager::getDerivedSymbol(SymbolRef parentSymbol,
116 80: const TypedRegion *R) {
117 :
118 80: llvm::FoldingSetNodeID profile;
119 80: SymbolDerived::Profile(profile, parentSymbol, R);
120 : void* InsertPos;
121 80: SymExpr *SD = DataSet.FindNodeOrInsertPos(profile, InsertPos);
56: branch 0 taken
24: branch 1 taken
122 80: if (!SD) {
123 56: SD = (SymExpr*) BPAlloc.Allocate<SymbolDerived>();
56: branch 1 taken
0: branch 2 not taken
124 56: new (SD) SymbolDerived(SymbolCounter, parentSymbol, R);
56: branch 0 taken
0: branch 1 not taken
125 56: DataSet.InsertNode(SD, InsertPos);
126 56: ++SymbolCounter;
127 : }
128 :
129 80: return cast<SymbolDerived>(SD);
130 : }
131 :
132 : const SymIntExpr *SymbolManager::getSymIntExpr(const SymExpr *lhs,
133 : BinaryOperator::Opcode op,
134 : const llvm::APSInt& v,
135 1266: QualType t) {
136 1266: llvm::FoldingSetNodeID ID;
137 1266: SymIntExpr::Profile(ID, lhs, op, v, t);
138 : void *InsertPos;
139 1266: SymExpr *data = DataSet.FindNodeOrInsertPos(ID, InsertPos);
140 :
965: branch 0 taken
301: branch 1 taken
141 1266: if (!data) {
142 965: data = (SymIntExpr*) BPAlloc.Allocate<SymIntExpr>();
965: branch 1 taken
0: branch 2 not taken
143 965: new (data) SymIntExpr(lhs, op, v, t);
965: branch 0 taken
0: branch 1 not taken
144 965: DataSet.InsertNode(data, InsertPos);
145 : }
146 :
147 1266: return cast<SymIntExpr>(data);
148 : }
149 :
150 : const SymSymExpr *SymbolManager::getSymSymExpr(const SymExpr *lhs,
151 : BinaryOperator::Opcode op,
152 : const SymExpr *rhs,
153 0: QualType t) {
154 0: llvm::FoldingSetNodeID ID;
155 0: SymSymExpr::Profile(ID, lhs, op, rhs, t);
156 : void *InsertPos;
157 0: SymExpr *data = DataSet.FindNodeOrInsertPos(ID, InsertPos);
158 :
0: branch 0 not taken
0: branch 1 not taken
159 0: if (!data) {
160 0: data = (SymSymExpr*) BPAlloc.Allocate<SymSymExpr>();
0: branch 1 not taken
0: branch 2 not taken
161 0: new (data) SymSymExpr(lhs, op, rhs, t);
0: branch 0 not taken
0: branch 1 not taken
162 0: DataSet.InsertNode(data, InsertPos);
163 : }
164 :
165 0: return cast<SymSymExpr>(data);
166 : }
167 :
168 2334: QualType SymbolConjured::getType(ASTContext&) const {
169 2334: return T;
170 : }
171 :
172 :
173 183: QualType SymbolDerived::getType(ASTContext& Ctx) const {
174 183: return R->getValueType(Ctx);
175 : }
176 :
177 4612: QualType SymbolRegionValue::getType(ASTContext& C) const {
4612: branch 1 taken
0: branch 2 not taken
178 4612: if (!T.isNull())
179 4612: return T;
180 :
0: branch 1 not taken
0: branch 2 not taken
181 0: if (const TypedRegion* TR = dyn_cast<TypedRegion>(R))
182 0: return TR->getValueType(C);
183 :
184 0: return QualType();
185 : }
186 :
187 2138: SymbolManager::~SymbolManager() {}
188 :
189 7098: bool SymbolManager::canSymbolicate(QualType T) {
3462: branch 1 taken
3636: branch 2 taken
2975: branch 5 taken
487: branch 6 taken
2969: branch 9 taken
6: branch 10 taken
190 7098: return Loc::IsLocType(T) || (T->isIntegerType() && T->isScalarType());
191 : }
192 :
193 21522: void SymbolReaper::markLive(SymbolRef sym) {
194 21522: TheLiving.insert(sym);
195 21522: TheDead.erase(sym);
196 21522: }
197 :
198 11013: bool SymbolReaper::maybeDead(SymbolRef sym) {
9585: branch 1 taken
1428: branch 2 taken
199 11013: if (isLive(sym))
200 9585: return false;
201 :
202 1428: TheDead.insert(sym);
203 1428: return true;
204 : }
205 :
206 11880: bool SymbolReaper::isLive(SymbolRef sym) {
4452: branch 1 taken
7428: branch 2 taken
207 11880: if (TheLiving.count(sym))
208 4452: return true;
209 :
82: branch 1 taken
7346: branch 2 taken
210 7428: if (const SymbolDerived *derived = dyn_cast<SymbolDerived>(sym)) {
62: branch 2 taken
20: branch 3 taken
211 82: if (isLive(derived->getParentSymbol())) {
212 62: markLive(sym);
213 62: return true;
214 : }
215 20: return false;
216 : }
217 :
218 : // Interogate the symbol. It may derive from an input value to
219 : // the analyzed function/method.
220 7346: return isa<SymbolRegionValue>(sym);
221 : }
222 :
223 19549: bool SymbolReaper::isLive(const Stmt *Loc, const VarRegion *VR) const {
224 19549: const StackFrameContext *SFC = VR->getStackFrame();
18783: branch 0 taken
766: branch 1 taken
225 19549: return SFC == CurrentStackFrame ? Liveness.isLive(Loc, VR->getDecl()) : true;
226 : }
227 :
3124: branch 0 taken
3124: branch 1 taken
0: branch 3 not taken
0: branch 4 not taken
0: branch 6 not taken
3124: branch 7 taken
228 3124: SymbolVisitor::~SymbolVisitor() {}
Generated: 2010-02-10 01:31 by zcov