blob: cc9c54423dcf449fce6bb0acb7295f67702b4e4a [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 Kremenek565256e2008-01-24 22:44:24 +000052 enum Kind { IsSubExpr=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 Kremenek565256e2008-01-24 22:44:24 +000060 : Raw(reinterpret_cast<uintptr_t>(S) | (isBlkExpr ? IsBlkExpr : IsSubExpr)){}
Ted Kremenekd27f8162008-01-15 23:55:06 +000061
Ted Kremenek565256e2008-01-24 22:44:24 +000062 bool isSubExpr() const { return getKind() == IsSubExpr; }
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//===----------------------------------------------------------------------===//
Ted Kremenekf13794e2008-01-24 23:19:54 +0000149
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000150namespace {
151
152class VISIBILITY_HIDDEN ExprValue {
153public:
Ted Kremenekf13794e2008-01-24 23:19:54 +0000154 enum BaseKind { LValueKind=0x1, RValueKind=0x2, InvalidKind=0x0 };
155
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000156private:
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000157 void* Data;
Ted Kremenekf13794e2008-01-24 23:19:54 +0000158 unsigned Kind;
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000159
160protected:
Ted Kremenekf13794e2008-01-24 23:19:54 +0000161 ExprValue(void* d, bool isRValue, unsigned ValKind)
162 : Data(d),
163 Kind((isRValue ? RValueKind : LValueKind) | (ValKind << 2)) {}
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000164
Ted Kremenekf13794e2008-01-24 23:19:54 +0000165 ExprValue() : Data(NULL), Kind(0) {}
166
167 void* getRawPtr() const { return Data; }
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000168
169public:
170 ~ExprValue() {};
171
Ted Kremenek874d63f2008-01-24 02:02:54 +0000172 ExprValue EvalCast(ValueManager& ValMgr, Expr* CastExpr) const;
173
Ted Kremenekf13794e2008-01-24 23:19:54 +0000174 unsigned getRawKind() const { return Kind; }
175 BaseKind getBaseKind() const { return (BaseKind) (Kind & 0x3); }
176 unsigned getSubKind() const { return (Kind & ~0x3) >> 2; }
177
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000178 void Profile(llvm::FoldingSetNodeID& ID) const {
Ted Kremenekf13794e2008-01-24 23:19:54 +0000179 ID.AddInteger((unsigned) getRawKind());
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000180 ID.AddPointer(Data);
181 }
182
183 bool operator==(const ExprValue& RHS) const {
Ted Kremenekf13794e2008-01-24 23:19:54 +0000184 return getRawKind() == RHS.getRawKind() && Data == RHS.Data;
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000185 }
186
Ted Kremenekf13794e2008-01-24 23:19:54 +0000187 inline bool isValid() const { return getRawKind() != InvalidKind; }
188 inline bool isInvalid() const { return getRawKind() == InvalidKind; }
189
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000190
191 void print(std::ostream& OS) const;
192 void print() const { print(*llvm::cerr.stream()); }
193
194 // Implement isa<T> support.
195 static inline bool classof(const ExprValue*) { return true; }
196};
197
198class VISIBILITY_HIDDEN InvalidValue : public ExprValue {
199public:
Ted Kremenekf13794e2008-01-24 23:19:54 +0000200 InvalidValue() {}
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000201
202 static inline bool classof(const ExprValue* V) {
Ted Kremenekf13794e2008-01-24 23:19:54 +0000203 return V->getBaseKind() == InvalidKind;
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000204 }
205};
206
Ted Kremenekf13794e2008-01-24 23:19:54 +0000207class VISIBILITY_HIDDEN LValue : public ExprValue {
208protected:
209 LValue(unsigned SubKind, void* D) : ExprValue(D, false, SubKind) {}
210
211public:
212 // Implement isa<T> support.
213 static inline bool classof(const ExprValue* V) {
214 return V->getBaseKind() == LValueKind;
215 }
216};
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000217
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000218class VISIBILITY_HIDDEN RValue : public ExprValue {
219protected:
Ted Kremenekf13794e2008-01-24 23:19:54 +0000220 RValue(unsigned SubKind, void* d) : ExprValue(d, true, SubKind) {}
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000221
222public:
Ted Kremenekf13794e2008-01-24 23:19:54 +0000223 void print(std::ostream& Out) const;
224
Ted Kremenek874d63f2008-01-24 02:02:54 +0000225 RValue EvalAdd(ValueManager& ValMgr, const RValue& RHS) const;
226 RValue EvalSub(ValueManager& ValMgr, const RValue& RHS) const;
227 RValue EvalMul(ValueManager& ValMgr, const RValue& RHS) const;
Ted Kremenekdacbb4f2008-01-24 08:20:02 +0000228 RValue EvalMinus(ValueManager& ValMgr, UnaryOperator* U) const;
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000229
Ted Kremenek7b8009a2008-01-24 02:28:56 +0000230 static RValue GetRValue(ValueManager& ValMgr, const llvm::APSInt& V);
Ted Kremenekdacbb4f2008-01-24 08:20:02 +0000231 static RValue GetRValue(ValueManager& ValMgr, IntegerLiteral* I);
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000232
233 // Implement isa<T> support.
234 static inline bool classof(const ExprValue* V) {
Ted Kremenekf13794e2008-01-24 23:19:54 +0000235 return V->getBaseKind() == RValueKind;
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000236 }
237};
Ted Kremenekf13794e2008-01-24 23:19:54 +0000238
239} // end anonymous namespace
240
241//===----------------------------------------------------------------------===//
242// "R-Values": Interface.
243//===----------------------------------------------------------------------===//
244
245namespace {
246
247enum { RValueMayEqualSetKind = 0x0, NumRValueKind };
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000248
249class VISIBILITY_HIDDEN RValueMayEqualSet : public RValue {
250public:
251 RValueMayEqualSet(const APSIntSetTy& S)
252 : RValue(RValueMayEqualSetKind, S.getRoot()) {}
253
254 APSIntSetTy GetValues() const {
255 return APSIntSetTy(reinterpret_cast<APSIntSetTy::TreeTy*>(getRawPtr()));
256 }
257
Ted Kremenek874d63f2008-01-24 02:02:54 +0000258 RValueMayEqualSet EvalAdd(ValueManager& ValMgr,
259 const RValueMayEqualSet& V) const;
260
261 RValueMayEqualSet EvalSub(ValueManager& ValMgr,
262 const RValueMayEqualSet& V) const;
263
264 RValueMayEqualSet EvalMul(ValueManager& ValMgr,
265 const RValueMayEqualSet& V) const;
266
267 RValueMayEqualSet EvalCast(ValueManager& ValMgr, Expr* CastExpr) const;
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000268
Ted Kremenekdacbb4f2008-01-24 08:20:02 +0000269 RValueMayEqualSet EvalMinus(ValueManager& ValMgr, UnaryOperator* U) const;
270
271
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000272 // Implement isa<T> support.
273 static inline bool classof(const ExprValue* V) {
Ted Kremenekf13794e2008-01-24 23:19:54 +0000274 return V->getSubKind() == RValueMayEqualSetKind;
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000275 }
276};
277} // end anonymous namespace
278
279//===----------------------------------------------------------------------===//
Ted Kremenek874d63f2008-01-24 02:02:54 +0000280// Transfer functions: Casts.
281//===----------------------------------------------------------------------===//
282
283ExprValue ExprValue::EvalCast(ValueManager& ValMgr, Expr* CastExpr) const {
Ted Kremenekf13794e2008-01-24 23:19:54 +0000284 switch (getSubKind()) {
Ted Kremenek874d63f2008-01-24 02:02:54 +0000285 case RValueMayEqualSetKind:
286 return cast<RValueMayEqualSet>(this)->EvalCast(ValMgr, CastExpr);
287 default:
288 return InvalidValue();
289 }
290}
291
292RValueMayEqualSet
293RValueMayEqualSet::EvalCast(ValueManager& ValMgr, Expr* CastExpr) const {
294 QualType T = CastExpr->getType();
295 assert (T->isIntegerType());
296
297 APSIntSetTy S1 = GetValues();
298 APSIntSetTy S2 = ValMgr.GetEmptyAPSIntSet();
299
300 for (APSIntSetTy::iterator I=S1.begin(), E=S1.end(); I!=E; ++I) {
301 llvm::APSInt X = *I;
302 X.setIsSigned(T->isSignedIntegerType());
303 X.extOrTrunc(ValMgr.getContext()->getTypeSize(T,CastExpr->getLocStart()));
304 S2 = ValMgr.AddToSet(S2, X);
305 }
306
307 return S2;
308}
309
310//===----------------------------------------------------------------------===//
Ted Kremenekdacbb4f2008-01-24 08:20:02 +0000311// Transfer functions: Unary Operations over R-Values.
312//===----------------------------------------------------------------------===//
313
314RValue RValue::EvalMinus(ValueManager& ValMgr, UnaryOperator* U) const {
Ted Kremenekf13794e2008-01-24 23:19:54 +0000315 switch (getSubKind()) {
Ted Kremenekdacbb4f2008-01-24 08:20:02 +0000316 case RValueMayEqualSetKind:
317 return cast<RValueMayEqualSet>(this)->EvalMinus(ValMgr, U);
318 default:
319 return cast<RValue>(InvalidValue());
320 }
321}
322
323RValueMayEqualSet
324RValueMayEqualSet::EvalMinus(ValueManager& ValMgr, UnaryOperator* U) const {
325
326 assert (U->getType() == U->getSubExpr()->getType());
327 assert (U->getType()->isIntegerType());
328
329 APSIntSetTy S1 = GetValues();
330 APSIntSetTy S2 = ValMgr.GetEmptyAPSIntSet();
331
332 for (APSIntSetTy::iterator I=S1.begin(), E=S1.end(); I!=E; ++I) {
333 assert ((*I).isSigned());
334
335 // FIXME: Shouldn't operator- on APSInt return an APSInt with the proper
336 // sign?
337 llvm::APSInt X(-(*I));
338 X.setIsSigned(true);
339
340 S2 = ValMgr.AddToSet(S2, X);
341 }
342
343 return S2;
344}
345
346
347
348//===----------------------------------------------------------------------===//
Ted Kremenek874d63f2008-01-24 02:02:54 +0000349// Transfer functions: Binary Operations over R-Values.
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000350//===----------------------------------------------------------------------===//
351
352#define RVALUE_DISPATCH_CASE(k1,k2,Op)\
Ted Kremenekf13794e2008-01-24 23:19:54 +0000353case (k1##Kind*NumRValueKind+k2##Kind):\
Ted Kremenek874d63f2008-01-24 02:02:54 +0000354 return cast<k1>(*this).Eval##Op(ValMgr,cast<k2>(RHS));
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000355
356#define RVALUE_DISPATCH(Op)\
Ted Kremenekf13794e2008-01-24 23:19:54 +0000357switch (getSubKind()*NumRValueKind+RHS.getSubKind()){\
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000358 RVALUE_DISPATCH_CASE(RValueMayEqualSet,RValueMayEqualSet,Op)\
359 default:\
360 assert (!isValid() || !RHS.isValid() && "Missing case.");\
361 break;\
362}\
363return cast<RValue>(InvalidValue());
364
Ted Kremenek874d63f2008-01-24 02:02:54 +0000365RValue RValue::EvalAdd(ValueManager& ValMgr, const RValue& RHS) const {
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000366 RVALUE_DISPATCH(Add)
367}
368
Ted Kremenek874d63f2008-01-24 02:02:54 +0000369RValue RValue::EvalSub(ValueManager& ValMgr, const RValue& RHS) const {
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000370 RVALUE_DISPATCH(Sub)
371}
372
Ted Kremenek874d63f2008-01-24 02:02:54 +0000373RValue RValue::EvalMul(ValueManager& ValMgr, const RValue& RHS) const {
Ted Kremenek2eafd0e2008-01-23 23:42:27 +0000374 RVALUE_DISPATCH(Mul)
375}
376
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000377#undef RVALUE_DISPATCH_CASE
378#undef RVALUE_DISPATCH
379
380RValueMayEqualSet
Ted Kremenek874d63f2008-01-24 02:02:54 +0000381RValueMayEqualSet::EvalAdd(ValueManager& ValMgr,
382 const RValueMayEqualSet& RHS) const {
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000383
384 APSIntSetTy S1 = GetValues();
385 APSIntSetTy S2 = RHS.GetValues();
386
387 APSIntSetTy M = ValMgr.GetEmptyAPSIntSet();
388
389 for (APSIntSetTy::iterator I1=S1.begin(), E1=S2.end(); I1!=E1; ++I1)
Ted Kremenekdacbb4f2008-01-24 08:20:02 +0000390 for (APSIntSetTy::iterator I2=S2.begin(), E2=S2.end(); I2!=E2; ++I2) {
391 // FIXME: operator- on APSInt is really operator* on APInt, which loses
392 // the "signess" information (although the bits are correct).
393 const llvm::APSInt& X = *I1;
394 llvm::APSInt Y = X + *I2;
395 Y.setIsSigned(X.isSigned());
396 M = ValMgr.AddToSet(M, Y);
397 }
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000398
399 return M;
400}
401
402RValueMayEqualSet
Ted Kremenek874d63f2008-01-24 02:02:54 +0000403RValueMayEqualSet::EvalSub(ValueManager& ValMgr,
404 const RValueMayEqualSet& RHS) const {
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000405
406 APSIntSetTy S1 = GetValues();
407 APSIntSetTy S2 = RHS.GetValues();
408
409 APSIntSetTy M = ValMgr.GetEmptyAPSIntSet();
410
411 for (APSIntSetTy::iterator I1=S1.begin(), E1=S2.end(); I1!=E1; ++I1)
Ted Kremenekdacbb4f2008-01-24 08:20:02 +0000412 for (APSIntSetTy::iterator I2=S2.begin(), E2=S2.end(); I2!=E2; ++I2) {
413 // FIXME: operator- on APSInt is really operator* on APInt, which loses
414 // the "signess" information (although the bits are correct).
415 const llvm::APSInt& X = *I1;
416 llvm::APSInt Y = X - *I2;
417 Y.setIsSigned(X.isSigned());
418 M = ValMgr.AddToSet(M, Y);
419 }
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000420
421 return M;
422}
423
Ted Kremenek2eafd0e2008-01-23 23:42:27 +0000424RValueMayEqualSet
Ted Kremenek874d63f2008-01-24 02:02:54 +0000425RValueMayEqualSet::EvalMul(ValueManager& ValMgr,
426 const RValueMayEqualSet& RHS) const {
Ted Kremenek2eafd0e2008-01-23 23:42:27 +0000427
428 APSIntSetTy S1 = GetValues();
429 APSIntSetTy S2 = RHS.GetValues();
430
431 APSIntSetTy M = ValMgr.GetEmptyAPSIntSet();
432
433 for (APSIntSetTy::iterator I1=S1.begin(), E1=S2.end(); I1!=E1; ++I1)
Ted Kremenekdacbb4f2008-01-24 08:20:02 +0000434 for (APSIntSetTy::iterator I2=S2.begin(), E2=S2.end(); I2!=E2; ++I2) {
435 // FIXME: operator* on APSInt is really operator* on APInt, which loses
436 // the "signess" information (although the bits are correct).
437 const llvm::APSInt& X = *I1;
438 llvm::APSInt Y = X * *I2;
439 Y.setIsSigned(X.isSigned());
440 M = ValMgr.AddToSet(M, Y);
441 }
Ted Kremenek2eafd0e2008-01-23 23:42:27 +0000442
443 return M;
444}
445
Ted Kremenek7b8009a2008-01-24 02:28:56 +0000446RValue RValue::GetRValue(ValueManager& ValMgr, const llvm::APSInt& V) {
447 return RValueMayEqualSet(ValMgr.AddToSet(ValMgr.GetEmptyAPSIntSet(), V));
Ted Kremenekdacbb4f2008-01-24 08:20:02 +0000448}
449
450RValue RValue::GetRValue(ValueManager& ValMgr, IntegerLiteral* I) {
451 llvm::APSInt X(I->getValue());
452 X.setIsSigned(I->getType()->isSignedIntegerType());
453 return GetRValue(ValMgr, X);
454}
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000455
456//===----------------------------------------------------------------------===//
457// "L-Values".
458//===----------------------------------------------------------------------===//
459
460namespace {
Ted Kremenekf13794e2008-01-24 23:19:54 +0000461
462enum { LValueDeclKind=0x0, MaxLValueKind };
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000463
464class VISIBILITY_HIDDEN LValueDecl : public LValue {
465public:
Ted Kremenek9de04c42008-01-24 20:55:43 +0000466 LValueDecl(const ValueDecl* vd)
467 : LValue(LValueDeclKind,const_cast<ValueDecl*>(vd)) {}
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000468
469 ValueDecl* getDecl() const {
470 return static_cast<ValueDecl*>(getRawPtr());
471 }
472
473 // Implement isa<T> support.
474 static inline bool classof(const ExprValue* V) {
Ted Kremenekf13794e2008-01-24 23:19:54 +0000475 return V->getSubKind() == LValueDeclKind;
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000476 }
477};
478} // end anonymous namespace
479
480//===----------------------------------------------------------------------===//
481// Pretty-Printing.
482//===----------------------------------------------------------------------===//
483
484void ExprValue::print(std::ostream& Out) const {
Ted Kremenekf13794e2008-01-24 23:19:54 +0000485 switch (getBaseKind()) {
486 case InvalidKind:
487 Out << "Invalid";
488 break;
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000489
Ted Kremenekf13794e2008-01-24 23:19:54 +0000490 case RValueKind:
491 cast<RValue>(this)->print(Out);
492 break;
493
494 case LValueKind:
495 assert (false && "FIXME: LValue printing not implemented.");
496 break;
497
498 default:
499 assert (false && "Invalid ExprValue.");
500 }
501}
502
503void RValue::print(std::ostream& Out) const {
504 switch (getSubKind()) {
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000505 case RValueMayEqualSetKind: {
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000506 APSIntSetTy S = cast<RValueMayEqualSet>(this)->GetValues();
Ted Kremenek803c9ed2008-01-23 22:30:44 +0000507 bool first = true;
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000508
Ted Kremenek803c9ed2008-01-23 22:30:44 +0000509 for (APSIntSetTy::iterator I=S.begin(), E=S.end(); I!=E; ++I) {
510 if (first) first = false;
511 else Out << " | ";
512
513 Out << (*I).toString();
514 }
515
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000516 break;
517 }
518
519 default:
Ted Kremenekf13794e2008-01-24 23:19:54 +0000520 assert (false && "Pretty-printed not implemented for this RValue.");
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000521 break;
522 }
523}
524
525//===----------------------------------------------------------------------===//
526// ValueMapTy - A ImmutableMap type Stmt*/Decl* to ExprValues.
527//===----------------------------------------------------------------------===//
528
529typedef llvm::ImmutableMap<ValueKey,ExprValue> ValueMapTy;
530
531namespace clang {
532 template<>
533 struct VISIBILITY_HIDDEN GRTrait<ValueMapTy> {
534 static inline void* toPtr(ValueMapTy M) {
535 return reinterpret_cast<void*>(M.getRoot());
536 }
537 static inline ValueMapTy toState(void* P) {
538 return ValueMapTy(static_cast<ValueMapTy::TreeTy*>(P));
539 }
540 };
Ted Kremenekd27f8162008-01-15 23:55:06 +0000541}
542
543//===----------------------------------------------------------------------===//
544// The Checker!
545//===----------------------------------------------------------------------===//
546
547namespace {
Ted Kremenekd27f8162008-01-15 23:55:06 +0000548
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000549class VISIBILITY_HIDDEN GRConstants {
Ted Kremenekd27f8162008-01-15 23:55:06 +0000550
551public:
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000552 typedef ValueMapTy StateTy;
Ted Kremenekd27f8162008-01-15 23:55:06 +0000553 typedef GRNodeBuilder<GRConstants> NodeBuilder;
554 typedef ExplodedNode<StateTy> NodeTy;
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000555
556 class NodeSet {
557 typedef llvm::SmallVector<NodeTy*,3> ImplTy;
558 ImplTy Impl;
559 public:
560
561 NodeSet() {}
562 NodeSet(NodeTy* N) { assert (N && !N->isInfeasible()); Impl.push_back(N); }
563
564 void Add(NodeTy* N) { if (N && !N->isInfeasible()) Impl.push_back(N); }
565
566 typedef ImplTy::iterator iterator;
567 typedef ImplTy::const_iterator const_iterator;
568
569 unsigned size() const { return Impl.size(); }
Ted Kremenek9de04c42008-01-24 20:55:43 +0000570 bool empty() const { return Impl.empty(); }
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000571
572 iterator begin() { return Impl.begin(); }
573 iterator end() { return Impl.end(); }
574
575 const_iterator begin() const { return Impl.begin(); }
576 const_iterator end() const { return Impl.end(); }
577 };
Ted Kremenekd27f8162008-01-15 23:55:06 +0000578
579protected:
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000580 /// Liveness - live-variables information the ValueDecl* and block-level
581 /// Expr* in the CFG. Used to prune out dead state.
Ted Kremenekd27f8162008-01-15 23:55:06 +0000582 LiveVariables* Liveness;
583
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000584 /// Builder - The current GRNodeBuilder which is used when building the nodes
585 /// for a given statement.
Ted Kremenekd27f8162008-01-15 23:55:06 +0000586 NodeBuilder* Builder;
587
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000588 /// StateMgr - Object that manages the data for all created states.
589 ValueMapTy::Factory StateMgr;
Ted Kremenekd27f8162008-01-15 23:55:06 +0000590
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000591 /// ValueMgr - Object that manages the data for all created ExprValues.
592 ValueManager ValMgr;
593
594 /// cfg - the current CFG.
Ted Kremenekd27f8162008-01-15 23:55:06 +0000595 CFG* cfg;
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000596
597 /// StmtEntryNode - The immediate predecessor node.
598 NodeTy* StmtEntryNode;
599
600 /// CurrentStmt - The current block-level statement.
601 Stmt* CurrentStmt;
602
603 bool StateCleaned;
Ted Kremenekd27f8162008-01-15 23:55:06 +0000604
Ted Kremenek7b8009a2008-01-24 02:28:56 +0000605 ASTContext* getContext() const { return ValMgr.getContext(); }
606
Ted Kremenekd27f8162008-01-15 23:55:06 +0000607public:
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000608 GRConstants() : Liveness(NULL), Builder(NULL), cfg(NULL),
609 StmtEntryNode(NULL), CurrentStmt(NULL) {}
Ted Kremenekd27f8162008-01-15 23:55:06 +0000610
611 ~GRConstants() { delete Liveness; }
612
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000613 /// getCFG - Returns the CFG associated with this analysis.
Ted Kremenekd27f8162008-01-15 23:55:06 +0000614 CFG& getCFG() { assert (cfg); return *cfg; }
615
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000616 /// Initialize - Initialize the checker's state based on the specified
617 /// CFG. This results in liveness information being computed for
618 /// each block-level statement in the CFG.
Ted Kremenek874d63f2008-01-24 02:02:54 +0000619 void Initialize(CFG& c, ASTContext& ctx) {
620 cfg = &c;
621 ValMgr.setContext(&ctx);
Ted Kremenekd27f8162008-01-15 23:55:06 +0000622 Liveness = new LiveVariables(c);
623 Liveness->runOnCFG(c);
Ted Kremenek79649df2008-01-17 18:25:22 +0000624 Liveness->runOnAllBlocks(c, NULL, true);
Ted Kremenekd27f8162008-01-15 23:55:06 +0000625 }
626
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000627 /// getInitialState - Return the initial state used for the root vertex
628 /// in the ExplodedGraph.
Ted Kremenekd27f8162008-01-15 23:55:06 +0000629 StateTy getInitialState() {
Ted Kremenekcb448ca2008-01-16 00:53:15 +0000630 return StateMgr.GetEmptyMap();
Ted Kremenekd27f8162008-01-15 23:55:06 +0000631 }
Ted Kremenekd27f8162008-01-15 23:55:06 +0000632
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000633 /// ProcessStmt - Called by GREngine. Used to generate new successor
634 /// nodes by processing the 'effects' of a block-level statement.
635 void ProcessStmt(Stmt* S, NodeBuilder& builder);
636
637 /// RemoveDeadBindings - Return a new state that is the same as 'M' except
638 /// that all subexpression mappings are removed and that any
639 /// block-level expressions that are not live at 'S' also have their
640 /// mappings removed.
641 StateTy RemoveDeadBindings(Stmt* S, StateTy M);
642
Ted Kremenek9de04c42008-01-24 20:55:43 +0000643 StateTy SetValue(StateTy St, Stmt* S, const ExprValue& V);
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000644
Ted Kremenek9de04c42008-01-24 20:55:43 +0000645 StateTy SetValue(StateTy St, const Stmt* S, const ExprValue& V) {
646 return SetValue(St, const_cast<Stmt*>(S), V);
647 }
648
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000649 StateTy SetValue(StateTy St, const LValue& LV, const ExprValue& V);
Ted Kremenek1ccd31c2008-01-16 19:42:59 +0000650
Ted Kremenek9de04c42008-01-24 20:55:43 +0000651 ExprValue GetValue(const StateTy& St, Stmt* S);
652 inline ExprValue GetValue(const StateTy& St, const Stmt* S) {
653 return GetValue(St, const_cast<Stmt*>(S));
654 }
655
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000656 ExprValue GetValue(const StateTy& St, const LValue& LV);
657 LValue GetLValue(const StateTy& St, Stmt* S);
Ted Kremenekd27f8162008-01-15 23:55:06 +0000658
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000659 void Nodify(NodeSet& Dst, Stmt* S, NodeTy* Pred, StateTy St);
Ted Kremenekd27f8162008-01-15 23:55:06 +0000660
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000661 /// Visit - Transfer function logic for all statements. Dispatches to
662 /// other functions that handle specific kinds of statements.
663 void Visit(Stmt* S, NodeTy* Pred, NodeSet& Dst);
Ted Kremenek874d63f2008-01-24 02:02:54 +0000664
665 /// VisitCast - Transfer function logic for all casts (implicit and explicit).
666 void VisitCast(Expr* CastE, Expr* E, NodeTy* Pred, NodeSet& Dst);
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000667
Ted Kremenek7b8009a2008-01-24 02:28:56 +0000668 /// VisitUnaryOperator - Transfer function logic for unary operators.
669 void VisitUnaryOperator(UnaryOperator* B, NodeTy* Pred, NodeSet& Dst);
670
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000671 /// VisitBinaryOperator - Transfer function logic for binary operators.
Ted Kremenek9de04c42008-01-24 20:55:43 +0000672 void VisitBinaryOperator(BinaryOperator* B, NodeTy* Pred, NodeSet& Dst);
673
674 /// VisitDeclStmt - Transfer function logic for DeclStmts.
675 void VisitDeclStmt(DeclStmt* DS, NodeTy* Pred, NodeSet& Dst);
Ted Kremenekd27f8162008-01-15 23:55:06 +0000676};
677} // end anonymous namespace
678
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000679
Ted Kremenekd27f8162008-01-15 23:55:06 +0000680void GRConstants::ProcessStmt(Stmt* S, NodeBuilder& builder) {
681 Builder = &builder;
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000682
683 StmtEntryNode = builder.getLastNode();
684 CurrentStmt = S;
685 NodeSet Dst;
686 StateCleaned = false;
687
688 Visit(S, StmtEntryNode, Dst);
689
690 // If no nodes were generated, generate a new node that has all the
691 // dead mappings removed.
692 if (Dst.size() == 1 && *Dst.begin() == StmtEntryNode) {
693 StateTy St = RemoveDeadBindings(S, StmtEntryNode->getState());
694 builder.generateNode(S, St, StmtEntryNode);
695 }
Ted Kremenekf84469b2008-01-18 00:41:32 +0000696
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000697 CurrentStmt = NULL;
698 StmtEntryNode = NULL;
699 Builder = NULL;
Ted Kremenekd27f8162008-01-15 23:55:06 +0000700}
701
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000702
703ExprValue GRConstants::GetValue(const StateTy& St, const LValue& LV) {
Ted Kremenekf13794e2008-01-24 23:19:54 +0000704 switch (LV.getSubKind()) {
705 case LValueDeclKind: {
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000706 StateTy::TreeTy* T = St.SlimFind(cast<LValueDecl>(LV).getDecl());
707 return T ? T->getValue().second : InvalidValue();
708 }
709 default:
710 assert (false && "Invalid LValue.");
Ted Kremenekca3e8572008-01-16 22:28:08 +0000711 break;
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000712 }
713
714 return InvalidValue();
715}
716
717ExprValue GRConstants::GetValue(const StateTy& St, Stmt* S) {
Ted Kremenek671c9e82008-01-24 00:50:08 +0000718 for (;;) {
719 switch (S->getStmtClass()) {
720 case Stmt::ParenExprClass:
721 S = cast<ParenExpr>(S)->getSubExpr();
722 continue;
723
724 case Stmt::DeclRefExprClass:
725 return GetValue(St, LValueDecl(cast<DeclRefExpr>(S)->getDecl()));
Ted Kremenekca3e8572008-01-16 22:28:08 +0000726
Ted Kremenek671c9e82008-01-24 00:50:08 +0000727 case Stmt::IntegerLiteralClass:
Ted Kremenekdacbb4f2008-01-24 08:20:02 +0000728 return RValue::GetRValue(ValMgr, cast<IntegerLiteral>(S));
Ted Kremenek874d63f2008-01-24 02:02:54 +0000729
730 case Stmt::ImplicitCastExprClass: {
731 ImplicitCastExpr* C = cast<ImplicitCastExpr>(S);
732 if (C->getType() == C->getSubExpr()->getType()) {
733 S = C->getSubExpr();
734 continue;
735 }
736 break;
737 }
738
739 case Stmt::CastExprClass: {
740 CastExpr* C = cast<CastExpr>(S);
741 if (C->getType() == C->getSubExpr()->getType()) {
742 S = C->getSubExpr();
743 continue;
744 }
745 break;
746 }
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000747
Ted Kremenek671c9e82008-01-24 00:50:08 +0000748 default:
749 break;
750 };
751
752 break;
753 }
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000754
Ted Kremenek5c1b9962008-01-24 19:43:37 +0000755 StateTy::TreeTy* T = St.SlimFind(S);
Ted Kremenek874d63f2008-01-24 02:02:54 +0000756
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000757 return T ? T->getValue().second : InvalidValue();
758}
759
760LValue GRConstants::GetLValue(const StateTy& St, Stmt* S) {
761 if (Expr* E = dyn_cast<Expr>(S))
762 S = E->IgnoreParens();
763
764 if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(S))
765 return LValueDecl(DR->getDecl());
766
767 return cast<LValue>(GetValue(St, S));
768}
769
770GRConstants::StateTy GRConstants::SetValue(StateTy St, Stmt* S,
Ted Kremenekdaadf452008-01-24 19:28:01 +0000771 const ExprValue& V) {
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000772
773 if (!StateCleaned) {
774 St = RemoveDeadBindings(CurrentStmt, St);
775 StateCleaned = true;
776 }
777
Ted Kremenek9ff731d2008-01-24 22:27:20 +0000778 bool isBlkExpr = false;
779
780 if (S == CurrentStmt) {
781 isBlkExpr = getCFG().isBlkExpr(S);
782
783 if (!isBlkExpr)
784 return St;
785 }
Ted Kremenekdaadf452008-01-24 19:28:01 +0000786
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000787 return V.isValid() ? StateMgr.Add(St, ValueKey(S,isBlkExpr), V)
788 : St;
789}
790
791GRConstants::StateTy GRConstants::SetValue(StateTy St, const LValue& LV,
792 const ExprValue& V) {
793 if (!LV.isValid())
794 return St;
795
796 if (!StateCleaned) {
797 St = RemoveDeadBindings(CurrentStmt, St);
798 StateCleaned = true;
Ted Kremenekca3e8572008-01-16 22:28:08 +0000799 }
Ted Kremenek0525a4f2008-01-16 19:47:19 +0000800
Ted Kremenekf13794e2008-01-24 23:19:54 +0000801 switch (LV.getSubKind()) {
802 case LValueDeclKind:
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000803 return V.isValid() ? StateMgr.Add(St, cast<LValueDecl>(LV).getDecl(), V)
804 : StateMgr.Remove(St, cast<LValueDecl>(LV).getDecl());
805
806 default:
807 assert ("SetValue for given LValue type not yet implemented.");
808 return St;
809 }
Ted Kremenekd27f8162008-01-15 23:55:06 +0000810}
811
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000812GRConstants::StateTy GRConstants::RemoveDeadBindings(Stmt* Loc, StateTy M) {
Ted Kremenekf84469b2008-01-18 00:41:32 +0000813 // Note: in the code below, we can assign a new map to M since the
814 // iterators are iterating over the tree of the *original* map.
Ted Kremenekf84469b2008-01-18 00:41:32 +0000815 StateTy::iterator I = M.begin(), E = M.end();
816
Ted Kremenek5c1b9962008-01-24 19:43:37 +0000817 // Remove old bindings for subexpressions and "dead" block-level expressions.
818 for (; I!=E && !I.getKey().isDecl(); ++I) {
819 if (I.getKey().isSubExpr() || !Liveness->isLive(Loc,cast<Stmt>(I.getKey())))
820 M = StateMgr.Remove(M, I.getKey());
821 }
Ted Kremenekf84469b2008-01-18 00:41:32 +0000822
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000823 // Remove bindings for "dead" decls.
Ted Kremenek5c1b9962008-01-24 19:43:37 +0000824 for (; I!=E ; ++I) {
825 assert (I.getKey().isDecl());
826
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000827 if (VarDecl* V = dyn_cast<VarDecl>(cast<ValueDecl>(I.getKey())))
828 if (!Liveness->isLive(Loc, V))
829 M = StateMgr.Remove(M, I.getKey());
Ted Kremenek5c1b9962008-01-24 19:43:37 +0000830 }
Ted Kremenek565256e2008-01-24 22:44:24 +0000831
Ted Kremeneke00fe3f2008-01-17 00:52:48 +0000832 return M;
Ted Kremeneke00fe3f2008-01-17 00:52:48 +0000833}
834
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000835void GRConstants::Nodify(NodeSet& Dst, Stmt* S, GRConstants::NodeTy* Pred,
836 GRConstants::StateTy St) {
837
838 // If the state hasn't changed, don't generate a new node.
839 if (St == Pred->getState())
840 return;
Ted Kremenekcb448ca2008-01-16 00:53:15 +0000841
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000842 Dst.Add(Builder->generateNode(S, St, Pred));
Ted Kremenekcb448ca2008-01-16 00:53:15 +0000843}
Ted Kremenekd27f8162008-01-15 23:55:06 +0000844
Ted Kremenek874d63f2008-01-24 02:02:54 +0000845void GRConstants::VisitCast(Expr* CastE, Expr* E, GRConstants::NodeTy* Pred,
846 GRConstants::NodeSet& Dst) {
847
848 QualType T = CastE->getType();
849
850 // Check for redundant casts.
851 if (E->getType() == T) {
852 Dst.Add(Pred);
853 return;
854 }
855
856 NodeSet S1;
857 Visit(E, Pred, S1);
858
859 for (NodeSet::iterator I1=S1.begin(), E1=S1.end(); I1 != E1; ++I1) {
860 NodeTy* N = *I1;
861 StateTy St = N->getState();
862 const ExprValue& V = GetValue(St, E);
863 Nodify(Dst, CastE, N, SetValue(St, CastE, V.EvalCast(ValMgr, CastE)));
864 }
Ted Kremenek9de04c42008-01-24 20:55:43 +0000865}
866
867void GRConstants::VisitDeclStmt(DeclStmt* DS, GRConstants::NodeTy* Pred,
868 GRConstants::NodeSet& Dst) {
869
870 StateTy St = Pred->getState();
871
872 for (const ScopedDecl* D = DS->getDecl(); D; D = D->getNextDeclarator())
873 if (const VarDecl* VD = dyn_cast<VarDecl>(D))
874 St = SetValue(St, LValueDecl(VD), GetValue(St, VD->getInit()));
875
876 Nodify(Dst, DS, Pred, St);
877
878 if (Dst.empty())
879 Dst.Add(Pred);
880}
Ted Kremenek874d63f2008-01-24 02:02:54 +0000881
Ted Kremenek7b8009a2008-01-24 02:28:56 +0000882void GRConstants::VisitUnaryOperator(UnaryOperator* U,
883 GRConstants::NodeTy* Pred,
884 GRConstants::NodeSet& Dst) {
885 NodeSet S1;
886 Visit(U->getSubExpr(), Pred, S1);
887
888 for (NodeSet::iterator I1=S1.begin(), E1=S1.end(); I1 != E1; ++I1) {
889 NodeTy* N1 = *I1;
890 StateTy St = N1->getState();
891
892 switch (U->getOpcode()) {
893 case UnaryOperator::PostInc: {
894 const LValue& L1 = GetLValue(St, U->getSubExpr());
895 RValue R1 = cast<RValue>(GetValue(St, L1));
896
897 QualType T = U->getType();
Ted Kremeneke0cf9c82008-01-24 19:00:57 +0000898 unsigned bits = getContext()->getTypeSize(T, U->getLocStart());
899 llvm::APSInt One(llvm::APInt(bits, 1), T->isUnsignedIntegerType());
900 RValue R2 = RValue::GetRValue(ValMgr, One);
901
Ted Kremenek7b8009a2008-01-24 02:28:56 +0000902 RValue Result = R1.EvalAdd(ValMgr, R2);
903 Nodify(Dst, U, N1, SetValue(SetValue(St, U, R1), L1, Result));
904 break;
905 }
906
907 case UnaryOperator::PostDec: {
908 const LValue& L1 = GetLValue(St, U->getSubExpr());
909 RValue R1 = cast<RValue>(GetValue(St, L1));
910
911 QualType T = U->getType();
Ted Kremeneke0cf9c82008-01-24 19:00:57 +0000912 unsigned bits = getContext()->getTypeSize(T, U->getLocStart());
913 llvm::APSInt One(llvm::APInt(bits, 1), T->isUnsignedIntegerType());
914 RValue R2 = RValue::GetRValue(ValMgr, One);
Ted Kremenek7b8009a2008-01-24 02:28:56 +0000915
916 RValue Result = R1.EvalSub(ValMgr, R2);
917 Nodify(Dst, U, N1, SetValue(SetValue(St, U, R1), L1, Result));
918 break;
919 }
920
921 case UnaryOperator::PreInc: {
922 const LValue& L1 = GetLValue(St, U->getSubExpr());
923 RValue R1 = cast<RValue>(GetValue(St, L1));
924
925 QualType T = U->getType();
Ted Kremeneke0cf9c82008-01-24 19:00:57 +0000926 unsigned bits = getContext()->getTypeSize(T, U->getLocStart());
927 llvm::APSInt One(llvm::APInt(bits, 1), T->isUnsignedIntegerType());
Ted Kremenek7b8009a2008-01-24 02:28:56 +0000928 RValue R2 = RValue::GetRValue(ValMgr, One);
929
930 RValue Result = R1.EvalAdd(ValMgr, R2);
931 Nodify(Dst, U, N1, SetValue(SetValue(St, U, Result), L1, Result));
932 break;
933 }
934
935 case UnaryOperator::PreDec: {
936 const LValue& L1 = GetLValue(St, U->getSubExpr());
937 RValue R1 = cast<RValue>(GetValue(St, L1));
938
939 QualType T = U->getType();
Ted Kremeneke0cf9c82008-01-24 19:00:57 +0000940 unsigned bits = getContext()->getTypeSize(T, U->getLocStart());
941 llvm::APSInt One(llvm::APInt(bits, 1), T->isUnsignedIntegerType());
942 RValue R2 = RValue::GetRValue(ValMgr, One);
Ted Kremenek7b8009a2008-01-24 02:28:56 +0000943
944 RValue Result = R1.EvalSub(ValMgr, R2);
945 Nodify(Dst, U, N1, SetValue(SetValue(St, U, Result), L1, Result));
946 break;
947 }
948
Ted Kremenekdacbb4f2008-01-24 08:20:02 +0000949 case UnaryOperator::Minus: {
950 const RValue& R1 = cast<RValue>(GetValue(St, U->getSubExpr()));
951 Nodify(Dst, U, N1, SetValue(St, U, R1.EvalMinus(ValMgr, U)));
952 break;
953 }
954
Ted Kremenek7b8009a2008-01-24 02:28:56 +0000955 default: ;
956 assert (false && "Not implemented.");
957 }
958 }
959}
960
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000961void GRConstants::VisitBinaryOperator(BinaryOperator* B,
962 GRConstants::NodeTy* Pred,
963 GRConstants::NodeSet& Dst) {
964 NodeSet S1;
965 Visit(B->getLHS(), Pred, S1);
Ted Kremenekcb448ca2008-01-16 00:53:15 +0000966
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000967 for (NodeSet::iterator I1=S1.begin(), E1=S1.end(); I1 != E1; ++I1) {
968 NodeTy* N1 = *I1;
Ted Kremeneke00fe3f2008-01-17 00:52:48 +0000969
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000970 // When getting the value for the LHS, check if we are in an assignment.
971 // In such cases, we want to (initially) treat the LHS as an LValue,
972 // so we use GetLValue instead of GetValue so that DeclRefExpr's are
973 // evaluated to LValueDecl's instead of to an RValue.
974 const ExprValue& V1 =
975 B->isAssignmentOp() ? GetLValue(N1->getState(), B->getLHS())
976 : GetValue(N1->getState(), B->getLHS());
Ted Kremenekcb448ca2008-01-16 00:53:15 +0000977
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000978 NodeSet S2;
979 Visit(B->getRHS(), N1, S2);
980
981 for (NodeSet::iterator I2=S2.begin(), E2=S2.end(); I2 != E2; ++I2) {
982 NodeTy* N2 = *I2;
983 StateTy St = N2->getState();
984 const ExprValue& V2 = GetValue(St, B->getRHS());
985
986 switch (B->getOpcode()) {
987 case BinaryOperator::Add: {
988 const RValue& R1 = cast<RValue>(V1);
989 const RValue& R2 = cast<RValue>(V2);
990
Ted Kremenek874d63f2008-01-24 02:02:54 +0000991 Nodify(Dst, B, N2, SetValue(St, B, R1.EvalAdd(ValMgr, R2)));
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000992 break;
993 }
994
995 case BinaryOperator::Sub: {
996 const RValue& R1 = cast<RValue>(V1);
997 const RValue& R2 = cast<RValue>(V2);
Ted Kremenek874d63f2008-01-24 02:02:54 +0000998 Nodify(Dst, B, N2, SetValue(St, B, R1.EvalSub(ValMgr, R2)));
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000999 break;
1000 }
1001
Ted Kremenek2eafd0e2008-01-23 23:42:27 +00001002 case BinaryOperator::Mul: {
1003 const RValue& R1 = cast<RValue>(V1);
1004 const RValue& R2 = cast<RValue>(V2);
Ted Kremenek874d63f2008-01-24 02:02:54 +00001005 Nodify(Dst, B, N2, SetValue(St, B, R1.EvalMul(ValMgr, R2)));
Ted Kremenek2eafd0e2008-01-23 23:42:27 +00001006 break;
1007 }
1008
Ted Kremenekab2b8c52008-01-23 19:59:44 +00001009 case BinaryOperator::Assign: {
1010 const LValue& L1 = cast<LValue>(V1);
1011 const RValue& R2 = cast<RValue>(V2);
Ted Kremenekab2b8c52008-01-23 19:59:44 +00001012 Nodify(Dst, B, N2, SetValue(SetValue(St, B, R2), L1, R2));
1013 break;
1014 }
Ted Kremenekb4ae33f2008-01-23 23:38:00 +00001015
1016 case BinaryOperator::AddAssign: {
1017 const LValue& L1 = cast<LValue>(V1);
1018 RValue R1 = cast<RValue>(GetValue(N1->getState(), L1));
Ted Kremenek874d63f2008-01-24 02:02:54 +00001019 RValue Result = R1.EvalAdd(ValMgr, cast<RValue>(V2));
Ted Kremenekb4ae33f2008-01-23 23:38:00 +00001020 Nodify(Dst, B, N2, SetValue(SetValue(St, B, Result), L1, Result));
1021 break;
1022 }
1023
1024 case BinaryOperator::SubAssign: {
1025 const LValue& L1 = cast<LValue>(V1);
1026 RValue R1 = cast<RValue>(GetValue(N1->getState(), L1));
Ted Kremenek874d63f2008-01-24 02:02:54 +00001027 RValue Result = R1.EvalSub(ValMgr, cast<RValue>(V2));
Ted Kremenekb4ae33f2008-01-23 23:38:00 +00001028 Nodify(Dst, B, N2, SetValue(SetValue(St, B, Result), L1, Result));
1029 break;
1030 }
Ted Kremenek2eafd0e2008-01-23 23:42:27 +00001031
1032 case BinaryOperator::MulAssign: {
1033 const LValue& L1 = cast<LValue>(V1);
1034 RValue R1 = cast<RValue>(GetValue(N1->getState(), L1));
Ted Kremenek874d63f2008-01-24 02:02:54 +00001035 RValue Result = R1.EvalMul(ValMgr, cast<RValue>(V2));
Ted Kremenek2eafd0e2008-01-23 23:42:27 +00001036 Nodify(Dst, B, N2, SetValue(SetValue(St, B, Result), L1, Result));
1037 break;
1038 }
Ted Kremenekab2b8c52008-01-23 19:59:44 +00001039
1040 default:
1041 Dst.Add(N2);
1042 break;
1043 }
Ted Kremenekcb448ca2008-01-16 00:53:15 +00001044 }
Ted Kremenekd27f8162008-01-15 23:55:06 +00001045 }
Ted Kremenekd27f8162008-01-15 23:55:06 +00001046}
Ted Kremenekee985462008-01-16 18:18:48 +00001047
Ted Kremenek1ccd31c2008-01-16 19:42:59 +00001048
Ted Kremenekab2b8c52008-01-23 19:59:44 +00001049void GRConstants::Visit(Stmt* S, GRConstants::NodeTy* Pred,
1050 GRConstants::NodeSet& Dst) {
1051
1052 // FIXME: add metadata to the CFG so that we can disable
1053 // this check when we KNOW that there is no block-level subexpression.
1054 // The motivation is that this check requires a hashtable lookup.
1055
1056 if (S != CurrentStmt && getCFG().isBlkExpr(S)) {
1057 Dst.Add(Pred);
1058 return;
1059 }
1060
1061 switch (S->getStmtClass()) {
1062 case Stmt::BinaryOperatorClass:
Ted Kremenekb4ae33f2008-01-23 23:38:00 +00001063 case Stmt::CompoundAssignOperatorClass:
Ted Kremenekab2b8c52008-01-23 19:59:44 +00001064 VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Dst);
1065 break;
1066
Ted Kremenek7b8009a2008-01-24 02:28:56 +00001067 case Stmt::UnaryOperatorClass:
1068 VisitUnaryOperator(cast<UnaryOperator>(S), Pred, Dst);
1069 break;
1070
Ted Kremenekab2b8c52008-01-23 19:59:44 +00001071 case Stmt::ParenExprClass:
1072 Visit(cast<ParenExpr>(S)->getSubExpr(), Pred, Dst);
1073 break;
1074
Ted Kremenek874d63f2008-01-24 02:02:54 +00001075 case Stmt::ImplicitCastExprClass: {
1076 ImplicitCastExpr* C = cast<ImplicitCastExpr>(S);
1077 VisitCast(C, C->getSubExpr(), Pred, Dst);
1078 break;
1079 }
1080
1081 case Stmt::CastExprClass: {
1082 CastExpr* C = cast<CastExpr>(S);
1083 VisitCast(C, C->getSubExpr(), Pred, Dst);
1084 break;
1085 }
1086
Ted Kremenek9de04c42008-01-24 20:55:43 +00001087 case Stmt::DeclStmtClass:
1088 VisitDeclStmt(cast<DeclStmt>(S), Pred, Dst);
1089 break;
1090
Ted Kremenekab2b8c52008-01-23 19:59:44 +00001091 default:
1092 Dst.Add(Pred); // No-op. Simply propagate the current state unchanged.
1093 break;
Ted Kremenek79649df2008-01-17 18:25:22 +00001094 }
Ted Kremenek1ccd31c2008-01-16 19:42:59 +00001095}
1096
Ted Kremenekee985462008-01-16 18:18:48 +00001097//===----------------------------------------------------------------------===//
1098// Driver.
1099//===----------------------------------------------------------------------===//
1100
Ted Kremenekaa66a322008-01-16 21:46:15 +00001101#ifndef NDEBUG
1102namespace llvm {
1103template<>
1104struct VISIBILITY_HIDDEN DOTGraphTraits<GRConstants::NodeTy*> :
1105 public DefaultDOTGraphTraits {
Ted Kremenek9ff731d2008-01-24 22:27:20 +00001106
1107 static void PrintKindLabel(std::ostream& Out, ValueKey::Kind kind) {
Ted Kremenek803c9ed2008-01-23 22:30:44 +00001108 switch (kind) {
Ted Kremenek565256e2008-01-24 22:44:24 +00001109 case ValueKey::IsSubExpr: Out << "Sub-Expressions:\\l"; break;
Ted Kremenek803c9ed2008-01-23 22:30:44 +00001110 case ValueKey::IsDecl: Out << "Variables:\\l"; break;
1111 case ValueKey::IsBlkExpr: Out << "Block-level Expressions:\\l"; break;
1112 default: assert (false && "Unknown ValueKey type.");
1113 }
1114 }
1115
Ted Kremenek9ff731d2008-01-24 22:27:20 +00001116 static void PrintKind(std::ostream& Out, GRConstants::StateTy M,
1117 ValueKey::Kind kind, bool isFirstGroup = false) {
1118 bool isFirst = true;
1119
1120 for (GRConstants::StateTy::iterator I=M.begin(), E=M.end();I!=E;++I) {
1121 if (I.getKey().getKind() != kind)
1122 continue;
1123
1124 if (isFirst) {
1125 if (!isFirstGroup) Out << "\\l\\l";
1126 PrintKindLabel(Out, kind);
1127 isFirst = false;
1128 }
1129 else
1130 Out << "\\l";
1131
1132 Out << ' ';
1133
1134 if (ValueDecl* V = dyn_cast<ValueDecl>(I.getKey()))
1135 Out << V->getName();
1136 else {
1137 Stmt* E = cast<Stmt>(I.getKey());
1138 Out << " (" << (void*) E << ") ";
1139 E->printPretty(Out);
1140 }
1141
1142 Out << " : ";
1143 I.getData().print(Out);
1144 }
1145 }
1146
Ted Kremenekaa66a322008-01-16 21:46:15 +00001147 static std::string getNodeLabel(const GRConstants::NodeTy* N, void*) {
1148 std::ostringstream Out;
Ted Kremenek803c9ed2008-01-23 22:30:44 +00001149
1150 // Program Location.
Ted Kremenekaa66a322008-01-16 21:46:15 +00001151 ProgramPoint Loc = N->getLocation();
1152
1153 switch (Loc.getKind()) {
1154 case ProgramPoint::BlockEntranceKind:
1155 Out << "Block Entrance: B"
1156 << cast<BlockEntrance>(Loc).getBlock()->getBlockID();
1157 break;
1158
1159 case ProgramPoint::BlockExitKind:
1160 assert (false);
1161 break;
1162
1163 case ProgramPoint::PostStmtKind: {
1164 const PostStmt& L = cast<PostStmt>(Loc);
Ted Kremenek9ff731d2008-01-24 22:27:20 +00001165 Out << L.getStmt()->getStmtClassName() << ':'
1166 << (void*) L.getStmt() << ' ';
1167
Ted Kremenekaa66a322008-01-16 21:46:15 +00001168 L.getStmt()->printPretty(Out);
1169 break;
1170 }
1171
1172 default: {
1173 const BlockEdge& E = cast<BlockEdge>(Loc);
1174 Out << "Edge: (B" << E.getSrc()->getBlockID() << ", B"
1175 << E.getDst()->getBlockID() << ')';
1176 }
1177 }
1178
Ted Kremenek803c9ed2008-01-23 22:30:44 +00001179 Out << "\\|";
Ted Kremenekaa66a322008-01-16 21:46:15 +00001180
Ted Kremenek9ff731d2008-01-24 22:27:20 +00001181 PrintKind(Out, N->getState(), ValueKey::IsDecl, true);
1182 PrintKind(Out, N->getState(), ValueKey::IsBlkExpr);
Ted Kremenek565256e2008-01-24 22:44:24 +00001183 PrintKind(Out, N->getState(), ValueKey::IsSubExpr);
Ted Kremenek803c9ed2008-01-23 22:30:44 +00001184
Ted Kremenek803c9ed2008-01-23 22:30:44 +00001185 Out << "\\l";
Ted Kremenekaa66a322008-01-16 21:46:15 +00001186 return Out.str();
1187 }
1188};
1189} // end llvm namespace
1190#endif
1191
Ted Kremenekee985462008-01-16 18:18:48 +00001192namespace clang {
Ted Kremenek874d63f2008-01-24 02:02:54 +00001193void RunGRConstants(CFG& cfg, ASTContext& Ctx) {
1194 GREngine<GRConstants> Engine(cfg, Ctx);
Ted Kremenekee985462008-01-16 18:18:48 +00001195 Engine.ExecuteWorkList();
Ted Kremenekaa66a322008-01-16 21:46:15 +00001196#ifndef NDEBUG
1197 llvm::ViewGraph(*Engine.getGraph().roots_begin(),"GRConstants");
1198#endif
Ted Kremenekee985462008-01-16 18:18:48 +00001199}
Ted Kremenekab2b8c52008-01-23 19:59:44 +00001200} // end clang namespace