blob: 5944c12e5896c5f9a9b7cec11c5ac484856eb745 [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//
Gabor Greif843e9342008-03-06 10:40:09 +000010// This file defines GRSimpleVals, a sub-class of GRTransferFuncs that
Ted Kremenekd59cccc2008-02-14 18:28:23 +000011// provides transfer functions for performing simple value tracking with
12// limited support for symbolics.
13//
14//===----------------------------------------------------------------------===//
15
16#include "GRSimpleVals.h"
Ted Kremenek52755612008-03-27 17:17:22 +000017#include "BasicObjCFoundationChecks.h"
Ted Kremenek0f5f0592008-02-27 06:07:00 +000018#include "clang/Analysis/PathSensitive/ValueState.h"
Ted Kremenek4dc41cc2008-03-31 18:26:32 +000019#include "clang/Analysis/PathDiagnostic.h"
Ted Kremenek5c061212008-02-27 17:56:16 +000020#include <sstream>
Ted Kremenekd59cccc2008-02-14 18:28:23 +000021
22using namespace clang;
23
Ted Kremeneke01c9872008-02-14 22:36:46 +000024namespace clang {
Ted Kremenekd87a3212008-02-26 21:31:18 +000025
26template <typename ITERATOR>
Ted Kremenek1b9df4c2008-03-14 18:14:50 +000027static inline ProgramPoint GetLocation(ITERATOR I) {
28 return (*I)->getLocation();
Ted Kremenek1e80aa42008-03-04 00:42:54 +000029}
30
31template <>
Ted Kremenek1b9df4c2008-03-14 18:14:50 +000032inline ProgramPoint GetLocation(GRExprEngine::undef_arg_iterator I) {
33 return I->first->getLocation();
34}
35
36static inline Stmt* GetStmt(const ProgramPoint& P) {
37 if (const PostStmt* PS = dyn_cast<PostStmt>(&P)) {
38 return PS->getStmt();
39 }
40 else if (const BlockEdge* BE = dyn_cast<BlockEdge>(&P)) {
41 return BE->getSrc()->getTerminator();
42 }
43
44 assert (false && "Unsupported ProgramPoint.");
45 return NULL;
Ted Kremenek1e80aa42008-03-04 00:42:54 +000046}
47
48template <typename ITERATOR>
Ted Kremenek4dc41cc2008-03-31 18:26:32 +000049static void EmitDiag(Diagnostic& Diag, PathDiagnosticClient* PD,
50 SourceManager& SrcMgr,
51unsigned ErrorDiag, ITERATOR I) {
Ted Kremenek1e80aa42008-03-04 00:42:54 +000052
Ted Kremenek1b9df4c2008-03-14 18:14:50 +000053 Stmt* S = GetStmt(GetLocation(I));
Ted Kremenek5297e5f2008-03-31 18:44:32 +000054 SourceRange R = S->getSourceRange();
55 Diag.Report(PD, FullSourceLoc(S->getLocStart(), SrcMgr), ErrorDiag,
56 NULL, 0, &R, 1);
Ted Kremenek1e80aa42008-03-04 00:42:54 +000057}
58
59
60template <>
Ted Kremenek4dc41cc2008-03-31 18:26:32 +000061static void EmitDiag(Diagnostic& Diag, PathDiagnosticClient* PD,
62 SourceManager& SrcMgr, unsigned ErrorDiag,
63 GRExprEngine::undef_arg_iterator I) {
Ted Kremenek1e80aa42008-03-04 00:42:54 +000064
Ted Kremenek1b9df4c2008-03-14 18:14:50 +000065 Stmt* S1 = GetStmt(GetLocation(I));
Ted Kremenek1e80aa42008-03-04 00:42:54 +000066 Expr* E2 = cast<Expr>(I->second);
67
Ted Kremenek1b9df4c2008-03-14 18:14:50 +000068 SourceLocation Loc = S1->getLocStart();
Ted Kremenek1e80aa42008-03-04 00:42:54 +000069 SourceRange R = E2->getSourceRange();
Ted Kremenek4dc41cc2008-03-31 18:26:32 +000070 Diag.Report(PD, FullSourceLoc(Loc, SrcMgr), ErrorDiag, 0, 0, &R, 1);
Ted Kremenek1e80aa42008-03-04 00:42:54 +000071}
72
73template <typename ITERATOR>
Ted Kremenek4dc41cc2008-03-31 18:26:32 +000074void EmitWarning(Diagnostic& Diag, PathDiagnosticClient* PD,
75 SourceManager& SrcMgr,
Chris Lattner8ce68d22008-03-10 17:06:40 +000076 ITERATOR I, ITERATOR E, const char* msg) {
Ted Kremenekd87a3212008-02-26 21:31:18 +000077
Ted Kremenek5c061212008-02-27 17:56:16 +000078 std::ostringstream Out;
Ted Kremeneka6fb4e02008-04-01 22:35:58 +000079 std::string Str;
Ted Kremenek6bb205c2008-03-31 20:42:43 +000080
81 if (!PD) {
82 Out << "[CHECKER] " << msg;
Ted Kremeneka6fb4e02008-04-01 22:35:58 +000083 Str = Out.str();
84 msg = Str.c_str();
Ted Kremenek6bb205c2008-03-31 20:42:43 +000085 }
Ted Kremenek5c061212008-02-27 17:56:16 +000086
Ted Kremenek2bebc402008-02-27 20:47:56 +000087 bool isFirst = true;
Ted Kremenekd9d1cbf2008-03-15 07:58:36 +000088 unsigned ErrorDiag = 0;
Ted Kremenek1e80aa42008-03-04 00:42:54 +000089 llvm::SmallPtrSet<void*,10> CachedErrors;
Ted Kremenekd87a3212008-02-26 21:31:18 +000090
91 for (; I != E; ++I) {
92
93 if (isFirst) {
94 isFirst = false;
95 ErrorDiag = Diag.getCustomDiagID(Diagnostic::Warning, msg);
96 }
Ted Kremenek5c61e7a2008-02-28 20:38:16 +000097 else {
98
99 // HACK: Cache the location of the error. Don't emit the same
100 // warning for the same error type that occurs at the same program
101 // location but along a different path.
Ted Kremenek1e80aa42008-03-04 00:42:54 +0000102 void* p = GetLocation(I).getRawData();
Ted Kremenek5c61e7a2008-02-28 20:38:16 +0000103
104 if (CachedErrors.count(p))
105 continue;
106
107 CachedErrors.insert(p);
108 }
Ted Kremenek1e80aa42008-03-04 00:42:54 +0000109
Ted Kremenek4dc41cc2008-03-31 18:26:32 +0000110 EmitDiag(Diag, PD, SrcMgr, ErrorDiag, I);
Ted Kremenekd87a3212008-02-26 21:31:18 +0000111 }
112}
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000113
Ted Kremenek63bbe532008-03-14 17:31:00 +0000114unsigned RunGRSimpleVals(CFG& cfg, Decl& CD, ASTContext& Ctx,
Ted Kremenek4dc41cc2008-03-31 18:26:32 +0000115 Diagnostic& Diag, PathDiagnosticClient* PD,
116 bool Visualize, bool TrimGraph) {
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000117
Ted Kremenek63bbe532008-03-14 17:31:00 +0000118 GRCoreEngine<GRExprEngine> Eng(cfg, CD, Ctx);
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000119 GRExprEngine* CheckerState = &Eng.getCheckerState();
Ted Kremenek52755612008-03-27 17:17:22 +0000120
121 // Set base transfer functions.
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000122 GRSimpleVals GRSV;
123 CheckerState->setTransferFunctions(GRSV);
124
Ted Kremenek52755612008-03-27 17:17:22 +0000125 // Add extra checkers.
126 llvm::OwningPtr<GRSimpleAPICheck> FoundationCheck(
127 CreateBasicObjCFoundationChecks(Ctx, &CheckerState->getStateManager()));
128
129 CheckerState->AddObjCMessageExprCheck(FoundationCheck.get());
130
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000131 // Execute the worklist algorithm.
Ted Kremenek4dc41cc2008-03-31 18:26:32 +0000132 Eng.ExecuteWorkList(120000);
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000133
Ted Kremenekd87a3212008-02-26 21:31:18 +0000134 SourceManager& SrcMgr = Ctx.getSourceManager();
135
Ted Kremenek4dc41cc2008-03-31 18:26:32 +0000136 EmitWarning(Diag, PD, SrcMgr,
Ted Kremenekd87a3212008-02-26 21:31:18 +0000137 CheckerState->null_derefs_begin(),
138 CheckerState->null_derefs_end(),
Ted Kremenekdbfe41a2008-03-25 16:40:05 +0000139 "Dereference of NULL pointer.");
Ted Kremenekd87a3212008-02-26 21:31:18 +0000140
Ted Kremenek4dc41cc2008-03-31 18:26:32 +0000141 EmitWarning(Diag, PD, SrcMgr,
Ted Kremenek4a4e5242008-02-28 09:25:22 +0000142 CheckerState->undef_derefs_begin(),
143 CheckerState->undef_derefs_end(),
144 "Dereference of undefined value.");
Ted Kremenekd87a3212008-02-26 21:31:18 +0000145
Ted Kremenek4dc41cc2008-03-31 18:26:32 +0000146 EmitWarning(Diag, PD, SrcMgr,
Ted Kremenekdbfe41a2008-03-25 16:40:05 +0000147 CheckerState->undef_branches_begin(),
148 CheckerState->undef_branches_end(),
149 "Branch condition evaluates to an uninitialized value.");
Ted Kremenekd87a3212008-02-26 21:31:18 +0000150
Ted Kremenek4dc41cc2008-03-31 18:26:32 +0000151 EmitWarning(Diag, PD, SrcMgr,
Ted Kremenek4d839b42008-03-07 19:04:53 +0000152 CheckerState->explicit_bad_divides_begin(),
153 CheckerState->explicit_bad_divides_end(),
Ted Kremenek4a4e5242008-02-28 09:25:22 +0000154 "Division by zero/undefined value.");
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000155
Ted Kremenek4dc41cc2008-03-31 18:26:32 +0000156 EmitWarning(Diag, PD, SrcMgr,
Ted Kremenek8cc13ea2008-02-28 20:32:03 +0000157 CheckerState->undef_results_begin(),
158 CheckerState->undef_results_end(),
159 "Result of operation is undefined.");
Ted Kremenek5e03fcb2008-02-29 23:14:48 +0000160
Ted Kremenek4dc41cc2008-03-31 18:26:32 +0000161 EmitWarning(Diag, PD, SrcMgr,
Ted Kremenek5e03fcb2008-02-29 23:14:48 +0000162 CheckerState->bad_calls_begin(),
163 CheckerState->bad_calls_end(),
164 "Call using a NULL or undefined function pointer value.");
Ted Kremenek2ded35a2008-02-29 23:53:11 +0000165
Ted Kremenek4dc41cc2008-03-31 18:26:32 +0000166 EmitWarning(Diag, PD, SrcMgr,
Ted Kremenek2ded35a2008-02-29 23:53:11 +0000167 CheckerState->undef_arg_begin(),
168 CheckerState->undef_arg_end(),
Ted Kremenekdbfe41a2008-03-25 16:40:05 +0000169 "Pass-by-value argument in function is undefined.");
Ted Kremenek1b9df4c2008-03-14 18:14:50 +0000170
Ted Kremenek4dc41cc2008-03-31 18:26:32 +0000171 EmitWarning(Diag, PD, SrcMgr,
Ted Kremenekdbfe41a2008-03-25 16:40:05 +0000172 CheckerState->msg_expr_undef_arg_begin(),
173 CheckerState->msg_expr_undef_arg_end(),
174 "Pass-by-value argument in message expression is undefined.");
175
Ted Kremenek4dc41cc2008-03-31 18:26:32 +0000176 EmitWarning(Diag, PD, SrcMgr,
Ted Kremenekdbfe41a2008-03-25 16:40:05 +0000177 CheckerState->undef_receivers_begin(),
178 CheckerState->undef_receivers_end(),
179 "Receiver in message expression is an uninitialized value.");
Ted Kremenek02737ed2008-03-31 15:02:58 +0000180
Ted Kremenek4dc41cc2008-03-31 18:26:32 +0000181 EmitWarning(Diag, PD, SrcMgr,
Ted Kremenek02737ed2008-03-31 15:02:58 +0000182 CheckerState->ret_stackaddr_begin(),
183 CheckerState->ret_stackaddr_end(),
184 "Address of stack-allocated variable returned.");
Ted Kremenekdbfe41a2008-03-25 16:40:05 +0000185
Ted Kremeneke5d5c202008-03-27 21:15:17 +0000186 FoundationCheck.get()->ReportResults(Diag);
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000187#ifndef NDEBUG
Ted Kremenekffe0f432008-03-07 22:58:01 +0000188 if (Visualize) CheckerState->ViewGraph(TrimGraph);
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000189#endif
190
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000191 return Eng.getGraph().size();
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000192}
193
Ted Kremeneke01c9872008-02-14 22:36:46 +0000194} // end clang namespace
195
Ted Kremenekd59cccc2008-02-14 18:28:23 +0000196//===----------------------------------------------------------------------===//
197// Transfer function for Casts.
198//===----------------------------------------------------------------------===//
199
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000200RVal GRSimpleVals::EvalCast(GRExprEngine& Eng, NonLVal X, QualType T) {
Ted Kremenek692416c2008-02-18 22:57:02 +0000201
Ted Kremenekd59cccc2008-02-14 18:28:23 +0000202 if (!isa<nonlval::ConcreteInt>(X))
203 return UnknownVal();
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000204
205 BasicValueFactory& BasicVals = Eng.getBasicVals();
Ted Kremenekd59cccc2008-02-14 18:28:23 +0000206
207 llvm::APSInt V = cast<nonlval::ConcreteInt>(X).getValue();
Ted Kremenek1b9df4c2008-03-14 18:14:50 +0000208 V.setIsUnsigned(T->isUnsignedIntegerType() || T->isPointerType()
209 || T->isObjCQualifiedIdType());
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000210 V.extOrTrunc(Eng.getContext().getTypeSize(T));
Ted Kremenekd59cccc2008-02-14 18:28:23 +0000211
Ted Kremenek9ef1ec92008-02-21 18:43:30 +0000212 if (T->isPointerType())
Ted Kremenek240f1f02008-03-07 20:13:31 +0000213 return lval::ConcreteInt(BasicVals.getValue(V));
Ted Kremenekd59cccc2008-02-14 18:28:23 +0000214 else
Ted Kremenek240f1f02008-03-07 20:13:31 +0000215 return nonlval::ConcreteInt(BasicVals.getValue(V));
Ted Kremenekd59cccc2008-02-14 18:28:23 +0000216}
217
218// Casts.
219
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000220RVal GRSimpleVals::EvalCast(GRExprEngine& Eng, LVal X, QualType T) {
Ted Kremenek692416c2008-02-18 22:57:02 +0000221
Ted Kremenek1b9df4c2008-03-14 18:14:50 +0000222 if (T->isPointerType() || T->isReferenceType() || T->isObjCQualifiedIdType())
Ted Kremenekd59cccc2008-02-14 18:28:23 +0000223 return X;
224
Ted Kremenek9ef1ec92008-02-21 18:43:30 +0000225 assert (T->isIntegerType());
Ted Kremenekd59cccc2008-02-14 18:28:23 +0000226
227 if (!isa<lval::ConcreteInt>(X))
228 return UnknownVal();
229
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000230 BasicValueFactory& BasicVals = Eng.getBasicVals();
231
Ted Kremenekd59cccc2008-02-14 18:28:23 +0000232 llvm::APSInt V = cast<lval::ConcreteInt>(X).getValue();
Ted Kremenekd59cccc2008-02-14 18:28:23 +0000233 V.setIsUnsigned(T->isUnsignedIntegerType() || T->isPointerType());
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000234 V.extOrTrunc(Eng.getContext().getTypeSize(T));
Ted Kremenekd59cccc2008-02-14 18:28:23 +0000235
Ted Kremenek240f1f02008-03-07 20:13:31 +0000236 return nonlval::ConcreteInt(BasicVals.getValue(V));
Ted Kremenekc3f261d2008-02-14 18:40:24 +0000237}
238
239// Unary operators.
240
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000241RVal GRSimpleVals::EvalMinus(GRExprEngine& Eng, UnaryOperator* U, NonLVal X){
Ted Kremenek692416c2008-02-18 22:57:02 +0000242
Ted Kremenekc3f261d2008-02-14 18:40:24 +0000243 switch (X.getSubKind()) {
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000244
Ted Kremenekc3f261d2008-02-14 18:40:24 +0000245 case nonlval::ConcreteIntKind:
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000246 return cast<nonlval::ConcreteInt>(X).EvalMinus(Eng.getBasicVals(), U);
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000247
Ted Kremenekc3f261d2008-02-14 18:40:24 +0000248 default:
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000249 return UnknownVal();
Ted Kremenekc3f261d2008-02-14 18:40:24 +0000250 }
251}
252
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000253RVal GRSimpleVals::EvalComplement(GRExprEngine& Eng, NonLVal X) {
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000254
Ted Kremenek90e42032008-02-20 04:12:31 +0000255 switch (X.getSubKind()) {
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000256
Ted Kremenekc3f261d2008-02-14 18:40:24 +0000257 case nonlval::ConcreteIntKind:
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000258 return cast<nonlval::ConcreteInt>(X).EvalComplement(Eng.getBasicVals());
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000259
Ted Kremenekc3f261d2008-02-14 18:40:24 +0000260 default:
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000261 return UnknownVal();
Ted Kremenekc3f261d2008-02-14 18:40:24 +0000262 }
263}
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000264
265// Binary operators.
266
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000267RVal GRSimpleVals::EvalBinOp(GRExprEngine& Eng, BinaryOperator::Opcode Op,
268 NonLVal L, NonLVal R) {
269
270 BasicValueFactory& BasicVals = Eng.getBasicVals();
271
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000272 while (1) {
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000273
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000274 switch (L.getSubKind()) {
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000275 default:
Ted Kremenek9258a642008-02-21 19:10:12 +0000276 return UnknownVal();
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000277
278 case nonlval::ConcreteIntKind:
279
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000280 if (isa<nonlval::ConcreteInt>(R)) {
281 const nonlval::ConcreteInt& L_CI = cast<nonlval::ConcreteInt>(L);
282 const nonlval::ConcreteInt& R_CI = cast<nonlval::ConcreteInt>(R);
Ted Kremenek240f1f02008-03-07 20:13:31 +0000283 return L_CI.EvalBinOp(BasicVals, Op, R_CI);
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000284 }
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000285 else {
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000286 NonLVal tmp = R;
287 R = L;
288 L = tmp;
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000289 continue;
290 }
291
292 case nonlval::SymbolValKind: {
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000293
294 if (isa<nonlval::ConcreteInt>(R)) {
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000295 const SymIntConstraint& C =
Ted Kremenek240f1f02008-03-07 20:13:31 +0000296 BasicVals.getConstraint(cast<nonlval::SymbolVal>(L).getSymbol(), Op,
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000297 cast<nonlval::ConcreteInt>(R).getValue());
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000298
299 return nonlval::SymIntConstraintVal(C);
300 }
301 else
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000302 return UnknownVal();
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000303 }
304 }
305 }
306}
307
Ted Kremenekb640b3b2008-02-15 00:52:26 +0000308
Ted Kremenekc6fbdcd2008-02-15 23:15:23 +0000309// Binary Operators (except assignments and comma).
310
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000311RVal GRSimpleVals::EvalBinOp(GRExprEngine& Eng, BinaryOperator::Opcode Op,
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000312 LVal L, LVal R) {
Ted Kremenek692416c2008-02-18 22:57:02 +0000313
Ted Kremenekc6fbdcd2008-02-15 23:15:23 +0000314 switch (Op) {
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000315
Ted Kremenekc6fbdcd2008-02-15 23:15:23 +0000316 default:
317 return UnknownVal();
318
319 case BinaryOperator::EQ:
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000320 return EvalEQ(Eng, L, R);
Ted Kremenekc6fbdcd2008-02-15 23:15:23 +0000321
322 case BinaryOperator::NE:
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000323 return EvalNE(Eng, L, R);
Ted Kremenekc6fbdcd2008-02-15 23:15:23 +0000324 }
325}
326
Ted Kremenekb640b3b2008-02-15 00:52:26 +0000327// Pointer arithmetic.
328
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000329RVal GRSimpleVals::EvalBinOp(GRExprEngine& Eng, BinaryOperator::Opcode Op,
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000330 LVal L, NonLVal R) {
331 return UnknownVal();
Ted Kremenekb640b3b2008-02-15 00:52:26 +0000332}
333
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000334// Equality operators for LVals.
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000335
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000336RVal GRSimpleVals::EvalEQ(GRExprEngine& Eng, LVal L, LVal R) {
337
338 BasicValueFactory& BasicVals = Eng.getBasicVals();
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000339
340 switch (L.getSubKind()) {
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000341
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000342 default:
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000343 assert(false && "EQ not implemented for this LVal.");
344 return UnknownVal();
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000345
346 case lval::ConcreteIntKind:
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000347
348 if (isa<lval::ConcreteInt>(R)) {
349 bool b = cast<lval::ConcreteInt>(L).getValue() ==
350 cast<lval::ConcreteInt>(R).getValue();
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000351
Ted Kremenek240f1f02008-03-07 20:13:31 +0000352 return NonLVal::MakeIntTruthVal(BasicVals, b);
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000353 }
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000354 else if (isa<lval::SymbolVal>(R)) {
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000355
356 const SymIntConstraint& C =
Ted Kremenek240f1f02008-03-07 20:13:31 +0000357 BasicVals.getConstraint(cast<lval::SymbolVal>(R).getSymbol(),
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000358 BinaryOperator::EQ,
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000359 cast<lval::ConcreteInt>(L).getValue());
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000360
361 return nonlval::SymIntConstraintVal(C);
362 }
363
364 break;
365
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000366 case lval::SymbolValKind: {
367
368 if (isa<lval::ConcreteInt>(R)) {
369 const SymIntConstraint& C =
Ted Kremenek240f1f02008-03-07 20:13:31 +0000370 BasicVals.getConstraint(cast<lval::SymbolVal>(L).getSymbol(),
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000371 BinaryOperator::EQ,
372 cast<lval::ConcreteInt>(R).getValue());
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000373
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000374 return nonlval::SymIntConstraintVal(C);
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000375 }
376
Ted Kremenekf700df22008-02-22 18:41:59 +0000377 // FIXME: Implement == for lval Symbols. This is mainly useful
378 // in iterator loops when traversing a buffer, e.g. while(z != zTerm).
379 // Since this is not useful for many checkers we'll punt on this for
380 // now.
381
382 return UnknownVal();
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000383 }
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000384
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000385 case lval::DeclValKind:
Ted Kremenekdc3936b2008-02-22 00:54:56 +0000386 case lval::FuncValKind:
387 case lval::GotoLabelKind:
Ted Kremenek240f1f02008-03-07 20:13:31 +0000388 return NonLVal::MakeIntTruthVal(BasicVals, L == R);
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000389 }
390
Ted Kremenek240f1f02008-03-07 20:13:31 +0000391 return NonLVal::MakeIntTruthVal(BasicVals, false);
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000392}
393
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000394RVal GRSimpleVals::EvalNE(GRExprEngine& Eng, LVal L, LVal R) {
Ted Kremenek692416c2008-02-18 22:57:02 +0000395
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000396 BasicValueFactory& BasicVals = Eng.getBasicVals();
397
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000398 switch (L.getSubKind()) {
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000399
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000400 default:
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000401 assert(false && "NE not implemented for this LVal.");
402 return UnknownVal();
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000403
404 case lval::ConcreteIntKind:
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000405
406 if (isa<lval::ConcreteInt>(R)) {
407 bool b = cast<lval::ConcreteInt>(L).getValue() !=
408 cast<lval::ConcreteInt>(R).getValue();
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000409
Ted Kremenek240f1f02008-03-07 20:13:31 +0000410 return NonLVal::MakeIntTruthVal(BasicVals, b);
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000411 }
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000412 else if (isa<lval::SymbolVal>(R)) {
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000413 const SymIntConstraint& C =
Ted Kremenek240f1f02008-03-07 20:13:31 +0000414 BasicVals.getConstraint(cast<lval::SymbolVal>(R).getSymbol(),
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000415 BinaryOperator::NE,
416 cast<lval::ConcreteInt>(L).getValue());
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000417
418 return nonlval::SymIntConstraintVal(C);
419 }
420
421 break;
422
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000423 case lval::SymbolValKind: {
424 if (isa<lval::ConcreteInt>(R)) {
425 const SymIntConstraint& C =
Ted Kremenek240f1f02008-03-07 20:13:31 +0000426 BasicVals.getConstraint(cast<lval::SymbolVal>(L).getSymbol(),
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000427 BinaryOperator::NE,
428 cast<lval::ConcreteInt>(R).getValue());
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000429
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000430 return nonlval::SymIntConstraintVal(C);
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000431 }
432
Ted Kremenekf700df22008-02-22 18:41:59 +0000433 // FIXME: Implement != for lval Symbols. This is mainly useful
434 // in iterator loops when traversing a buffer, e.g. while(z != zTerm).
435 // Since this is not useful for many checkers we'll punt on this for
436 // now.
437
438 return UnknownVal();
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000439
440 break;
Ted Kremenekaa1c4e52008-02-21 18:02:17 +0000441 }
442
443 case lval::DeclValKind:
Ted Kremenekdc3936b2008-02-22 00:54:56 +0000444 case lval::FuncValKind:
445 case lval::GotoLabelKind:
Ted Kremenek240f1f02008-03-07 20:13:31 +0000446 return NonLVal::MakeIntTruthVal(BasicVals, L != R);
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000447 }
448
Ted Kremenek240f1f02008-03-07 20:13:31 +0000449 return NonLVal::MakeIntTruthVal(BasicVals, true);
Ted Kremenek6cb0b542008-02-14 19:37:24 +0000450}
Ted Kremenek06747692008-02-26 23:04:29 +0000451
452//===----------------------------------------------------------------------===//
453// Transfer function for Function Calls.
454//===----------------------------------------------------------------------===//
455
Ted Kremenek330dddd2008-03-05 00:33:14 +0000456void GRSimpleVals::EvalCall(ExplodedNodeSet<ValueState>& Dst,
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000457 GRExprEngine& Eng,
Ted Kremenek330dddd2008-03-05 00:33:14 +0000458 GRStmtNodeBuilder<ValueState>& Builder,
Ted Kremenek330dddd2008-03-05 00:33:14 +0000459 CallExpr* CE, LVal L,
460 ExplodedNode<ValueState>* Pred) {
461
Ted Kremenekf923a912008-03-12 21:04:07 +0000462 ValueStateManager& StateMgr = Eng.getStateManager();
463 ValueState* St = Builder.GetState(Pred);
Ted Kremenek06747692008-02-26 23:04:29 +0000464
465 // Invalidate all arguments passed in by reference (LVals).
466
467 for (CallExpr::arg_iterator I = CE->arg_begin(), E = CE->arg_end();
468 I != E; ++I) {
469
Ted Kremenekf923a912008-03-12 21:04:07 +0000470 RVal V = StateMgr.GetRVal(St, *I);
Ted Kremenek06747692008-02-26 23:04:29 +0000471
472 if (isa<LVal>(V))
Ted Kremenekf923a912008-03-12 21:04:07 +0000473 St = StateMgr.SetRVal(St, cast<LVal>(V), UnknownVal());
Ted Kremenek06747692008-02-26 23:04:29 +0000474 }
Ted Kremenekf923a912008-03-12 21:04:07 +0000475
476 // Make up a symbol for the return value of this function.
477
478 if (CE->getType() != Eng.getContext().VoidTy) {
479 unsigned Count = Builder.getCurrentBlockCount();
Ted Kremenek361fa8e2008-03-12 21:45:47 +0000480 SymbolID Sym = Eng.getSymbolManager().getConjuredSymbol(CE, Count);
Ted Kremenekf923a912008-03-12 21:04:07 +0000481
482 RVal X = CE->getType()->isPointerType()
483 ? cast<RVal>(lval::SymbolVal(Sym))
484 : cast<RVal>(nonlval::SymbolVal(Sym));
485
486 St = StateMgr.SetRVal(St, CE, X, Eng.getCFG().isBlkExpr(CE), false);
487 }
Ted Kremenek330dddd2008-03-05 00:33:14 +0000488
Ted Kremenek0e561a32008-03-21 21:30:14 +0000489 Builder.MakeNode(Dst, CE, Pred, St);
Ted Kremenek06747692008-02-26 23:04:29 +0000490}