blob: 775d099ab79c3c919a74ce02da3e8928acec9db8 [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 Kremenek9ef1ec92008-02-21 18:43:30 +000061RVal GRSimpleVals::EvalCast(ValueManager& ValMgr, NonLVal X, QualType T) {
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();
Ted Kremenekd59cccc2008-02-14 18:28:23 +000067 V.setIsUnsigned(T->isUnsignedIntegerType() || T->isPointerType());
Ted Kremenek9ef1ec92008-02-21 18:43:30 +000068 V.extOrTrunc(ValMgr.getContext().getTypeSize(T, SourceLocation()));
Ted Kremenekd59cccc2008-02-14 18:28:23 +000069
Ted Kremenek9ef1ec92008-02-21 18:43:30 +000070 if (T->isPointerType())
Ted Kremenekd59cccc2008-02-14 18:28:23 +000071 return lval::ConcreteInt(ValMgr.getValue(V));
72 else
73 return nonlval::ConcreteInt(ValMgr.getValue(V));
74}
75
76// Casts.
77
Ted Kremenek9ef1ec92008-02-21 18:43:30 +000078RVal GRSimpleVals::EvalCast(ValueManager& ValMgr, LVal X, QualType T) {
Ted Kremenek692416c2008-02-18 22:57:02 +000079
Ted Kremenek9ef1ec92008-02-21 18:43:30 +000080 if (T->isPointerType())
Ted Kremenekd59cccc2008-02-14 18:28:23 +000081 return X;
82
Ted Kremenek9ef1ec92008-02-21 18:43:30 +000083 assert (T->isIntegerType());
Ted Kremenekd59cccc2008-02-14 18:28:23 +000084
85 if (!isa<lval::ConcreteInt>(X))
86 return UnknownVal();
87
88 llvm::APSInt V = cast<lval::ConcreteInt>(X).getValue();
Ted Kremenekd59cccc2008-02-14 18:28:23 +000089 V.setIsUnsigned(T->isUnsignedIntegerType() || T->isPointerType());
Ted Kremenek9ef1ec92008-02-21 18:43:30 +000090 V.extOrTrunc(ValMgr.getContext().getTypeSize(T, SourceLocation()));
Ted Kremenekd59cccc2008-02-14 18:28:23 +000091
92 return nonlval::ConcreteInt(ValMgr.getValue(V));
Ted Kremenekc3f261d2008-02-14 18:40:24 +000093}
94
95// Unary operators.
96
Ted Kremenekaa1c4e52008-02-21 18:02:17 +000097RVal GRSimpleVals::EvalMinus(ValueManager& ValMgr, UnaryOperator* U, NonLVal X){
Ted Kremenek692416c2008-02-18 22:57:02 +000098
Ted Kremenekc3f261d2008-02-14 18:40:24 +000099 switch (X.getSubKind()) {
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000100
Ted Kremenekc3f261d2008-02-14 18:40:24 +0000101 case nonlval::ConcreteIntKind:
102 return cast<nonlval::ConcreteInt>(X).EvalMinus(ValMgr, U);
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000103
Ted Kremenekc3f261d2008-02-14 18:40:24 +0000104 default:
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000105 return UnknownVal();
Ted Kremenekc3f261d2008-02-14 18:40:24 +0000106 }
107}
108
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000109RVal GRSimpleVals::EvalComplement(ValueManager& ValMgr, NonLVal X) {
110
Ted Kremenek90e42032008-02-20 04:12:31 +0000111 switch (X.getSubKind()) {
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000112
Ted Kremenekc3f261d2008-02-14 18:40:24 +0000113 case nonlval::ConcreteIntKind:
114 return cast<nonlval::ConcreteInt>(X).EvalComplement(ValMgr);
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000115
Ted Kremenekc3f261d2008-02-14 18:40:24 +0000116 default:
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000117 return UnknownVal();
Ted Kremenekc3f261d2008-02-14 18:40:24 +0000118 }
119}
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000120
121// Binary operators.
122
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000123RVal GRSimpleVals::EvalBinOp(ValueManager& ValMgr, BinaryOperator::Opcode Op,
124 NonLVal L, NonLVal R) {
125 while (1) {
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000126
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000127 switch (L.getSubKind()) {
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000128 default:
Ted Kremenek9258a642008-02-21 19:10:12 +0000129 return UnknownVal();
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000130
131 case nonlval::ConcreteIntKind:
132
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000133 if (isa<nonlval::ConcreteInt>(R)) {
134 const nonlval::ConcreteInt& L_CI = cast<nonlval::ConcreteInt>(L);
135 const nonlval::ConcreteInt& R_CI = cast<nonlval::ConcreteInt>(R);
136 return L_CI.EvalBinOp(ValMgr, Op, R_CI);
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000137 }
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000138 else {
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000139 NonLVal tmp = R;
140 R = L;
141 L = tmp;
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000142 continue;
143 }
144
145 case nonlval::SymbolValKind: {
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000146
147 if (isa<nonlval::ConcreteInt>(R)) {
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000148 const SymIntConstraint& C =
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000149 ValMgr.getConstraint(cast<nonlval::SymbolVal>(L).getSymbol(), Op,
150 cast<nonlval::ConcreteInt>(R).getValue());
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000151
152 return nonlval::SymIntConstraintVal(C);
153 }
154 else
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000155 return UnknownVal();
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000156 }
157 }
158 }
159}
160
Ted Kremenekb640b3b2008-02-15 00:52:26 +0000161
Ted Kremenekc6fbdcd2008-02-15 23:15:23 +0000162// Binary Operators (except assignments and comma).
163
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000164RVal GRSimpleVals::EvalBinOp(ValueManager& ValMgr, BinaryOperator::Opcode Op,
165 LVal L, LVal R) {
Ted Kremenek692416c2008-02-18 22:57:02 +0000166
Ted Kremenekc6fbdcd2008-02-15 23:15:23 +0000167 switch (Op) {
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000168
Ted Kremenekc6fbdcd2008-02-15 23:15:23 +0000169 default:
170 return UnknownVal();
171
172 case BinaryOperator::EQ:
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000173 return EvalEQ(ValMgr, L, R);
Ted Kremenekc6fbdcd2008-02-15 23:15:23 +0000174
175 case BinaryOperator::NE:
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000176 return EvalNE(ValMgr, L, R);
Ted Kremenekc6fbdcd2008-02-15 23:15:23 +0000177 }
178}
179
Ted Kremenekb640b3b2008-02-15 00:52:26 +0000180// Pointer arithmetic.
181
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000182RVal GRSimpleVals::EvalBinOp(ValueManager& ValMgr, BinaryOperator::Opcode Op,
183 LVal L, NonLVal R) {
184 return UnknownVal();
Ted Kremenekb640b3b2008-02-15 00:52:26 +0000185}
186
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000187// Equality operators for LVals.
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000188
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000189RVal GRSimpleVals::EvalEQ(ValueManager& ValMgr, LVal L, LVal R) {
190
191 switch (L.getSubKind()) {
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000192
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000193 default:
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000194 assert(false && "EQ not implemented for this LVal.");
195 return UnknownVal();
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000196
197 case lval::ConcreteIntKind:
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000198
199 if (isa<lval::ConcreteInt>(R)) {
200 bool b = cast<lval::ConcreteInt>(L).getValue() ==
201 cast<lval::ConcreteInt>(R).getValue();
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000202
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000203 return NonLVal::MakeIntTruthVal(ValMgr, b);
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000204 }
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000205 else if (isa<lval::SymbolVal>(R)) {
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000206
207 const SymIntConstraint& C =
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000208 ValMgr.getConstraint(cast<lval::SymbolVal>(R).getSymbol(),
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000209 BinaryOperator::EQ,
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000210 cast<lval::ConcreteInt>(L).getValue());
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000211
212 return nonlval::SymIntConstraintVal(C);
213 }
214
215 break;
216
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000217 case lval::SymbolValKind: {
218
219 if (isa<lval::ConcreteInt>(R)) {
220 const SymIntConstraint& C =
221 ValMgr.getConstraint(cast<lval::SymbolVal>(L).getSymbol(),
222 BinaryOperator::EQ,
223 cast<lval::ConcreteInt>(R).getValue());
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000224
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000225 return nonlval::SymIntConstraintVal(C);
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000226 }
227
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000228 // FIXME: Implement unification
Ted Kremenek9258a642008-02-21 19:10:12 +0000229 return UnknownVal();
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000230 //assert (!isa<lval::SymbolVal>(R) && "FIXME: Implement unification.");
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000231
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000232 break;
233 }
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000234
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000235 case lval::DeclValKind:
Ted Kremenekdc3936b2008-02-22 00:54:56 +0000236 case lval::FuncValKind:
237 case lval::GotoLabelKind:
238 return NonLVal::MakeIntTruthVal(ValMgr, L == R);
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000239 }
240
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000241 return NonLVal::MakeIntTruthVal(ValMgr, false);
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000242}
243
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000244RVal GRSimpleVals::EvalNE(ValueManager& ValMgr, LVal L, LVal R) {
Ted Kremenek692416c2008-02-18 22:57:02 +0000245
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000246 switch (L.getSubKind()) {
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000247
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000248 default:
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000249 assert(false && "NE not implemented for this LVal.");
250 return UnknownVal();
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000251
252 case lval::ConcreteIntKind:
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000253
254 if (isa<lval::ConcreteInt>(R)) {
255 bool b = cast<lval::ConcreteInt>(L).getValue() !=
256 cast<lval::ConcreteInt>(R).getValue();
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000257
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000258 return NonLVal::MakeIntTruthVal(ValMgr, b);
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000259 }
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000260 else if (isa<lval::SymbolVal>(R)) {
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000261 const SymIntConstraint& C =
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000262 ValMgr.getConstraint(cast<lval::SymbolVal>(R).getSymbol(),
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000263 BinaryOperator::NE,
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000264 cast<lval::ConcreteInt>(L).getValue());
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000265
266 return nonlval::SymIntConstraintVal(C);
267 }
268
269 break;
270
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000271 case lval::SymbolValKind: {
272 if (isa<lval::ConcreteInt>(R)) {
273 const SymIntConstraint& C =
274 ValMgr.getConstraint(cast<lval::SymbolVal>(L).getSymbol(),
275 BinaryOperator::NE,
276 cast<lval::ConcreteInt>(R).getValue());
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000277
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000278 return nonlval::SymIntConstraintVal(C);
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000279 }
280
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000281 assert (!isa<lval::SymbolVal>(R) && "FIXME: Implement sym !=.");
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000282
283 break;
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000284 }
285
286 case lval::DeclValKind:
Ted Kremenekdc3936b2008-02-22 00:54:56 +0000287 case lval::FuncValKind:
288 case lval::GotoLabelKind:
289 return NonLVal::MakeIntTruthVal(ValMgr, L != R);
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000290 }
291
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000292 return NonLVal::MakeIntTruthVal(ValMgr, true);
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000293}