blob: 4d9dccf621e0b6f41c745028c9a656b10bce2e14 [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 Kremenek06747692008-02-26 23:04:29 +000017#include "ValueState.h"
Ted Kremeneke01c9872008-02-14 22:36:46 +000018#include "clang/Basic/Diagnostic.h"
Ted Kremenekd59cccc2008-02-14 18:28:23 +000019
20using namespace clang;
21
Ted Kremeneke01c9872008-02-14 22:36:46 +000022namespace clang {
Ted Kremenekd87a3212008-02-26 21:31:18 +000023
24template <typename ITERATOR>
25static void EmitWarning(Diagnostic& Diag, SourceManager& SrcMgr,
26 ITERATOR I, ITERATOR E, const char* msg) {
27
28 bool isFirst;
29 unsigned ErrorDiag;
30
31 for (; I != E; ++I) {
32
33 if (isFirst) {
34 isFirst = false;
35 ErrorDiag = Diag.getCustomDiagID(Diagnostic::Warning, msg);
36 }
37
38 const PostStmt& L = cast<PostStmt>((*I)->getLocation());
39 Expr* Exp = cast<Expr>(L.getStmt());
40
41 Diag.Report(FullSourceLoc(Exp->getExprLoc(), SrcMgr), ErrorDiag);
42 }
43}
Ted Kremenekaa1c4e52008-02-21 18:02:17 +000044
45unsigned RunGRSimpleVals(CFG& cfg, FunctionDecl& FD, ASTContext& Ctx,
46 Diagnostic& Diag, bool Visualize) {
47
48 if (Diag.hasErrorOccurred())
49 return 0;
50
51 GRCoreEngine<GRExprEngine> Engine(cfg, FD, Ctx);
52 GRExprEngine* CheckerState = &Engine.getCheckerState();
53 GRSimpleVals GRSV;
54 CheckerState->setTransferFunctions(GRSV);
55
56 // Execute the worklist algorithm.
Ted Kremenekd87a3212008-02-26 21:31:18 +000057 Engine.ExecuteWorkList(20000);
Ted Kremenekaa1c4e52008-02-21 18:02:17 +000058
Ted Kremenekd87a3212008-02-26 21:31:18 +000059 SourceManager& SrcMgr = Ctx.getSourceManager();
60
61 EmitWarning(Diag, SrcMgr,
62 CheckerState->null_derefs_begin(),
63 CheckerState->null_derefs_end(),
64 "NULL pointer is dereferenced after it is checked for NULL.");
65
66 EmitWarning(Diag, SrcMgr,
67 CheckerState->uninit_derefs_begin(),
68 CheckerState->uninit_derefs_end(),
69 "Dereference of uninitialized value.");
70
71 EmitWarning(Diag, SrcMgr,
72 CheckerState->uninit_derefs_begin(),
73 CheckerState->uninit_derefs_end(),
74 "Dereference of uninitialized value.");
75
76 EmitWarning(Diag, SrcMgr,
77 CheckerState->bad_divides_begin(),
78 CheckerState->bad_divides_end(),
79 "Division by zero/uninitialized value.");
Ted Kremenekaa1c4e52008-02-21 18:02:17 +000080
81#ifndef NDEBUG
82 if (Visualize) CheckerState->ViewGraph();
83#endif
84
85 return Engine.getGraph().size();
86}
87
Ted Kremeneke01c9872008-02-14 22:36:46 +000088} // end clang namespace
89
Ted Kremenekd59cccc2008-02-14 18:28:23 +000090//===----------------------------------------------------------------------===//
91// Transfer function for Casts.
92//===----------------------------------------------------------------------===//
93
Ted Kremenek9ef1ec92008-02-21 18:43:30 +000094RVal GRSimpleVals::EvalCast(ValueManager& ValMgr, NonLVal X, QualType T) {
Ted Kremenek692416c2008-02-18 22:57:02 +000095
Ted Kremenekd59cccc2008-02-14 18:28:23 +000096 if (!isa<nonlval::ConcreteInt>(X))
97 return UnknownVal();
98
99 llvm::APSInt V = cast<nonlval::ConcreteInt>(X).getValue();
Ted Kremenekd59cccc2008-02-14 18:28:23 +0000100 V.setIsUnsigned(T->isUnsignedIntegerType() || T->isPointerType());
Ted Kremenek9ef1ec92008-02-21 18:43:30 +0000101 V.extOrTrunc(ValMgr.getContext().getTypeSize(T, SourceLocation()));
Ted Kremenekd59cccc2008-02-14 18:28:23 +0000102
Ted Kremenek9ef1ec92008-02-21 18:43:30 +0000103 if (T->isPointerType())
Ted Kremenekd59cccc2008-02-14 18:28:23 +0000104 return lval::ConcreteInt(ValMgr.getValue(V));
105 else
106 return nonlval::ConcreteInt(ValMgr.getValue(V));
107}
108
109// Casts.
110
Ted Kremenek9ef1ec92008-02-21 18:43:30 +0000111RVal GRSimpleVals::EvalCast(ValueManager& ValMgr, LVal X, QualType T) {
Ted Kremenek692416c2008-02-18 22:57:02 +0000112
Ted Kremenek9ef1ec92008-02-21 18:43:30 +0000113 if (T->isPointerType())
Ted Kremenekd59cccc2008-02-14 18:28:23 +0000114 return X;
115
Ted Kremenek9ef1ec92008-02-21 18:43:30 +0000116 assert (T->isIntegerType());
Ted Kremenekd59cccc2008-02-14 18:28:23 +0000117
118 if (!isa<lval::ConcreteInt>(X))
119 return UnknownVal();
120
121 llvm::APSInt V = cast<lval::ConcreteInt>(X).getValue();
Ted Kremenekd59cccc2008-02-14 18:28:23 +0000122 V.setIsUnsigned(T->isUnsignedIntegerType() || T->isPointerType());
Ted Kremenek9ef1ec92008-02-21 18:43:30 +0000123 V.extOrTrunc(ValMgr.getContext().getTypeSize(T, SourceLocation()));
Ted Kremenekd59cccc2008-02-14 18:28:23 +0000124
125 return nonlval::ConcreteInt(ValMgr.getValue(V));
Ted Kremenekc3f261d2008-02-14 18:40:24 +0000126}
127
128// Unary operators.
129
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000130RVal GRSimpleVals::EvalMinus(ValueManager& ValMgr, UnaryOperator* U, NonLVal X){
Ted Kremenek692416c2008-02-18 22:57:02 +0000131
Ted Kremenekc3f261d2008-02-14 18:40:24 +0000132 switch (X.getSubKind()) {
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000133
Ted Kremenekc3f261d2008-02-14 18:40:24 +0000134 case nonlval::ConcreteIntKind:
135 return cast<nonlval::ConcreteInt>(X).EvalMinus(ValMgr, U);
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000136
Ted Kremenekc3f261d2008-02-14 18:40:24 +0000137 default:
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000138 return UnknownVal();
Ted Kremenekc3f261d2008-02-14 18:40:24 +0000139 }
140}
141
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000142RVal GRSimpleVals::EvalComplement(ValueManager& ValMgr, NonLVal X) {
143
Ted Kremenek90e42032008-02-20 04:12:31 +0000144 switch (X.getSubKind()) {
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000145
Ted Kremenekc3f261d2008-02-14 18:40:24 +0000146 case nonlval::ConcreteIntKind:
147 return cast<nonlval::ConcreteInt>(X).EvalComplement(ValMgr);
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000148
Ted Kremenekc3f261d2008-02-14 18:40:24 +0000149 default:
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000150 return UnknownVal();
Ted Kremenekc3f261d2008-02-14 18:40:24 +0000151 }
152}
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000153
154// Binary operators.
155
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000156RVal GRSimpleVals::EvalBinOp(ValueManager& ValMgr, BinaryOperator::Opcode Op,
157 NonLVal L, NonLVal R) {
158 while (1) {
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000159
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000160 switch (L.getSubKind()) {
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000161 default:
Ted Kremenek9258a642008-02-21 19:10:12 +0000162 return UnknownVal();
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000163
164 case nonlval::ConcreteIntKind:
165
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000166 if (isa<nonlval::ConcreteInt>(R)) {
167 const nonlval::ConcreteInt& L_CI = cast<nonlval::ConcreteInt>(L);
168 const nonlval::ConcreteInt& R_CI = cast<nonlval::ConcreteInt>(R);
169 return L_CI.EvalBinOp(ValMgr, Op, R_CI);
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000170 }
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000171 else {
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000172 NonLVal tmp = R;
173 R = L;
174 L = tmp;
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000175 continue;
176 }
177
178 case nonlval::SymbolValKind: {
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000179
180 if (isa<nonlval::ConcreteInt>(R)) {
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000181 const SymIntConstraint& C =
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000182 ValMgr.getConstraint(cast<nonlval::SymbolVal>(L).getSymbol(), Op,
183 cast<nonlval::ConcreteInt>(R).getValue());
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000184
185 return nonlval::SymIntConstraintVal(C);
186 }
187 else
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000188 return UnknownVal();
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000189 }
190 }
191 }
192}
193
Ted Kremenekb640b3b2008-02-15 00:52:26 +0000194
Ted Kremenekc6fbdcd2008-02-15 23:15:23 +0000195// Binary Operators (except assignments and comma).
196
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000197RVal GRSimpleVals::EvalBinOp(ValueManager& ValMgr, BinaryOperator::Opcode Op,
198 LVal L, LVal R) {
Ted Kremenek692416c2008-02-18 22:57:02 +0000199
Ted Kremenekc6fbdcd2008-02-15 23:15:23 +0000200 switch (Op) {
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000201
Ted Kremenekc6fbdcd2008-02-15 23:15:23 +0000202 default:
203 return UnknownVal();
204
205 case BinaryOperator::EQ:
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000206 return EvalEQ(ValMgr, L, R);
Ted Kremenekc6fbdcd2008-02-15 23:15:23 +0000207
208 case BinaryOperator::NE:
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000209 return EvalNE(ValMgr, L, R);
Ted Kremenekc6fbdcd2008-02-15 23:15:23 +0000210 }
211}
212
Ted Kremenekb640b3b2008-02-15 00:52:26 +0000213// Pointer arithmetic.
214
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000215RVal GRSimpleVals::EvalBinOp(ValueManager& ValMgr, BinaryOperator::Opcode Op,
216 LVal L, NonLVal R) {
217 return UnknownVal();
Ted Kremenekb640b3b2008-02-15 00:52:26 +0000218}
219
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000220// Equality operators for LVals.
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000221
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000222RVal GRSimpleVals::EvalEQ(ValueManager& ValMgr, LVal L, LVal R) {
223
224 switch (L.getSubKind()) {
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000225
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000226 default:
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000227 assert(false && "EQ not implemented for this LVal.");
228 return UnknownVal();
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000229
230 case lval::ConcreteIntKind:
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000231
232 if (isa<lval::ConcreteInt>(R)) {
233 bool b = cast<lval::ConcreteInt>(L).getValue() ==
234 cast<lval::ConcreteInt>(R).getValue();
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000235
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000236 return NonLVal::MakeIntTruthVal(ValMgr, b);
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000237 }
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000238 else if (isa<lval::SymbolVal>(R)) {
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000239
240 const SymIntConstraint& C =
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000241 ValMgr.getConstraint(cast<lval::SymbolVal>(R).getSymbol(),
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000242 BinaryOperator::EQ,
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000243 cast<lval::ConcreteInt>(L).getValue());
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000244
245 return nonlval::SymIntConstraintVal(C);
246 }
247
248 break;
249
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000250 case lval::SymbolValKind: {
251
252 if (isa<lval::ConcreteInt>(R)) {
253 const SymIntConstraint& C =
254 ValMgr.getConstraint(cast<lval::SymbolVal>(L).getSymbol(),
255 BinaryOperator::EQ,
256 cast<lval::ConcreteInt>(R).getValue());
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000257
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000258 return nonlval::SymIntConstraintVal(C);
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000259 }
260
Ted Kremenekf700df22008-02-22 18:41:59 +0000261 // FIXME: Implement == for lval Symbols. This is mainly useful
262 // in iterator loops when traversing a buffer, e.g. while(z != zTerm).
263 // Since this is not useful for many checkers we'll punt on this for
264 // now.
265
266 return UnknownVal();
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000267 }
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000268
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000269 case lval::DeclValKind:
Ted Kremenekdc3936b2008-02-22 00:54:56 +0000270 case lval::FuncValKind:
271 case lval::GotoLabelKind:
272 return NonLVal::MakeIntTruthVal(ValMgr, L == R);
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000273 }
274
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000275 return NonLVal::MakeIntTruthVal(ValMgr, false);
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000276}
277
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000278RVal GRSimpleVals::EvalNE(ValueManager& ValMgr, LVal L, LVal R) {
Ted Kremenek692416c2008-02-18 22:57:02 +0000279
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000280 switch (L.getSubKind()) {
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000281
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000282 default:
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000283 assert(false && "NE not implemented for this LVal.");
284 return UnknownVal();
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000285
286 case lval::ConcreteIntKind:
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000287
288 if (isa<lval::ConcreteInt>(R)) {
289 bool b = cast<lval::ConcreteInt>(L).getValue() !=
290 cast<lval::ConcreteInt>(R).getValue();
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000291
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000292 return NonLVal::MakeIntTruthVal(ValMgr, b);
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000293 }
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000294 else if (isa<lval::SymbolVal>(R)) {
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000295 const SymIntConstraint& C =
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000296 ValMgr.getConstraint(cast<lval::SymbolVal>(R).getSymbol(),
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000297 BinaryOperator::NE,
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000298 cast<lval::ConcreteInt>(L).getValue());
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000299
300 return nonlval::SymIntConstraintVal(C);
301 }
302
303 break;
304
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000305 case lval::SymbolValKind: {
306 if (isa<lval::ConcreteInt>(R)) {
307 const SymIntConstraint& C =
308 ValMgr.getConstraint(cast<lval::SymbolVal>(L).getSymbol(),
309 BinaryOperator::NE,
310 cast<lval::ConcreteInt>(R).getValue());
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000311
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000312 return nonlval::SymIntConstraintVal(C);
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000313 }
314
Ted Kremenekf700df22008-02-22 18:41:59 +0000315 // FIXME: Implement != for lval Symbols. This is mainly useful
316 // in iterator loops when traversing a buffer, e.g. while(z != zTerm).
317 // Since this is not useful for many checkers we'll punt on this for
318 // now.
319
320 return UnknownVal();
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000321
322 break;
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000323 }
324
325 case lval::DeclValKind:
Ted Kremenekdc3936b2008-02-22 00:54:56 +0000326 case lval::FuncValKind:
327 case lval::GotoLabelKind:
328 return NonLVal::MakeIntTruthVal(ValMgr, L != R);
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000329 }
330
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000331 return NonLVal::MakeIntTruthVal(ValMgr, true);
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000332}
Ted Kremenek06747692008-02-26 23:04:29 +0000333
334//===----------------------------------------------------------------------===//
335// Transfer function for Function Calls.
336//===----------------------------------------------------------------------===//
337
338ValueStateImpl*
339GRSimpleVals::EvalCall(ValueStateManager& StateMgr, ValueManager& ValMgr,
340 CallExpr* CE, LVal L, ValueStateImpl* StImpl) {
341
342 ValueState St(StImpl);
343
344 // Invalidate all arguments passed in by reference (LVals).
345
346 for (CallExpr::arg_iterator I = CE->arg_begin(), E = CE->arg_end();
347 I != E; ++I) {
348
349 RVal V = StateMgr.GetRVal(St, *I);
350
351 if (isa<LVal>(V))
352 St = StateMgr.SetRVal(St, cast<LVal>(V), UnknownVal());
353 }
354
355 return St.getImpl();
356}