blob: 200c9a39c6dd8fa62bb59bb2e6f5af11bc270e79 [file] [log] [blame]
Ted Kremenekd59cccc2008-02-14 18:28:23 +00001// GRSimpleVals.cpp - Transfer functions for tracking simple 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 files defines GRSimpleVals, a sub-class of GRTransferFuncs that
11// provides transfer functions for performing simple value tracking with
12// limited support for symbolics.
13//
14//===----------------------------------------------------------------------===//
15
16#include "GRSimpleVals.h"
17
18using namespace clang;
19
20//===----------------------------------------------------------------------===//
21// Transfer function for Casts.
22//===----------------------------------------------------------------------===//
23
24RValue GRSimpleVals::EvalCast(ValueManager& ValMgr, NonLValue X,
25 Expr* CastExpr) {
26
27 if (!isa<nonlval::ConcreteInt>(X))
28 return UnknownVal();
29
30 llvm::APSInt V = cast<nonlval::ConcreteInt>(X).getValue();
31 QualType T = CastExpr->getType();
32 V.setIsUnsigned(T->isUnsignedIntegerType() || T->isPointerType());
33 V.extOrTrunc(ValMgr.getContext().getTypeSize(T, CastExpr->getLocStart()));
34
35 if (CastExpr->getType()->isPointerType())
36 return lval::ConcreteInt(ValMgr.getValue(V));
37 else
38 return nonlval::ConcreteInt(ValMgr.getValue(V));
39}
40
41// Casts.
42
43RValue GRSimpleVals::EvalCast(ValueManager& ValMgr, LValue X, Expr* CastExpr) {
44
45 if (CastExpr->getType()->isPointerType())
46 return X;
47
48 assert (CastExpr->getType()->isIntegerType());
49
50 if (!isa<lval::ConcreteInt>(X))
51 return UnknownVal();
52
53 llvm::APSInt V = cast<lval::ConcreteInt>(X).getValue();
54 QualType T = CastExpr->getType();
55 V.setIsUnsigned(T->isUnsignedIntegerType() || T->isPointerType());
56 V.extOrTrunc(ValMgr.getContext().getTypeSize(T, CastExpr->getLocStart()));
57
58 return nonlval::ConcreteInt(ValMgr.getValue(V));
Ted Kremenekc3f261d2008-02-14 18:40:24 +000059}
60
61// Unary operators.
62
63NonLValue GRSimpleVals::EvalMinus(ValueManager& ValMgr, UnaryOperator* U,
64 NonLValue X) {
65
66 switch (X.getSubKind()) {
67 case nonlval::ConcreteIntKind:
68 return cast<nonlval::ConcreteInt>(X).EvalMinus(ValMgr, U);
69 default:
70 return cast<NonLValue>(UnknownVal());
71 }
72}
73
74NonLValue GRSimpleVals::EvalComplement(ValueManager& ValMgr, NonLValue X) {
75 switch (X.getSubKind()) {
76 case nonlval::ConcreteIntKind:
77 return cast<nonlval::ConcreteInt>(X).EvalComplement(ValMgr);
78 default:
79 return cast<NonLValue>(UnknownVal());
80 }
81}
Ted Kremenek6cb0b542008-02-14 19:37:24 +000082
83// Binary operators.
84
85NonLValue GRSimpleVals::EvalBinaryOp(ValueManager& ValMgr,
86 BinaryOperator::Opcode Op,
87 NonLValue LHS, NonLValue RHS) {
88
89 if (isa<UnknownVal>(LHS) || isa<UnknownVal>(RHS))
90 return cast<NonLValue>(UnknownVal());
91
92 if (isa<UninitializedVal>(LHS) || isa<UninitializedVal>(RHS))
93 return cast<NonLValue>(UninitializedVal());
94
95 while(1) {
96
97 switch (LHS.getSubKind()) {
98 default:
99 return cast<NonLValue>(UnknownVal());
100
101 case nonlval::ConcreteIntKind:
102
103 if (isa<nonlval::ConcreteInt>(RHS)) {
104 const nonlval::ConcreteInt& LHS_CI = cast<nonlval::ConcreteInt>(LHS);
105 const nonlval::ConcreteInt& RHS_CI = cast<nonlval::ConcreteInt>(RHS);
106 return LHS_CI.EvalBinaryOp(ValMgr, Op, RHS_CI);
107 }
108 else if(isa<UnknownVal>(RHS))
109 return cast<NonLValue>(UnknownVal());
110 else {
111 NonLValue tmp = RHS;
112 RHS = LHS;
113 LHS = tmp;
114 continue;
115 }
116
117 case nonlval::SymbolValKind: {
118 if (isa<nonlval::ConcreteInt>(RHS)) {
119 const SymIntConstraint& C =
120 ValMgr.getConstraint(cast<nonlval::SymbolVal>(LHS).getSymbol(), Op,
121 cast<nonlval::ConcreteInt>(RHS).getValue());
122
123 return nonlval::SymIntConstraintVal(C);
124 }
125 else
126 return cast<NonLValue>(UnknownVal());
127 }
128 }
129 }
130}
131
132// Equality operators for LValues.
133
134
135NonLValue GRSimpleVals::EvalEQ(ValueManager& ValMgr, LValue LHS, LValue RHS) {
136
137 switch (LHS.getSubKind()) {
138 default:
139 assert(false && "EQ not implemented for this LValue.");
140 return cast<NonLValue>(UnknownVal());
141
142 case lval::ConcreteIntKind:
143 if (isa<lval::ConcreteInt>(RHS)) {
144 bool b = cast<lval::ConcreteInt>(LHS).getValue() ==
145 cast<lval::ConcreteInt>(RHS).getValue();
146
147 return NonLValue::GetIntTruthValue(ValMgr, b);
148 }
149 else if (isa<lval::SymbolVal>(RHS)) {
150
151 const SymIntConstraint& C =
152 ValMgr.getConstraint(cast<lval::SymbolVal>(RHS).getSymbol(),
153 BinaryOperator::EQ,
154 cast<lval::ConcreteInt>(LHS).getValue());
155
156 return nonlval::SymIntConstraintVal(C);
157 }
158
159 break;
160
161 case lval::SymbolValKind: {
162 if (isa<lval::ConcreteInt>(RHS)) {
163 const SymIntConstraint& C =
164 ValMgr.getConstraint(cast<lval::SymbolVal>(LHS).getSymbol(),
165 BinaryOperator::EQ,
166 cast<lval::ConcreteInt>(RHS).getValue());
167
168 return nonlval::SymIntConstraintVal(C);
169 }
170
171 assert (!isa<lval::SymbolVal>(RHS) && "FIXME: Implement unification.");
172
173 break;
174 }
175
176 case lval::DeclValKind:
177
178 if (isa<lval::DeclVal>(RHS)) {
179 bool b = cast<lval::DeclVal>(LHS) == cast<lval::DeclVal>(RHS);
180 return NonLValue::GetIntTruthValue(ValMgr, b);
181 }
182
183 break;
184 }
185
186 return NonLValue::GetIntTruthValue(ValMgr, false);
187}
188
189NonLValue GRSimpleVals::EvalNE(ValueManager& ValMgr, LValue LHS, LValue RHS) {
190
191 switch (LHS.getSubKind()) {
192 default:
193 assert(false && "NE not implemented for this LValue.");
194 return cast<NonLValue>(UnknownVal());
195
196 case lval::ConcreteIntKind:
197 if (isa<lval::ConcreteInt>(RHS)) {
198 bool b = cast<lval::ConcreteInt>(LHS).getValue() !=
199 cast<lval::ConcreteInt>(RHS).getValue();
200
201 return NonLValue::GetIntTruthValue(ValMgr, b);
202 }
203 else if (isa<lval::SymbolVal>(RHS)) {
204 const SymIntConstraint& C =
205 ValMgr.getConstraint(cast<lval::SymbolVal>(RHS).getSymbol(),
206 BinaryOperator::NE,
207 cast<lval::ConcreteInt>(LHS).getValue());
208
209 return nonlval::SymIntConstraintVal(C);
210 }
211
212 break;
213
214 case lval::SymbolValKind: {
215 if (isa<lval::ConcreteInt>(RHS)) {
216 const SymIntConstraint& C =
217 ValMgr.getConstraint(cast<lval::SymbolVal>(LHS).getSymbol(),
218 BinaryOperator::NE,
219 cast<lval::ConcreteInt>(RHS).getValue());
220
221 return nonlval::SymIntConstraintVal(C);
222 }
223
224 assert (!isa<lval::SymbolVal>(RHS) && "FIXME: Implement sym !=.");
225
226 break;
227 }
228
229 case lval::DeclValKind:
230 if (isa<lval::DeclVal>(RHS)) {
231 bool b = cast<lval::DeclVal>(LHS) == cast<lval::DeclVal>(RHS);
232 return NonLValue::GetIntTruthValue(ValMgr, b);
233 }
234
235 break;
236 }
237
238 return NonLValue::GetIntTruthValue(ValMgr, true);
239}