blob: 50be690077112635d47d60496de4813ef366957e [file] [log] [blame]
Ted Kremenekd27f8162008-01-15 23:55:06 +00001//===-- GRConstants.cpp - Simple, Path-Sens. Constant Prop. ------*- C++ -*-==//
2//
Ted Kremenekab2b8c52008-01-23 19:59:44 +00003// The LLValM Compiler Infrastructure
Ted Kremenekd27f8162008-01-15 23:55:06 +00004//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// Constant Propagation via Graph Reachability
11//
12// This files defines a simple analysis that performs path-sensitive
13// constant propagation within a function. An example use of this analysis
14// is to perform simple checks for NULL dereferences.
15//
16//===----------------------------------------------------------------------===//
17
18#include "clang/Analysis/PathSensitive/GREngine.h"
19#include "clang/AST/Expr.h"
Ted Kremenek874d63f2008-01-24 02:02:54 +000020#include "clang/AST/ASTContext.h"
Ted Kremenekd27f8162008-01-15 23:55:06 +000021#include "clang/Analysis/Analyses/LiveVariables.h"
Ted Kremenekd27f8162008-01-15 23:55:06 +000022
23#include "llvm/Support/Casting.h"
24#include "llvm/Support/DataTypes.h"
25#include "llvm/ADT/APSInt.h"
26#include "llvm/ADT/FoldingSet.h"
27#include "llvm/ADT/ImmutableMap.h"
Ted Kremenek3c6c6722008-01-16 17:56:25 +000028#include "llvm/ADT/SmallVector.h"
Ted Kremenekab2b8c52008-01-23 19:59:44 +000029#include "llvm/Support/Allocator.h"
Ted Kremenekd27f8162008-01-15 23:55:06 +000030#include "llvm/Support/Compiler.h"
31
Ted Kremenekab2b8c52008-01-23 19:59:44 +000032#include "llvm/Support/Streams.h"
33
Ted Kremenekaa66a322008-01-16 21:46:15 +000034#ifndef NDEBUG
35#include "llvm/Support/GraphWriter.h"
36#include <sstream>
37#endif
38
Ted Kremenekd27f8162008-01-15 23:55:06 +000039using namespace clang;
Ted Kremenekd27f8162008-01-15 23:55:06 +000040using llvm::dyn_cast;
41using llvm::cast;
42
43//===----------------------------------------------------------------------===//
Ted Kremenekab2b8c52008-01-23 19:59:44 +000044/// ValueKey - A variant smart pointer that wraps either a ValueDecl* or a
Ted Kremenekd27f8162008-01-15 23:55:06 +000045/// Stmt*. Use cast<> or dyn_cast<> to get actual pointer type
46//===----------------------------------------------------------------------===//
47namespace {
Ted Kremenekab2b8c52008-01-23 19:59:44 +000048
49class VISIBILITY_HIDDEN ValueKey {
Ted Kremenek0525a4f2008-01-16 19:47:19 +000050 uintptr_t Raw;
Ted Kremenekd27f8162008-01-15 23:55:06 +000051public:
Ted Kremenek5c1b9962008-01-24 19:43:37 +000052 enum Kind { IsSubExp=0x0, IsBlkExpr=0x1, IsDecl=0x2, Flags=0x3 };
Ted Kremenekd27f8162008-01-15 23:55:06 +000053 inline void* getPtr() const { return reinterpret_cast<void*>(Raw & ~Flags); }
Ted Kremenekab2b8c52008-01-23 19:59:44 +000054 inline Kind getKind() const { return (Kind) (Raw & Flags); }
Ted Kremenekd27f8162008-01-15 23:55:06 +000055
Ted Kremenekab2b8c52008-01-23 19:59:44 +000056 ValueKey(const ValueDecl* VD)
57 : Raw(reinterpret_cast<uintptr_t>(VD) | IsDecl) {}
58
Ted Kremenek5c1b9962008-01-24 19:43:37 +000059 ValueKey(Stmt* S, bool isBlkExpr = false)
Ted Kremenekab2b8c52008-01-23 19:59:44 +000060 : Raw(reinterpret_cast<uintptr_t>(S) | (isBlkExpr ? IsBlkExpr : IsSubExp)){}
Ted Kremenekd27f8162008-01-15 23:55:06 +000061
62 bool isSubExpr() const { return getKind() == IsSubExp; }
Ted Kremenekab2b8c52008-01-23 19:59:44 +000063 bool isDecl() const { return getKind() == IsDecl; }
Ted Kremenekd27f8162008-01-15 23:55:06 +000064
65 inline void Profile(llvm::FoldingSetNodeID& ID) const {
Ted Kremenek98491852008-01-16 05:51:13 +000066 ID.AddPointer(getPtr());
67 ID.AddInteger((unsigned) getKind());
Ted Kremenekab2b8c52008-01-23 19:59:44 +000068 }
69
70 inline bool operator==(const ValueKey& X) const {
Ted Kremenek5c1b9962008-01-24 19:43:37 +000071 return getPtr() == X.getPtr();
Ted Kremenekab2b8c52008-01-23 19:59:44 +000072 }
73
74 inline bool operator!=(const ValueKey& X) const {
75 return !operator==(X);
76 }
77
78 inline bool operator<(const ValueKey& X) const {
79 Kind k = getKind(), Xk = X.getKind();
Ted Kremenek5c1b9962008-01-24 19:43:37 +000080
81 if (k == IsDecl) {
82 if (Xk != IsDecl)
83 return false;
84 }
85 else {
86 if (Xk == IsDecl)
87 return true;
88 }
Ted Kremenekab2b8c52008-01-23 19:59:44 +000089
Ted Kremenek5c1b9962008-01-24 19:43:37 +000090 return getPtr() < X.getPtr();
Ted Kremenekb3d2dca2008-01-16 23:33:44 +000091 }
Ted Kremenekd27f8162008-01-15 23:55:06 +000092};
93} // end anonymous namespace
94
Ted Kremenekab2b8c52008-01-23 19:59:44 +000095// Machinery to get cast<> and dyn_cast<> working with ValueKey.
Ted Kremenekd27f8162008-01-15 23:55:06 +000096namespace llvm {
Ted Kremenekab2b8c52008-01-23 19:59:44 +000097 template<> inline bool isa<ValueDecl,ValueKey>(const ValueKey& V) {
98 return V.getKind() == ValueKey::IsDecl;
Ted Kremenekd27f8162008-01-15 23:55:06 +000099 }
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000100 template<> inline bool isa<Stmt,ValueKey>(const ValueKey& V) {
101 return ((unsigned) V.getKind()) != ValueKey::IsDecl;
Ted Kremenekd27f8162008-01-15 23:55:06 +0000102 }
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000103 template<> struct VISIBILITY_HIDDEN cast_retty_impl<ValueDecl,ValueKey> {
Ted Kremenekaa66a322008-01-16 21:46:15 +0000104 typedef const ValueDecl* ret_type;
Ted Kremenekd27f8162008-01-15 23:55:06 +0000105 };
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000106 template<> struct VISIBILITY_HIDDEN cast_retty_impl<Stmt,ValueKey> {
Ted Kremenekd27f8162008-01-15 23:55:06 +0000107 typedef const Stmt* ret_type;
108 };
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000109 template<> struct VISIBILITY_HIDDEN simplify_type<ValueKey> {
Ted Kremenekd27f8162008-01-15 23:55:06 +0000110 typedef void* SimpleType;
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000111 static inline SimpleType getSimplifiedValue(const ValueKey &V) {
Ted Kremenekd27f8162008-01-15 23:55:06 +0000112 return V.getPtr();
113 }
114 };
115} // end llvm namespace
116
117//===----------------------------------------------------------------------===//
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000118// ValueManager.
Ted Kremenekd27f8162008-01-15 23:55:06 +0000119//===----------------------------------------------------------------------===//
120
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000121namespace {
122
123typedef llvm::ImmutableSet<llvm::APSInt > APSIntSetTy;
124
125class VISIBILITY_HIDDEN ValueManager {
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000126 APSIntSetTy::Factory APSIntSetFactory;
Ted Kremenek874d63f2008-01-24 02:02:54 +0000127 ASTContext* Ctx;
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000128
129public:
130 ValueManager() {}
131 ~ValueManager() {}
132
Ted Kremenek874d63f2008-01-24 02:02:54 +0000133 void setContext(ASTContext* ctx) { Ctx = ctx; }
134 ASTContext* getContext() const { return Ctx; }
135
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000136 APSIntSetTy GetEmptyAPSIntSet() {
137 return APSIntSetFactory.GetEmptySet();
138 }
139
140 APSIntSetTy AddToSet(const APSIntSetTy& Set, const llvm::APSInt& Val) {
141 return APSIntSetFactory.Add(Set, Val);
Ted Kremenekd27f8162008-01-15 23:55:06 +0000142 }
143};
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000144} // end anonymous namespace
145
146//===----------------------------------------------------------------------===//
147// Expression Values.
148//===----------------------------------------------------------------------===//
149
150namespace {
151
152class VISIBILITY_HIDDEN ExprValue {
153public:
154 enum Kind { // L-Values.
155 LValueDeclKind = 0x0,
156 // Special "Invalid" value.
157 InvalidValueKind = 0x1,
158 // R-Values.
159 RValueMayEqualSetKind = 0x2,
160 // Note that the Lvalue and RValue "kinds" overlap;
161 // the "InvalidValue" class can be used either as
162 // an LValue or RValue.
163 MinLValueKind = 0x0, MaxLValueKind = 0x1,
164 MinRValueKind = 0x1, MaxRValueKind = 0x2 };
165
166private:
167 enum Kind kind;
168 void* Data;
169
170protected:
171 ExprValue(Kind k, void* d) : kind(k), Data(d) {}
172
173 void* getRawPtr() const { return Data; }
174
175public:
176 ~ExprValue() {};
177
Ted Kremenek874d63f2008-01-24 02:02:54 +0000178 ExprValue EvalCast(ValueManager& ValMgr, Expr* CastExpr) const;
179
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000180 void Profile(llvm::FoldingSetNodeID& ID) const {
181 ID.AddInteger((unsigned) getKind());
182 ID.AddPointer(Data);
183 }
184
185 bool operator==(const ExprValue& RHS) const {
186 return kind == RHS.kind && Data == RHS.Data;
187 }
188
189 Kind getKind() const { return kind; }
190 bool isValid() const { return getKind() != InvalidValueKind; }
191
192 void print(std::ostream& OS) const;
193 void print() const { print(*llvm::cerr.stream()); }
194
195 // Implement isa<T> support.
196 static inline bool classof(const ExprValue*) { return true; }
197};
198
199class VISIBILITY_HIDDEN InvalidValue : public ExprValue {
200public:
201 InvalidValue() : ExprValue(InvalidValueKind, NULL) {}
202
203 static inline bool classof(const ExprValue* V) {
204 return V->getKind() == InvalidValueKind;
205 }
206};
207
208} // end anonymous namespace
209
210//===----------------------------------------------------------------------===//
211// "R-Values": Interface.
212//===----------------------------------------------------------------------===//
213
214namespace {
215class VISIBILITY_HIDDEN RValue : public ExprValue {
216protected:
217 RValue(Kind k, void* d) : ExprValue(k,d) {}
218
219public:
Ted Kremenek874d63f2008-01-24 02:02:54 +0000220 RValue EvalAdd(ValueManager& ValMgr, const RValue& RHS) const;
221 RValue EvalSub(ValueManager& ValMgr, const RValue& RHS) const;
222 RValue EvalMul(ValueManager& ValMgr, const RValue& RHS) const;
Ted Kremenekdacbb4f2008-01-24 08:20:02 +0000223 RValue EvalMinus(ValueManager& ValMgr, UnaryOperator* U) const;
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000224
Ted Kremenek7b8009a2008-01-24 02:28:56 +0000225 static RValue GetRValue(ValueManager& ValMgr, const llvm::APSInt& V);
Ted Kremenekdacbb4f2008-01-24 08:20:02 +0000226 static RValue GetRValue(ValueManager& ValMgr, IntegerLiteral* I);
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000227
228 // Implement isa<T> support.
229 static inline bool classof(const ExprValue* V) {
230 return V->getKind() >= MinRValueKind;
231 }
232};
233
234class VISIBILITY_HIDDEN RValueMayEqualSet : public RValue {
235public:
236 RValueMayEqualSet(const APSIntSetTy& S)
237 : RValue(RValueMayEqualSetKind, S.getRoot()) {}
238
239 APSIntSetTy GetValues() const {
240 return APSIntSetTy(reinterpret_cast<APSIntSetTy::TreeTy*>(getRawPtr()));
241 }
242
Ted Kremenek874d63f2008-01-24 02:02:54 +0000243 RValueMayEqualSet EvalAdd(ValueManager& ValMgr,
244 const RValueMayEqualSet& V) const;
245
246 RValueMayEqualSet EvalSub(ValueManager& ValMgr,
247 const RValueMayEqualSet& V) const;
248
249 RValueMayEqualSet EvalMul(ValueManager& ValMgr,
250 const RValueMayEqualSet& V) const;
251
252 RValueMayEqualSet EvalCast(ValueManager& ValMgr, Expr* CastExpr) const;
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000253
Ted Kremenekdacbb4f2008-01-24 08:20:02 +0000254 RValueMayEqualSet EvalMinus(ValueManager& ValMgr, UnaryOperator* U) const;
255
256
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000257 // Implement isa<T> support.
258 static inline bool classof(const ExprValue* V) {
259 return V->getKind() == RValueMayEqualSetKind;
260 }
261};
262} // end anonymous namespace
263
264//===----------------------------------------------------------------------===//
Ted Kremenek874d63f2008-01-24 02:02:54 +0000265// Transfer functions: Casts.
266//===----------------------------------------------------------------------===//
267
268ExprValue ExprValue::EvalCast(ValueManager& ValMgr, Expr* CastExpr) const {
269 switch (getKind()) {
270 case RValueMayEqualSetKind:
271 return cast<RValueMayEqualSet>(this)->EvalCast(ValMgr, CastExpr);
272 default:
273 return InvalidValue();
274 }
275}
276
277RValueMayEqualSet
278RValueMayEqualSet::EvalCast(ValueManager& ValMgr, Expr* CastExpr) const {
279 QualType T = CastExpr->getType();
280 assert (T->isIntegerType());
281
282 APSIntSetTy S1 = GetValues();
283 APSIntSetTy S2 = ValMgr.GetEmptyAPSIntSet();
284
285 for (APSIntSetTy::iterator I=S1.begin(), E=S1.end(); I!=E; ++I) {
286 llvm::APSInt X = *I;
287 X.setIsSigned(T->isSignedIntegerType());
288 X.extOrTrunc(ValMgr.getContext()->getTypeSize(T,CastExpr->getLocStart()));
289 S2 = ValMgr.AddToSet(S2, X);
290 }
291
292 return S2;
293}
294
295//===----------------------------------------------------------------------===//
Ted Kremenekdacbb4f2008-01-24 08:20:02 +0000296// Transfer functions: Unary Operations over R-Values.
297//===----------------------------------------------------------------------===//
298
299RValue RValue::EvalMinus(ValueManager& ValMgr, UnaryOperator* U) const {
300 switch (getKind()) {
301 case RValueMayEqualSetKind:
302 return cast<RValueMayEqualSet>(this)->EvalMinus(ValMgr, U);
303 default:
304 return cast<RValue>(InvalidValue());
305 }
306}
307
308RValueMayEqualSet
309RValueMayEqualSet::EvalMinus(ValueManager& ValMgr, UnaryOperator* U) const {
310
311 assert (U->getType() == U->getSubExpr()->getType());
312 assert (U->getType()->isIntegerType());
313
314 APSIntSetTy S1 = GetValues();
315 APSIntSetTy S2 = ValMgr.GetEmptyAPSIntSet();
316
317 for (APSIntSetTy::iterator I=S1.begin(), E=S1.end(); I!=E; ++I) {
318 assert ((*I).isSigned());
319
320 // FIXME: Shouldn't operator- on APSInt return an APSInt with the proper
321 // sign?
322 llvm::APSInt X(-(*I));
323 X.setIsSigned(true);
324
325 S2 = ValMgr.AddToSet(S2, X);
326 }
327
328 return S2;
329}
330
331
332
333//===----------------------------------------------------------------------===//
Ted Kremenek874d63f2008-01-24 02:02:54 +0000334// Transfer functions: Binary Operations over R-Values.
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000335//===----------------------------------------------------------------------===//
336
337#define RVALUE_DISPATCH_CASE(k1,k2,Op)\
338case ((k1##Kind+(MaxRValueKind-MinRValueKind))+(k2##Kind - MinRValueKind)):\
Ted Kremenek874d63f2008-01-24 02:02:54 +0000339 return cast<k1>(*this).Eval##Op(ValMgr,cast<k2>(RHS));
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000340
341#define RVALUE_DISPATCH(Op)\
342switch (getKind()+(MaxRValueKind-MinRValueKind)+(RHS.getKind()-MinRValueKind)){\
343 RVALUE_DISPATCH_CASE(RValueMayEqualSet,RValueMayEqualSet,Op)\
344 default:\
345 assert (!isValid() || !RHS.isValid() && "Missing case.");\
346 break;\
347}\
348return cast<RValue>(InvalidValue());
349
Ted Kremenek874d63f2008-01-24 02:02:54 +0000350RValue RValue::EvalAdd(ValueManager& ValMgr, const RValue& RHS) const {
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000351 RVALUE_DISPATCH(Add)
352}
353
Ted Kremenek874d63f2008-01-24 02:02:54 +0000354RValue RValue::EvalSub(ValueManager& ValMgr, const RValue& RHS) const {
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000355 RVALUE_DISPATCH(Sub)
356}
357
Ted Kremenek874d63f2008-01-24 02:02:54 +0000358RValue RValue::EvalMul(ValueManager& ValMgr, const RValue& RHS) const {
Ted Kremenek2eafd0e2008-01-23 23:42:27 +0000359 RVALUE_DISPATCH(Mul)
360}
361
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000362#undef RVALUE_DISPATCH_CASE
363#undef RVALUE_DISPATCH
364
365RValueMayEqualSet
Ted Kremenek874d63f2008-01-24 02:02:54 +0000366RValueMayEqualSet::EvalAdd(ValueManager& ValMgr,
367 const RValueMayEqualSet& RHS) const {
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000368
369 APSIntSetTy S1 = GetValues();
370 APSIntSetTy S2 = RHS.GetValues();
371
372 APSIntSetTy M = ValMgr.GetEmptyAPSIntSet();
373
374 for (APSIntSetTy::iterator I1=S1.begin(), E1=S2.end(); I1!=E1; ++I1)
Ted Kremenekdacbb4f2008-01-24 08:20:02 +0000375 for (APSIntSetTy::iterator I2=S2.begin(), E2=S2.end(); I2!=E2; ++I2) {
376 // FIXME: operator- on APSInt is really operator* on APInt, which loses
377 // the "signess" information (although the bits are correct).
378 const llvm::APSInt& X = *I1;
379 llvm::APSInt Y = X + *I2;
380 Y.setIsSigned(X.isSigned());
381 M = ValMgr.AddToSet(M, Y);
382 }
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000383
384 return M;
385}
386
387RValueMayEqualSet
Ted Kremenek874d63f2008-01-24 02:02:54 +0000388RValueMayEqualSet::EvalSub(ValueManager& ValMgr,
389 const RValueMayEqualSet& RHS) const {
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000390
391 APSIntSetTy S1 = GetValues();
392 APSIntSetTy S2 = RHS.GetValues();
393
394 APSIntSetTy M = ValMgr.GetEmptyAPSIntSet();
395
396 for (APSIntSetTy::iterator I1=S1.begin(), E1=S2.end(); I1!=E1; ++I1)
Ted Kremenekdacbb4f2008-01-24 08:20:02 +0000397 for (APSIntSetTy::iterator I2=S2.begin(), E2=S2.end(); I2!=E2; ++I2) {
398 // FIXME: operator- on APSInt is really operator* on APInt, which loses
399 // the "signess" information (although the bits are correct).
400 const llvm::APSInt& X = *I1;
401 llvm::APSInt Y = X - *I2;
402 Y.setIsSigned(X.isSigned());
403 M = ValMgr.AddToSet(M, Y);
404 }
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000405
406 return M;
407}
408
Ted Kremenek2eafd0e2008-01-23 23:42:27 +0000409RValueMayEqualSet
Ted Kremenek874d63f2008-01-24 02:02:54 +0000410RValueMayEqualSet::EvalMul(ValueManager& ValMgr,
411 const RValueMayEqualSet& RHS) const {
Ted Kremenek2eafd0e2008-01-23 23:42:27 +0000412
413 APSIntSetTy S1 = GetValues();
414 APSIntSetTy S2 = RHS.GetValues();
415
416 APSIntSetTy M = ValMgr.GetEmptyAPSIntSet();
417
418 for (APSIntSetTy::iterator I1=S1.begin(), E1=S2.end(); I1!=E1; ++I1)
Ted Kremenekdacbb4f2008-01-24 08:20:02 +0000419 for (APSIntSetTy::iterator I2=S2.begin(), E2=S2.end(); I2!=E2; ++I2) {
420 // FIXME: operator* on APSInt is really operator* on APInt, which loses
421 // the "signess" information (although the bits are correct).
422 const llvm::APSInt& X = *I1;
423 llvm::APSInt Y = X * *I2;
424 Y.setIsSigned(X.isSigned());
425 M = ValMgr.AddToSet(M, Y);
426 }
Ted Kremenek2eafd0e2008-01-23 23:42:27 +0000427
428 return M;
429}
430
Ted Kremenek7b8009a2008-01-24 02:28:56 +0000431RValue RValue::GetRValue(ValueManager& ValMgr, const llvm::APSInt& V) {
432 return RValueMayEqualSet(ValMgr.AddToSet(ValMgr.GetEmptyAPSIntSet(), V));
Ted Kremenekdacbb4f2008-01-24 08:20:02 +0000433}
434
435RValue RValue::GetRValue(ValueManager& ValMgr, IntegerLiteral* I) {
436 llvm::APSInt X(I->getValue());
437 X.setIsSigned(I->getType()->isSignedIntegerType());
438 return GetRValue(ValMgr, X);
439}
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000440
441//===----------------------------------------------------------------------===//
442// "L-Values".
443//===----------------------------------------------------------------------===//
444
445namespace {
446
447class VISIBILITY_HIDDEN LValue : public ExprValue {
448protected:
449 LValue(Kind k, void* D) : ExprValue(k, D) {}
450
451public:
452 // Implement isa<T> support.
453 static inline bool classof(const ExprValue* V) {
454 return V->getKind() <= MaxLValueKind;
455 }
456};
457
458class VISIBILITY_HIDDEN LValueDecl : public LValue {
459public:
Ted Kremenek9de04c42008-01-24 20:55:43 +0000460 LValueDecl(const ValueDecl* vd)
461 : LValue(LValueDeclKind,const_cast<ValueDecl*>(vd)) {}
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000462
463 ValueDecl* getDecl() const {
464 return static_cast<ValueDecl*>(getRawPtr());
465 }
466
467 // Implement isa<T> support.
468 static inline bool classof(const ExprValue* V) {
469 return V->getKind() == LValueDeclKind;
470 }
471};
472} // end anonymous namespace
473
474//===----------------------------------------------------------------------===//
475// Pretty-Printing.
476//===----------------------------------------------------------------------===//
477
478void ExprValue::print(std::ostream& Out) const {
479 switch (getKind()) {
480 case InvalidValueKind:
481 Out << "Invalid"; break;
482
483 case RValueMayEqualSetKind: {
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000484 APSIntSetTy S = cast<RValueMayEqualSet>(this)->GetValues();
Ted Kremenek803c9ed2008-01-23 22:30:44 +0000485 bool first = true;
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000486
Ted Kremenek803c9ed2008-01-23 22:30:44 +0000487 for (APSIntSetTy::iterator I=S.begin(), E=S.end(); I!=E; ++I) {
488 if (first) first = false;
489 else Out << " | ";
490
491 Out << (*I).toString();
492 }
493
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000494 break;
495 }
496
497 default:
498 assert (false && "Pretty-printed not implemented for this ExprValue.");
499 break;
500 }
501}
502
503//===----------------------------------------------------------------------===//
504// ValueMapTy - A ImmutableMap type Stmt*/Decl* to ExprValues.
505//===----------------------------------------------------------------------===//
506
507typedef llvm::ImmutableMap<ValueKey,ExprValue> ValueMapTy;
508
509namespace clang {
510 template<>
511 struct VISIBILITY_HIDDEN GRTrait<ValueMapTy> {
512 static inline void* toPtr(ValueMapTy M) {
513 return reinterpret_cast<void*>(M.getRoot());
514 }
515 static inline ValueMapTy toState(void* P) {
516 return ValueMapTy(static_cast<ValueMapTy::TreeTy*>(P));
517 }
518 };
Ted Kremenekd27f8162008-01-15 23:55:06 +0000519}
520
521//===----------------------------------------------------------------------===//
522// The Checker!
523//===----------------------------------------------------------------------===//
524
525namespace {
Ted Kremenekd27f8162008-01-15 23:55:06 +0000526
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000527class VISIBILITY_HIDDEN GRConstants {
Ted Kremenekd27f8162008-01-15 23:55:06 +0000528
529public:
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000530 typedef ValueMapTy StateTy;
Ted Kremenekd27f8162008-01-15 23:55:06 +0000531 typedef GRNodeBuilder<GRConstants> NodeBuilder;
532 typedef ExplodedNode<StateTy> NodeTy;
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000533
534 class NodeSet {
535 typedef llvm::SmallVector<NodeTy*,3> ImplTy;
536 ImplTy Impl;
537 public:
538
539 NodeSet() {}
540 NodeSet(NodeTy* N) { assert (N && !N->isInfeasible()); Impl.push_back(N); }
541
542 void Add(NodeTy* N) { if (N && !N->isInfeasible()) Impl.push_back(N); }
543
544 typedef ImplTy::iterator iterator;
545 typedef ImplTy::const_iterator const_iterator;
546
547 unsigned size() const { return Impl.size(); }
Ted Kremenek9de04c42008-01-24 20:55:43 +0000548 bool empty() const { return Impl.empty(); }
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000549
550 iterator begin() { return Impl.begin(); }
551 iterator end() { return Impl.end(); }
552
553 const_iterator begin() const { return Impl.begin(); }
554 const_iterator end() const { return Impl.end(); }
555 };
Ted Kremenekd27f8162008-01-15 23:55:06 +0000556
557protected:
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000558 /// Liveness - live-variables information the ValueDecl* and block-level
559 /// Expr* in the CFG. Used to prune out dead state.
Ted Kremenekd27f8162008-01-15 23:55:06 +0000560 LiveVariables* Liveness;
561
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000562 /// Builder - The current GRNodeBuilder which is used when building the nodes
563 /// for a given statement.
Ted Kremenekd27f8162008-01-15 23:55:06 +0000564 NodeBuilder* Builder;
565
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000566 /// StateMgr - Object that manages the data for all created states.
567 ValueMapTy::Factory StateMgr;
Ted Kremenekd27f8162008-01-15 23:55:06 +0000568
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000569 /// ValueMgr - Object that manages the data for all created ExprValues.
570 ValueManager ValMgr;
571
572 /// cfg - the current CFG.
Ted Kremenekd27f8162008-01-15 23:55:06 +0000573 CFG* cfg;
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000574
575 /// StmtEntryNode - The immediate predecessor node.
576 NodeTy* StmtEntryNode;
577
578 /// CurrentStmt - The current block-level statement.
579 Stmt* CurrentStmt;
580
581 bool StateCleaned;
Ted Kremenekd27f8162008-01-15 23:55:06 +0000582
Ted Kremenek7b8009a2008-01-24 02:28:56 +0000583 ASTContext* getContext() const { return ValMgr.getContext(); }
584
Ted Kremenekd27f8162008-01-15 23:55:06 +0000585public:
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000586 GRConstants() : Liveness(NULL), Builder(NULL), cfg(NULL),
587 StmtEntryNode(NULL), CurrentStmt(NULL) {}
Ted Kremenekd27f8162008-01-15 23:55:06 +0000588
589 ~GRConstants() { delete Liveness; }
590
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000591 /// getCFG - Returns the CFG associated with this analysis.
Ted Kremenekd27f8162008-01-15 23:55:06 +0000592 CFG& getCFG() { assert (cfg); return *cfg; }
593
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000594 /// Initialize - Initialize the checker's state based on the specified
595 /// CFG. This results in liveness information being computed for
596 /// each block-level statement in the CFG.
Ted Kremenek874d63f2008-01-24 02:02:54 +0000597 void Initialize(CFG& c, ASTContext& ctx) {
598 cfg = &c;
599 ValMgr.setContext(&ctx);
Ted Kremenekd27f8162008-01-15 23:55:06 +0000600 Liveness = new LiveVariables(c);
601 Liveness->runOnCFG(c);
Ted Kremenek79649df2008-01-17 18:25:22 +0000602 Liveness->runOnAllBlocks(c, NULL, true);
Ted Kremenekd27f8162008-01-15 23:55:06 +0000603 }
604
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000605 /// getInitialState - Return the initial state used for the root vertex
606 /// in the ExplodedGraph.
Ted Kremenekd27f8162008-01-15 23:55:06 +0000607 StateTy getInitialState() {
Ted Kremenekcb448ca2008-01-16 00:53:15 +0000608 return StateMgr.GetEmptyMap();
Ted Kremenekd27f8162008-01-15 23:55:06 +0000609 }
Ted Kremenekd27f8162008-01-15 23:55:06 +0000610
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000611 /// ProcessStmt - Called by GREngine. Used to generate new successor
612 /// nodes by processing the 'effects' of a block-level statement.
613 void ProcessStmt(Stmt* S, NodeBuilder& builder);
614
615 /// RemoveDeadBindings - Return a new state that is the same as 'M' except
616 /// that all subexpression mappings are removed and that any
617 /// block-level expressions that are not live at 'S' also have their
618 /// mappings removed.
619 StateTy RemoveDeadBindings(Stmt* S, StateTy M);
620
Ted Kremenek9de04c42008-01-24 20:55:43 +0000621 StateTy SetValue(StateTy St, Stmt* S, const ExprValue& V);
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000622
Ted Kremenek9de04c42008-01-24 20:55:43 +0000623 StateTy SetValue(StateTy St, const Stmt* S, const ExprValue& V) {
624 return SetValue(St, const_cast<Stmt*>(S), V);
625 }
626
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000627 StateTy SetValue(StateTy St, const LValue& LV, const ExprValue& V);
Ted Kremenek1ccd31c2008-01-16 19:42:59 +0000628
Ted Kremenek9de04c42008-01-24 20:55:43 +0000629 ExprValue GetValue(const StateTy& St, Stmt* S);
630 inline ExprValue GetValue(const StateTy& St, const Stmt* S) {
631 return GetValue(St, const_cast<Stmt*>(S));
632 }
633
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000634 ExprValue GetValue(const StateTy& St, const LValue& LV);
635 LValue GetLValue(const StateTy& St, Stmt* S);
Ted Kremenekd27f8162008-01-15 23:55:06 +0000636
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000637 void Nodify(NodeSet& Dst, Stmt* S, NodeTy* Pred, StateTy St);
Ted Kremenekd27f8162008-01-15 23:55:06 +0000638
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000639 /// Visit - Transfer function logic for all statements. Dispatches to
640 /// other functions that handle specific kinds of statements.
641 void Visit(Stmt* S, NodeTy* Pred, NodeSet& Dst);
Ted Kremenek874d63f2008-01-24 02:02:54 +0000642
643 /// VisitCast - Transfer function logic for all casts (implicit and explicit).
644 void VisitCast(Expr* CastE, Expr* E, NodeTy* Pred, NodeSet& Dst);
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000645
Ted Kremenek7b8009a2008-01-24 02:28:56 +0000646 /// VisitUnaryOperator - Transfer function logic for unary operators.
647 void VisitUnaryOperator(UnaryOperator* B, NodeTy* Pred, NodeSet& Dst);
648
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000649 /// VisitBinaryOperator - Transfer function logic for binary operators.
Ted Kremenek9de04c42008-01-24 20:55:43 +0000650 void VisitBinaryOperator(BinaryOperator* B, NodeTy* Pred, NodeSet& Dst);
651
652 /// VisitDeclStmt - Transfer function logic for DeclStmts.
653 void VisitDeclStmt(DeclStmt* DS, NodeTy* Pred, NodeSet& Dst);
Ted Kremenekd27f8162008-01-15 23:55:06 +0000654};
655} // end anonymous namespace
656
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000657
Ted Kremenekd27f8162008-01-15 23:55:06 +0000658void GRConstants::ProcessStmt(Stmt* S, NodeBuilder& builder) {
659 Builder = &builder;
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000660
661 StmtEntryNode = builder.getLastNode();
662 CurrentStmt = S;
663 NodeSet Dst;
664 StateCleaned = false;
665
666 Visit(S, StmtEntryNode, Dst);
667
668 // If no nodes were generated, generate a new node that has all the
669 // dead mappings removed.
670 if (Dst.size() == 1 && *Dst.begin() == StmtEntryNode) {
671 StateTy St = RemoveDeadBindings(S, StmtEntryNode->getState());
672 builder.generateNode(S, St, StmtEntryNode);
673 }
Ted Kremenekf84469b2008-01-18 00:41:32 +0000674
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000675 CurrentStmt = NULL;
676 StmtEntryNode = NULL;
677 Builder = NULL;
Ted Kremenekd27f8162008-01-15 23:55:06 +0000678}
679
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000680
681ExprValue GRConstants::GetValue(const StateTy& St, const LValue& LV) {
682 switch (LV.getKind()) {
683 case ExprValue::LValueDeclKind: {
684 StateTy::TreeTy* T = St.SlimFind(cast<LValueDecl>(LV).getDecl());
685 return T ? T->getValue().second : InvalidValue();
686 }
687 default:
688 assert (false && "Invalid LValue.");
Ted Kremenekca3e8572008-01-16 22:28:08 +0000689 break;
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000690 }
691
692 return InvalidValue();
693}
694
695ExprValue GRConstants::GetValue(const StateTy& St, Stmt* S) {
Ted Kremenek671c9e82008-01-24 00:50:08 +0000696 for (;;) {
697 switch (S->getStmtClass()) {
698 case Stmt::ParenExprClass:
699 S = cast<ParenExpr>(S)->getSubExpr();
700 continue;
701
702 case Stmt::DeclRefExprClass:
703 return GetValue(St, LValueDecl(cast<DeclRefExpr>(S)->getDecl()));
Ted Kremenekca3e8572008-01-16 22:28:08 +0000704
Ted Kremenek671c9e82008-01-24 00:50:08 +0000705 case Stmt::IntegerLiteralClass:
Ted Kremenekdacbb4f2008-01-24 08:20:02 +0000706 return RValue::GetRValue(ValMgr, cast<IntegerLiteral>(S));
Ted Kremenek874d63f2008-01-24 02:02:54 +0000707
708 case Stmt::ImplicitCastExprClass: {
709 ImplicitCastExpr* C = cast<ImplicitCastExpr>(S);
710 if (C->getType() == C->getSubExpr()->getType()) {
711 S = C->getSubExpr();
712 continue;
713 }
714 break;
715 }
716
717 case Stmt::CastExprClass: {
718 CastExpr* C = cast<CastExpr>(S);
719 if (C->getType() == C->getSubExpr()->getType()) {
720 S = C->getSubExpr();
721 continue;
722 }
723 break;
724 }
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000725
Ted Kremenek671c9e82008-01-24 00:50:08 +0000726 default:
727 break;
728 };
729
730 break;
731 }
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000732
Ted Kremenek5c1b9962008-01-24 19:43:37 +0000733 StateTy::TreeTy* T = St.SlimFind(S);
Ted Kremenek874d63f2008-01-24 02:02:54 +0000734
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000735 return T ? T->getValue().second : InvalidValue();
736}
737
738LValue GRConstants::GetLValue(const StateTy& St, Stmt* S) {
739 if (Expr* E = dyn_cast<Expr>(S))
740 S = E->IgnoreParens();
741
742 if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(S))
743 return LValueDecl(DR->getDecl());
744
745 return cast<LValue>(GetValue(St, S));
746}
747
748GRConstants::StateTy GRConstants::SetValue(StateTy St, Stmt* S,
Ted Kremenekdaadf452008-01-24 19:28:01 +0000749 const ExprValue& V) {
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000750
751 if (!StateCleaned) {
752 St = RemoveDeadBindings(CurrentStmt, St);
753 StateCleaned = true;
754 }
755
Ted Kremenek9ff731d2008-01-24 22:27:20 +0000756 bool isBlkExpr = false;
757
758 if (S == CurrentStmt) {
759 isBlkExpr = getCFG().isBlkExpr(S);
760
761 if (!isBlkExpr)
762 return St;
763 }
Ted Kremenekdaadf452008-01-24 19:28:01 +0000764
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000765 return V.isValid() ? StateMgr.Add(St, ValueKey(S,isBlkExpr), V)
766 : St;
767}
768
769GRConstants::StateTy GRConstants::SetValue(StateTy St, const LValue& LV,
770 const ExprValue& V) {
771 if (!LV.isValid())
772 return St;
773
774 if (!StateCleaned) {
775 St = RemoveDeadBindings(CurrentStmt, St);
776 StateCleaned = true;
Ted Kremenekca3e8572008-01-16 22:28:08 +0000777 }
Ted Kremenek0525a4f2008-01-16 19:47:19 +0000778
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000779 switch (LV.getKind()) {
780 case ExprValue::LValueDeclKind:
781 return V.isValid() ? StateMgr.Add(St, cast<LValueDecl>(LV).getDecl(), V)
782 : StateMgr.Remove(St, cast<LValueDecl>(LV).getDecl());
783
784 default:
785 assert ("SetValue for given LValue type not yet implemented.");
786 return St;
787 }
Ted Kremenekd27f8162008-01-15 23:55:06 +0000788}
789
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000790GRConstants::StateTy GRConstants::RemoveDeadBindings(Stmt* Loc, StateTy M) {
Ted Kremenek9de04c42008-01-24 20:55:43 +0000791#if 0
Ted Kremenekf84469b2008-01-18 00:41:32 +0000792 // Note: in the code below, we can assign a new map to M since the
793 // iterators are iterating over the tree of the *original* map.
Ted Kremenekf84469b2008-01-18 00:41:32 +0000794 StateTy::iterator I = M.begin(), E = M.end();
795
Ted Kremenek5c1b9962008-01-24 19:43:37 +0000796 // Remove old bindings for subexpressions and "dead" block-level expressions.
797 for (; I!=E && !I.getKey().isDecl(); ++I) {
798 if (I.getKey().isSubExpr() || !Liveness->isLive(Loc,cast<Stmt>(I.getKey())))
799 M = StateMgr.Remove(M, I.getKey());
800 }
Ted Kremenekf84469b2008-01-18 00:41:32 +0000801
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000802 // Remove bindings for "dead" decls.
Ted Kremenek5c1b9962008-01-24 19:43:37 +0000803 for (; I!=E ; ++I) {
804 assert (I.getKey().isDecl());
805
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000806 if (VarDecl* V = dyn_cast<VarDecl>(cast<ValueDecl>(I.getKey())))
807 if (!Liveness->isLive(Loc, V))
808 M = StateMgr.Remove(M, I.getKey());
Ted Kremenek5c1b9962008-01-24 19:43:37 +0000809 }
Ted Kremenek9de04c42008-01-24 20:55:43 +0000810#endif
Ted Kremeneke00fe3f2008-01-17 00:52:48 +0000811 return M;
Ted Kremeneke00fe3f2008-01-17 00:52:48 +0000812}
813
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000814void GRConstants::Nodify(NodeSet& Dst, Stmt* S, GRConstants::NodeTy* Pred,
815 GRConstants::StateTy St) {
816
817 // If the state hasn't changed, don't generate a new node.
818 if (St == Pred->getState())
819 return;
Ted Kremenekcb448ca2008-01-16 00:53:15 +0000820
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000821 Dst.Add(Builder->generateNode(S, St, Pred));
Ted Kremenekcb448ca2008-01-16 00:53:15 +0000822}
Ted Kremenekd27f8162008-01-15 23:55:06 +0000823
Ted Kremenek874d63f2008-01-24 02:02:54 +0000824void GRConstants::VisitCast(Expr* CastE, Expr* E, GRConstants::NodeTy* Pred,
825 GRConstants::NodeSet& Dst) {
826
827 QualType T = CastE->getType();
828
829 // Check for redundant casts.
830 if (E->getType() == T) {
831 Dst.Add(Pred);
832 return;
833 }
834
835 NodeSet S1;
836 Visit(E, Pred, S1);
837
838 for (NodeSet::iterator I1=S1.begin(), E1=S1.end(); I1 != E1; ++I1) {
839 NodeTy* N = *I1;
840 StateTy St = N->getState();
841 const ExprValue& V = GetValue(St, E);
842 Nodify(Dst, CastE, N, SetValue(St, CastE, V.EvalCast(ValMgr, CastE)));
843 }
Ted Kremenek9de04c42008-01-24 20:55:43 +0000844}
845
846void GRConstants::VisitDeclStmt(DeclStmt* DS, GRConstants::NodeTy* Pred,
847 GRConstants::NodeSet& Dst) {
848
849 StateTy St = Pred->getState();
850
851 for (const ScopedDecl* D = DS->getDecl(); D; D = D->getNextDeclarator())
852 if (const VarDecl* VD = dyn_cast<VarDecl>(D))
853 St = SetValue(St, LValueDecl(VD), GetValue(St, VD->getInit()));
854
855 Nodify(Dst, DS, Pred, St);
856
857 if (Dst.empty())
858 Dst.Add(Pred);
859}
Ted Kremenek874d63f2008-01-24 02:02:54 +0000860
Ted Kremenek7b8009a2008-01-24 02:28:56 +0000861void GRConstants::VisitUnaryOperator(UnaryOperator* U,
862 GRConstants::NodeTy* Pred,
863 GRConstants::NodeSet& Dst) {
864 NodeSet S1;
865 Visit(U->getSubExpr(), Pred, S1);
866
867 for (NodeSet::iterator I1=S1.begin(), E1=S1.end(); I1 != E1; ++I1) {
868 NodeTy* N1 = *I1;
869 StateTy St = N1->getState();
870
871 switch (U->getOpcode()) {
872 case UnaryOperator::PostInc: {
873 const LValue& L1 = GetLValue(St, U->getSubExpr());
874 RValue R1 = cast<RValue>(GetValue(St, L1));
875
876 QualType T = U->getType();
Ted Kremeneke0cf9c82008-01-24 19:00:57 +0000877 unsigned bits = getContext()->getTypeSize(T, U->getLocStart());
878 llvm::APSInt One(llvm::APInt(bits, 1), T->isUnsignedIntegerType());
879 RValue R2 = RValue::GetRValue(ValMgr, One);
880
Ted Kremenek7b8009a2008-01-24 02:28:56 +0000881 RValue Result = R1.EvalAdd(ValMgr, R2);
882 Nodify(Dst, U, N1, SetValue(SetValue(St, U, R1), L1, Result));
883 break;
884 }
885
886 case UnaryOperator::PostDec: {
887 const LValue& L1 = GetLValue(St, U->getSubExpr());
888 RValue R1 = cast<RValue>(GetValue(St, L1));
889
890 QualType T = U->getType();
Ted Kremeneke0cf9c82008-01-24 19:00:57 +0000891 unsigned bits = getContext()->getTypeSize(T, U->getLocStart());
892 llvm::APSInt One(llvm::APInt(bits, 1), T->isUnsignedIntegerType());
893 RValue R2 = RValue::GetRValue(ValMgr, One);
Ted Kremenek7b8009a2008-01-24 02:28:56 +0000894
895 RValue Result = R1.EvalSub(ValMgr, R2);
896 Nodify(Dst, U, N1, SetValue(SetValue(St, U, R1), L1, Result));
897 break;
898 }
899
900 case UnaryOperator::PreInc: {
901 const LValue& L1 = GetLValue(St, U->getSubExpr());
902 RValue R1 = cast<RValue>(GetValue(St, L1));
903
904 QualType T = U->getType();
Ted Kremeneke0cf9c82008-01-24 19:00:57 +0000905 unsigned bits = getContext()->getTypeSize(T, U->getLocStart());
906 llvm::APSInt One(llvm::APInt(bits, 1), T->isUnsignedIntegerType());
Ted Kremenek7b8009a2008-01-24 02:28:56 +0000907 RValue R2 = RValue::GetRValue(ValMgr, One);
908
909 RValue Result = R1.EvalAdd(ValMgr, R2);
910 Nodify(Dst, U, N1, SetValue(SetValue(St, U, Result), L1, Result));
911 break;
912 }
913
914 case UnaryOperator::PreDec: {
915 const LValue& L1 = GetLValue(St, U->getSubExpr());
916 RValue R1 = cast<RValue>(GetValue(St, L1));
917
918 QualType T = U->getType();
Ted Kremeneke0cf9c82008-01-24 19:00:57 +0000919 unsigned bits = getContext()->getTypeSize(T, U->getLocStart());
920 llvm::APSInt One(llvm::APInt(bits, 1), T->isUnsignedIntegerType());
921 RValue R2 = RValue::GetRValue(ValMgr, One);
Ted Kremenek7b8009a2008-01-24 02:28:56 +0000922
923 RValue Result = R1.EvalSub(ValMgr, R2);
924 Nodify(Dst, U, N1, SetValue(SetValue(St, U, Result), L1, Result));
925 break;
926 }
927
Ted Kremenekdacbb4f2008-01-24 08:20:02 +0000928 case UnaryOperator::Minus: {
929 const RValue& R1 = cast<RValue>(GetValue(St, U->getSubExpr()));
930 Nodify(Dst, U, N1, SetValue(St, U, R1.EvalMinus(ValMgr, U)));
931 break;
932 }
933
Ted Kremenek7b8009a2008-01-24 02:28:56 +0000934 default: ;
935 assert (false && "Not implemented.");
936 }
937 }
938}
939
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000940void GRConstants::VisitBinaryOperator(BinaryOperator* B,
941 GRConstants::NodeTy* Pred,
942 GRConstants::NodeSet& Dst) {
943 NodeSet S1;
944 Visit(B->getLHS(), Pred, S1);
Ted Kremenekcb448ca2008-01-16 00:53:15 +0000945
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000946 for (NodeSet::iterator I1=S1.begin(), E1=S1.end(); I1 != E1; ++I1) {
947 NodeTy* N1 = *I1;
Ted Kremeneke00fe3f2008-01-17 00:52:48 +0000948
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000949 // When getting the value for the LHS, check if we are in an assignment.
950 // In such cases, we want to (initially) treat the LHS as an LValue,
951 // so we use GetLValue instead of GetValue so that DeclRefExpr's are
952 // evaluated to LValueDecl's instead of to an RValue.
953 const ExprValue& V1 =
954 B->isAssignmentOp() ? GetLValue(N1->getState(), B->getLHS())
955 : GetValue(N1->getState(), B->getLHS());
Ted Kremenekcb448ca2008-01-16 00:53:15 +0000956
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000957 NodeSet S2;
958 Visit(B->getRHS(), N1, S2);
959
960 for (NodeSet::iterator I2=S2.begin(), E2=S2.end(); I2 != E2; ++I2) {
961 NodeTy* N2 = *I2;
962 StateTy St = N2->getState();
963 const ExprValue& V2 = GetValue(St, B->getRHS());
964
965 switch (B->getOpcode()) {
966 case BinaryOperator::Add: {
967 const RValue& R1 = cast<RValue>(V1);
968 const RValue& R2 = cast<RValue>(V2);
969
Ted Kremenek874d63f2008-01-24 02:02:54 +0000970 Nodify(Dst, B, N2, SetValue(St, B, R1.EvalAdd(ValMgr, R2)));
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000971 break;
972 }
973
974 case BinaryOperator::Sub: {
975 const RValue& R1 = cast<RValue>(V1);
976 const RValue& R2 = cast<RValue>(V2);
Ted Kremenek874d63f2008-01-24 02:02:54 +0000977 Nodify(Dst, B, N2, SetValue(St, B, R1.EvalSub(ValMgr, R2)));
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000978 break;
979 }
980
Ted Kremenek2eafd0e2008-01-23 23:42:27 +0000981 case BinaryOperator::Mul: {
982 const RValue& R1 = cast<RValue>(V1);
983 const RValue& R2 = cast<RValue>(V2);
Ted Kremenek874d63f2008-01-24 02:02:54 +0000984 Nodify(Dst, B, N2, SetValue(St, B, R1.EvalMul(ValMgr, R2)));
Ted Kremenek2eafd0e2008-01-23 23:42:27 +0000985 break;
986 }
987
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000988 case BinaryOperator::Assign: {
989 const LValue& L1 = cast<LValue>(V1);
990 const RValue& R2 = cast<RValue>(V2);
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000991 Nodify(Dst, B, N2, SetValue(SetValue(St, B, R2), L1, R2));
992 break;
993 }
Ted Kremenekb4ae33f2008-01-23 23:38:00 +0000994
995 case BinaryOperator::AddAssign: {
996 const LValue& L1 = cast<LValue>(V1);
997 RValue R1 = cast<RValue>(GetValue(N1->getState(), L1));
Ted Kremenek874d63f2008-01-24 02:02:54 +0000998 RValue Result = R1.EvalAdd(ValMgr, cast<RValue>(V2));
Ted Kremenekb4ae33f2008-01-23 23:38:00 +0000999 Nodify(Dst, B, N2, SetValue(SetValue(St, B, Result), L1, Result));
1000 break;
1001 }
1002
1003 case BinaryOperator::SubAssign: {
1004 const LValue& L1 = cast<LValue>(V1);
1005 RValue R1 = cast<RValue>(GetValue(N1->getState(), L1));
Ted Kremenek874d63f2008-01-24 02:02:54 +00001006 RValue Result = R1.EvalSub(ValMgr, cast<RValue>(V2));
Ted Kremenekb4ae33f2008-01-23 23:38:00 +00001007 Nodify(Dst, B, N2, SetValue(SetValue(St, B, Result), L1, Result));
1008 break;
1009 }
Ted Kremenek2eafd0e2008-01-23 23:42:27 +00001010
1011 case BinaryOperator::MulAssign: {
1012 const LValue& L1 = cast<LValue>(V1);
1013 RValue R1 = cast<RValue>(GetValue(N1->getState(), L1));
Ted Kremenek874d63f2008-01-24 02:02:54 +00001014 RValue Result = R1.EvalMul(ValMgr, cast<RValue>(V2));
Ted Kremenek2eafd0e2008-01-23 23:42:27 +00001015 Nodify(Dst, B, N2, SetValue(SetValue(St, B, Result), L1, Result));
1016 break;
1017 }
Ted Kremenekab2b8c52008-01-23 19:59:44 +00001018
1019 default:
1020 Dst.Add(N2);
1021 break;
1022 }
Ted Kremenekcb448ca2008-01-16 00:53:15 +00001023 }
Ted Kremenekd27f8162008-01-15 23:55:06 +00001024 }
Ted Kremenekd27f8162008-01-15 23:55:06 +00001025}
Ted Kremenekee985462008-01-16 18:18:48 +00001026
Ted Kremenek1ccd31c2008-01-16 19:42:59 +00001027
Ted Kremenekab2b8c52008-01-23 19:59:44 +00001028void GRConstants::Visit(Stmt* S, GRConstants::NodeTy* Pred,
1029 GRConstants::NodeSet& Dst) {
1030
1031 // FIXME: add metadata to the CFG so that we can disable
1032 // this check when we KNOW that there is no block-level subexpression.
1033 // The motivation is that this check requires a hashtable lookup.
1034
1035 if (S != CurrentStmt && getCFG().isBlkExpr(S)) {
1036 Dst.Add(Pred);
1037 return;
1038 }
1039
1040 switch (S->getStmtClass()) {
1041 case Stmt::BinaryOperatorClass:
Ted Kremenekb4ae33f2008-01-23 23:38:00 +00001042 case Stmt::CompoundAssignOperatorClass:
Ted Kremenekab2b8c52008-01-23 19:59:44 +00001043 VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Dst);
1044 break;
1045
Ted Kremenek7b8009a2008-01-24 02:28:56 +00001046 case Stmt::UnaryOperatorClass:
1047 VisitUnaryOperator(cast<UnaryOperator>(S), Pred, Dst);
1048 break;
1049
Ted Kremenekab2b8c52008-01-23 19:59:44 +00001050 case Stmt::ParenExprClass:
1051 Visit(cast<ParenExpr>(S)->getSubExpr(), Pred, Dst);
1052 break;
1053
Ted Kremenek874d63f2008-01-24 02:02:54 +00001054 case Stmt::ImplicitCastExprClass: {
1055 ImplicitCastExpr* C = cast<ImplicitCastExpr>(S);
1056 VisitCast(C, C->getSubExpr(), Pred, Dst);
1057 break;
1058 }
1059
1060 case Stmt::CastExprClass: {
1061 CastExpr* C = cast<CastExpr>(S);
1062 VisitCast(C, C->getSubExpr(), Pred, Dst);
1063 break;
1064 }
1065
Ted Kremenek9de04c42008-01-24 20:55:43 +00001066 case Stmt::DeclStmtClass:
1067 VisitDeclStmt(cast<DeclStmt>(S), Pred, Dst);
1068 break;
1069
Ted Kremenekab2b8c52008-01-23 19:59:44 +00001070 default:
1071 Dst.Add(Pred); // No-op. Simply propagate the current state unchanged.
1072 break;
Ted Kremenek79649df2008-01-17 18:25:22 +00001073 }
Ted Kremenek1ccd31c2008-01-16 19:42:59 +00001074}
1075
Ted Kremenekee985462008-01-16 18:18:48 +00001076//===----------------------------------------------------------------------===//
1077// Driver.
1078//===----------------------------------------------------------------------===//
1079
Ted Kremenekaa66a322008-01-16 21:46:15 +00001080#ifndef NDEBUG
1081namespace llvm {
1082template<>
1083struct VISIBILITY_HIDDEN DOTGraphTraits<GRConstants::NodeTy*> :
1084 public DefaultDOTGraphTraits {
Ted Kremenek9ff731d2008-01-24 22:27:20 +00001085
1086 static void PrintKindLabel(std::ostream& Out, ValueKey::Kind kind) {
Ted Kremenek803c9ed2008-01-23 22:30:44 +00001087 switch (kind) {
1088 case ValueKey::IsSubExp: Out << "Sub-Expressions:\\l"; break;
1089 case ValueKey::IsDecl: Out << "Variables:\\l"; break;
1090 case ValueKey::IsBlkExpr: Out << "Block-level Expressions:\\l"; break;
1091 default: assert (false && "Unknown ValueKey type.");
1092 }
1093 }
1094
Ted Kremenek9ff731d2008-01-24 22:27:20 +00001095 static void PrintKind(std::ostream& Out, GRConstants::StateTy M,
1096 ValueKey::Kind kind, bool isFirstGroup = false) {
1097 bool isFirst = true;
1098
1099 for (GRConstants::StateTy::iterator I=M.begin(), E=M.end();I!=E;++I) {
1100 if (I.getKey().getKind() != kind)
1101 continue;
1102
1103 if (isFirst) {
1104 if (!isFirstGroup) Out << "\\l\\l";
1105 PrintKindLabel(Out, kind);
1106 isFirst = false;
1107 }
1108 else
1109 Out << "\\l";
1110
1111 Out << ' ';
1112
1113 if (ValueDecl* V = dyn_cast<ValueDecl>(I.getKey()))
1114 Out << V->getName();
1115 else {
1116 Stmt* E = cast<Stmt>(I.getKey());
1117 Out << " (" << (void*) E << ") ";
1118 E->printPretty(Out);
1119 }
1120
1121 Out << " : ";
1122 I.getData().print(Out);
1123 }
1124 }
1125
Ted Kremenekaa66a322008-01-16 21:46:15 +00001126 static std::string getNodeLabel(const GRConstants::NodeTy* N, void*) {
1127 std::ostringstream Out;
Ted Kremenek803c9ed2008-01-23 22:30:44 +00001128
1129 // Program Location.
Ted Kremenekaa66a322008-01-16 21:46:15 +00001130 ProgramPoint Loc = N->getLocation();
1131
1132 switch (Loc.getKind()) {
1133 case ProgramPoint::BlockEntranceKind:
1134 Out << "Block Entrance: B"
1135 << cast<BlockEntrance>(Loc).getBlock()->getBlockID();
1136 break;
1137
1138 case ProgramPoint::BlockExitKind:
1139 assert (false);
1140 break;
1141
1142 case ProgramPoint::PostStmtKind: {
1143 const PostStmt& L = cast<PostStmt>(Loc);
Ted Kremenek9ff731d2008-01-24 22:27:20 +00001144 Out << L.getStmt()->getStmtClassName() << ':'
1145 << (void*) L.getStmt() << ' ';
1146
Ted Kremenekaa66a322008-01-16 21:46:15 +00001147 L.getStmt()->printPretty(Out);
1148 break;
1149 }
1150
1151 default: {
1152 const BlockEdge& E = cast<BlockEdge>(Loc);
1153 Out << "Edge: (B" << E.getSrc()->getBlockID() << ", B"
1154 << E.getDst()->getBlockID() << ')';
1155 }
1156 }
1157
Ted Kremenek803c9ed2008-01-23 22:30:44 +00001158 Out << "\\|";
Ted Kremenekaa66a322008-01-16 21:46:15 +00001159
Ted Kremenek9ff731d2008-01-24 22:27:20 +00001160 PrintKind(Out, N->getState(), ValueKey::IsDecl, true);
1161 PrintKind(Out, N->getState(), ValueKey::IsBlkExpr);
1162 PrintKind(Out, N->getState(), ValueKey::IsSubExp);
Ted Kremenek803c9ed2008-01-23 22:30:44 +00001163
Ted Kremenek803c9ed2008-01-23 22:30:44 +00001164 Out << "\\l";
Ted Kremenekaa66a322008-01-16 21:46:15 +00001165 return Out.str();
1166 }
1167};
1168} // end llvm namespace
1169#endif
1170
Ted Kremenekee985462008-01-16 18:18:48 +00001171namespace clang {
Ted Kremenek874d63f2008-01-24 02:02:54 +00001172void RunGRConstants(CFG& cfg, ASTContext& Ctx) {
1173 GREngine<GRConstants> Engine(cfg, Ctx);
Ted Kremenekee985462008-01-16 18:18:48 +00001174 Engine.ExecuteWorkList();
Ted Kremenekaa66a322008-01-16 21:46:15 +00001175#ifndef NDEBUG
1176 llvm::ViewGraph(*Engine.getGraph().roots_begin(),"GRConstants");
1177#endif
Ted Kremenekee985462008-01-16 18:18:48 +00001178}
Ted Kremenekab2b8c52008-01-23 19:59:44 +00001179} // end clang namespace