blob: 675882f42e09ad734d3d51dd9a272430c2993841 [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"
Ted Kremeneke01c9872008-02-14 22:36:46 +000017#include "clang/Basic/Diagnostic.h"
Ted Kremenekd59cccc2008-02-14 18:28:23 +000018
19using namespace clang;
20
Ted Kremeneke01c9872008-02-14 22:36:46 +000021namespace clang {
Ted Kremenekaa1c4e52008-02-21 18:02:17 +000022
23unsigned RunGRSimpleVals(CFG& cfg, FunctionDecl& FD, ASTContext& Ctx,
24 Diagnostic& Diag, bool Visualize) {
25
26 if (Diag.hasErrorOccurred())
27 return 0;
28
29 GRCoreEngine<GRExprEngine> Engine(cfg, FD, Ctx);
30 GRExprEngine* CheckerState = &Engine.getCheckerState();
31 GRSimpleVals GRSV;
32 CheckerState->setTransferFunctions(GRSV);
33
34 // Execute the worklist algorithm.
35 Engine.ExecuteWorkList(10000);
36
37 // Look for explicit-Null dereferences and warn about them.
38 for (GRExprEngine::null_iterator I=CheckerState->null_begin(),
39 E=CheckerState->null_end(); I!=E; ++I) {
Ted Kremeneke01c9872008-02-14 22:36:46 +000040
Ted Kremenekaa1c4e52008-02-21 18:02:17 +000041 const PostStmt& L = cast<PostStmt>((*I)->getLocation());
42 Expr* Exp = cast<Expr>(L.getStmt());
Ted Kremenek546bded2008-02-14 22:54:17 +000043
Ted Kremenekaa1c4e52008-02-21 18:02:17 +000044 Diag.Report(FullSourceLoc(Exp->getExprLoc(), Ctx.getSourceManager()),
45 diag::chkr_null_deref_after_check);
Ted Kremeneke01c9872008-02-14 22:36:46 +000046 }
Ted Kremenekaa1c4e52008-02-21 18:02:17 +000047
48#ifndef NDEBUG
49 if (Visualize) CheckerState->ViewGraph();
50#endif
51
52 return Engine.getGraph().size();
53}
54
Ted Kremeneke01c9872008-02-14 22:36:46 +000055} // end clang namespace
56
Ted Kremenekd59cccc2008-02-14 18:28:23 +000057//===----------------------------------------------------------------------===//
58// Transfer function for Casts.
59//===----------------------------------------------------------------------===//
60
Ted Kremenekaa1c4e52008-02-21 18:02:17 +000061RVal GRSimpleVals::EvalCast(ValueManager& ValMgr, NonLVal X, Expr* CastExpr) {
Ted Kremenek692416c2008-02-18 22:57:02 +000062
Ted Kremenekd59cccc2008-02-14 18:28:23 +000063 if (!isa<nonlval::ConcreteInt>(X))
64 return UnknownVal();
65
66 llvm::APSInt V = cast<nonlval::ConcreteInt>(X).getValue();
67 QualType T = CastExpr->getType();
68 V.setIsUnsigned(T->isUnsignedIntegerType() || T->isPointerType());
69 V.extOrTrunc(ValMgr.getContext().getTypeSize(T, CastExpr->getLocStart()));
70
71 if (CastExpr->getType()->isPointerType())
72 return lval::ConcreteInt(ValMgr.getValue(V));
73 else
74 return nonlval::ConcreteInt(ValMgr.getValue(V));
75}
76
77// Casts.
78
Ted Kremenekaa1c4e52008-02-21 18:02:17 +000079RVal GRSimpleVals::EvalCast(ValueManager& ValMgr, LVal X, Expr* CastExpr) {
Ted Kremenek692416c2008-02-18 22:57:02 +000080
Ted Kremenekd59cccc2008-02-14 18:28:23 +000081 if (CastExpr->getType()->isPointerType())
82 return X;
83
84 assert (CastExpr->getType()->isIntegerType());
85
86 if (!isa<lval::ConcreteInt>(X))
87 return UnknownVal();
88
89 llvm::APSInt V = cast<lval::ConcreteInt>(X).getValue();
90 QualType T = CastExpr->getType();
91 V.setIsUnsigned(T->isUnsignedIntegerType() || T->isPointerType());
92 V.extOrTrunc(ValMgr.getContext().getTypeSize(T, CastExpr->getLocStart()));
93
94 return nonlval::ConcreteInt(ValMgr.getValue(V));
Ted Kremenekc3f261d2008-02-14 18:40:24 +000095}
96
97// Unary operators.
98
Ted Kremenekaa1c4e52008-02-21 18:02:17 +000099RVal GRSimpleVals::EvalMinus(ValueManager& ValMgr, UnaryOperator* U, NonLVal X){
Ted Kremenek692416c2008-02-18 22:57:02 +0000100
Ted Kremenekc3f261d2008-02-14 18:40:24 +0000101 switch (X.getSubKind()) {
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000102
Ted Kremenekc3f261d2008-02-14 18:40:24 +0000103 case nonlval::ConcreteIntKind:
104 return cast<nonlval::ConcreteInt>(X).EvalMinus(ValMgr, U);
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000105
Ted Kremenekc3f261d2008-02-14 18:40:24 +0000106 default:
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000107 return UnknownVal();
Ted Kremenekc3f261d2008-02-14 18:40:24 +0000108 }
109}
110
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000111RVal GRSimpleVals::EvalComplement(ValueManager& ValMgr, NonLVal X) {
112
Ted Kremenek90e42032008-02-20 04:12:31 +0000113 switch (X.getSubKind()) {
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000114
Ted Kremenekc3f261d2008-02-14 18:40:24 +0000115 case nonlval::ConcreteIntKind:
116 return cast<nonlval::ConcreteInt>(X).EvalComplement(ValMgr);
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000117
Ted Kremenekc3f261d2008-02-14 18:40:24 +0000118 default:
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000119 return UnknownVal();
Ted Kremenekc3f261d2008-02-14 18:40:24 +0000120 }
121}
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000122
123// Binary operators.
124
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000125RVal GRSimpleVals::EvalBinOp(ValueManager& ValMgr, BinaryOperator::Opcode Op,
126 NonLVal L, NonLVal R) {
127 while (1) {
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000128
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000129 switch (L.getSubKind()) {
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000130 default:
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000131 return cast<NonLVal>(UnknownVal());
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000132
133 case nonlval::ConcreteIntKind:
134
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000135 if (isa<nonlval::ConcreteInt>(R)) {
136 const nonlval::ConcreteInt& L_CI = cast<nonlval::ConcreteInt>(L);
137 const nonlval::ConcreteInt& R_CI = cast<nonlval::ConcreteInt>(R);
138 return L_CI.EvalBinOp(ValMgr, Op, R_CI);
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000139 }
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000140 else {
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000141 NonLVal tmp = R;
142 R = L;
143 L = tmp;
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000144 continue;
145 }
146
147 case nonlval::SymbolValKind: {
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000148
149 if (isa<nonlval::ConcreteInt>(R)) {
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000150 const SymIntConstraint& C =
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000151 ValMgr.getConstraint(cast<nonlval::SymbolVal>(L).getSymbol(), Op,
152 cast<nonlval::ConcreteInt>(R).getValue());
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000153
154 return nonlval::SymIntConstraintVal(C);
155 }
156 else
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000157 return UnknownVal();
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000158 }
159 }
160 }
161}
162
Ted Kremenekb640b3b2008-02-15 00:52:26 +0000163
Ted Kremenekc6fbdcd2008-02-15 23:15:23 +0000164// Binary Operators (except assignments and comma).
165
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000166RVal GRSimpleVals::EvalBinOp(ValueManager& ValMgr, BinaryOperator::Opcode Op,
167 LVal L, LVal R) {
Ted Kremenek692416c2008-02-18 22:57:02 +0000168
Ted Kremenekc6fbdcd2008-02-15 23:15:23 +0000169 switch (Op) {
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000170
Ted Kremenekc6fbdcd2008-02-15 23:15:23 +0000171 default:
172 return UnknownVal();
173
174 case BinaryOperator::EQ:
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000175 return EvalEQ(ValMgr, L, R);
Ted Kremenekc6fbdcd2008-02-15 23:15:23 +0000176
177 case BinaryOperator::NE:
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000178 return EvalNE(ValMgr, L, R);
Ted Kremenekc6fbdcd2008-02-15 23:15:23 +0000179 }
180}
181
Ted Kremenekb640b3b2008-02-15 00:52:26 +0000182// Pointer arithmetic.
183
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000184RVal GRSimpleVals::EvalBinOp(ValueManager& ValMgr, BinaryOperator::Opcode Op,
185 LVal L, NonLVal R) {
186 return UnknownVal();
Ted Kremenekb640b3b2008-02-15 00:52:26 +0000187}
188
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000189// Equality operators for LVals.
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000190
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000191RVal GRSimpleVals::EvalEQ(ValueManager& ValMgr, LVal L, LVal R) {
192
193 switch (L.getSubKind()) {
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000194
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000195 default:
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000196 assert(false && "EQ not implemented for this LVal.");
197 return UnknownVal();
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000198
199 case lval::ConcreteIntKind:
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000200
201 if (isa<lval::ConcreteInt>(R)) {
202 bool b = cast<lval::ConcreteInt>(L).getValue() ==
203 cast<lval::ConcreteInt>(R).getValue();
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000204
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000205 return NonLVal::MakeIntTruthVal(ValMgr, b);
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000206 }
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000207 else if (isa<lval::SymbolVal>(R)) {
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000208
209 const SymIntConstraint& C =
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000210 ValMgr.getConstraint(cast<lval::SymbolVal>(R).getSymbol(),
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000211 BinaryOperator::EQ,
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000212 cast<lval::ConcreteInt>(L).getValue());
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000213
214 return nonlval::SymIntConstraintVal(C);
215 }
216
217 break;
218
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000219 case lval::SymbolValKind: {
220
221 if (isa<lval::ConcreteInt>(R)) {
222 const SymIntConstraint& C =
223 ValMgr.getConstraint(cast<lval::SymbolVal>(L).getSymbol(),
224 BinaryOperator::EQ,
225 cast<lval::ConcreteInt>(R).getValue());
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000226
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000227 return nonlval::SymIntConstraintVal(C);
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000228 }
229
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000230 // FIXME: Implement unification
231 return cast<NonLVal>(UnknownVal());
232 //assert (!isa<lval::SymbolVal>(R) && "FIXME: Implement unification.");
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000233
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000234 break;
235 }
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000236
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000237 case lval::DeclValKind:
238
239 if (isa<lval::DeclVal>(R)) {
240 bool b = cast<lval::DeclVal>(L) == cast<lval::DeclVal>(R);
241 return NonLVal::MakeIntTruthVal(ValMgr, b);
242 }
243
244 break;
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000245 }
246
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000247 return NonLVal::MakeIntTruthVal(ValMgr, false);
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000248}
249
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000250RVal GRSimpleVals::EvalNE(ValueManager& ValMgr, LVal L, LVal R) {
Ted Kremenek692416c2008-02-18 22:57:02 +0000251
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000252 switch (L.getSubKind()) {
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000253
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000254 default:
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000255 assert(false && "NE not implemented for this LVal.");
256 return UnknownVal();
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000257
258 case lval::ConcreteIntKind:
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000259
260 if (isa<lval::ConcreteInt>(R)) {
261 bool b = cast<lval::ConcreteInt>(L).getValue() !=
262 cast<lval::ConcreteInt>(R).getValue();
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000263
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000264 return NonLVal::MakeIntTruthVal(ValMgr, b);
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000265 }
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000266 else if (isa<lval::SymbolVal>(R)) {
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000267 const SymIntConstraint& C =
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000268 ValMgr.getConstraint(cast<lval::SymbolVal>(R).getSymbol(),
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000269 BinaryOperator::NE,
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000270 cast<lval::ConcreteInt>(L).getValue());
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000271
272 return nonlval::SymIntConstraintVal(C);
273 }
274
275 break;
276
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000277 case lval::SymbolValKind: {
278 if (isa<lval::ConcreteInt>(R)) {
279 const SymIntConstraint& C =
280 ValMgr.getConstraint(cast<lval::SymbolVal>(L).getSymbol(),
281 BinaryOperator::NE,
282 cast<lval::ConcreteInt>(R).getValue());
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000283
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000284 return nonlval::SymIntConstraintVal(C);
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000285 }
286
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000287 assert (!isa<lval::SymbolVal>(R) && "FIXME: Implement sym !=.");
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000288
289 break;
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000290 }
291
292 case lval::DeclValKind:
293 if (isa<lval::DeclVal>(R)) {
294 bool b = cast<lval::DeclVal>(L) == cast<lval::DeclVal>(R);
295 return NonLVal::MakeIntTruthVal(ValMgr, b);
296 }
297
298 break;
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000299 }
300
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000301 return NonLVal::MakeIntTruthVal(ValMgr, true);
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000302}