blob: 13d10f2d8bb1b456950945fb156a993036bcf0af [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"
Ted Kremenekab2b8c52008-01-23 19:59:44 +000031#include "llvm/Support/Streams.h"
32
Ted Kremenek5ee4ff82008-01-25 22:55:56 +000033#include <functional>
34
Ted Kremenekaa66a322008-01-16 21:46:15 +000035#ifndef NDEBUG
36#include "llvm/Support/GraphWriter.h"
37#include <sstream>
38#endif
39
Ted Kremenekd27f8162008-01-15 23:55:06 +000040using namespace clang;
Ted Kremenekd27f8162008-01-15 23:55:06 +000041using llvm::dyn_cast;
42using llvm::cast;
Ted Kremenek5ee4ff82008-01-25 22:55:56 +000043using llvm::APSInt;
Ted Kremenekd27f8162008-01-15 23:55:06 +000044
45//===----------------------------------------------------------------------===//
Ted Kremenekab2b8c52008-01-23 19:59:44 +000046/// ValueKey - A variant smart pointer that wraps either a ValueDecl* or a
Ted Kremenekd27f8162008-01-15 23:55:06 +000047/// Stmt*. Use cast<> or dyn_cast<> to get actual pointer type
48//===----------------------------------------------------------------------===//
49namespace {
Ted Kremenekab2b8c52008-01-23 19:59:44 +000050
51class VISIBILITY_HIDDEN ValueKey {
Ted Kremenek0525a4f2008-01-16 19:47:19 +000052 uintptr_t Raw;
Ted Kremenekcc1c3652008-01-25 23:43:12 +000053
54 void operator=(const ValueKey& RHS); // Do not implement.
Ted Kremenekd27f8162008-01-15 23:55:06 +000055public:
Ted Kremenek565256e2008-01-24 22:44:24 +000056 enum Kind { IsSubExpr=0x0, IsBlkExpr=0x1, IsDecl=0x2, Flags=0x3 };
Ted Kremenekd27f8162008-01-15 23:55:06 +000057 inline void* getPtr() const { return reinterpret_cast<void*>(Raw & ~Flags); }
Ted Kremenekab2b8c52008-01-23 19:59:44 +000058 inline Kind getKind() const { return (Kind) (Raw & Flags); }
Ted Kremenekd27f8162008-01-15 23:55:06 +000059
Ted Kremenekab2b8c52008-01-23 19:59:44 +000060 ValueKey(const ValueDecl* VD)
Ted Kremenekcc1c3652008-01-25 23:43:12 +000061 : Raw(reinterpret_cast<uintptr_t>(VD) | IsDecl) { assert(VD); }
Ted Kremenekab2b8c52008-01-23 19:59:44 +000062
Ted Kremenek5c1b9962008-01-24 19:43:37 +000063 ValueKey(Stmt* S, bool isBlkExpr = false)
Ted Kremenekcc1c3652008-01-25 23:43:12 +000064 : Raw(reinterpret_cast<uintptr_t>(S) | (isBlkExpr ? IsBlkExpr : IsSubExpr)){
65 assert(S);
66 }
Ted Kremenekd27f8162008-01-15 23:55:06 +000067
Ted Kremenek565256e2008-01-24 22:44:24 +000068 bool isSubExpr() const { return getKind() == IsSubExpr; }
Ted Kremenekab2b8c52008-01-23 19:59:44 +000069 bool isDecl() const { return getKind() == IsDecl; }
Ted Kremenekd27f8162008-01-15 23:55:06 +000070
71 inline void Profile(llvm::FoldingSetNodeID& ID) const {
Ted Kremenek98491852008-01-16 05:51:13 +000072 ID.AddPointer(getPtr());
Ted Kremenekab2b8c52008-01-23 19:59:44 +000073 }
74
75 inline bool operator==(const ValueKey& X) const {
Ted Kremenek5c1b9962008-01-24 19:43:37 +000076 return getPtr() == X.getPtr();
Ted Kremenekab2b8c52008-01-23 19:59:44 +000077 }
78
79 inline bool operator!=(const ValueKey& X) const {
80 return !operator==(X);
81 }
82
83 inline bool operator<(const ValueKey& X) const {
84 Kind k = getKind(), Xk = X.getKind();
Ted Kremenek5c1b9962008-01-24 19:43:37 +000085
86 if (k == IsDecl) {
87 if (Xk != IsDecl)
88 return false;
89 }
90 else {
91 if (Xk == IsDecl)
92 return true;
93 }
Ted Kremenekab2b8c52008-01-23 19:59:44 +000094
Ted Kremenek5c1b9962008-01-24 19:43:37 +000095 return getPtr() < X.getPtr();
Ted Kremenekb3d2dca2008-01-16 23:33:44 +000096 }
Ted Kremenekd27f8162008-01-15 23:55:06 +000097};
98} // end anonymous namespace
99
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000100// Machinery to get cast<> and dyn_cast<> working with ValueKey.
Ted Kremenekd27f8162008-01-15 23:55:06 +0000101namespace llvm {
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000102 template<> inline bool isa<ValueDecl,ValueKey>(const ValueKey& V) {
103 return V.getKind() == ValueKey::IsDecl;
Ted Kremenekd27f8162008-01-15 23:55:06 +0000104 }
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000105 template<> inline bool isa<Stmt,ValueKey>(const ValueKey& V) {
106 return ((unsigned) V.getKind()) != ValueKey::IsDecl;
Ted Kremenekd27f8162008-01-15 23:55:06 +0000107 }
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000108 template<> struct VISIBILITY_HIDDEN cast_retty_impl<ValueDecl,ValueKey> {
Ted Kremenekaa66a322008-01-16 21:46:15 +0000109 typedef const ValueDecl* ret_type;
Ted Kremenekd27f8162008-01-15 23:55:06 +0000110 };
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000111 template<> struct VISIBILITY_HIDDEN cast_retty_impl<Stmt,ValueKey> {
Ted Kremenekd27f8162008-01-15 23:55:06 +0000112 typedef const Stmt* ret_type;
113 };
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000114 template<> struct VISIBILITY_HIDDEN simplify_type<ValueKey> {
Ted Kremenekd27f8162008-01-15 23:55:06 +0000115 typedef void* SimpleType;
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000116 static inline SimpleType getSimplifiedValue(const ValueKey &V) {
Ted Kremenekd27f8162008-01-15 23:55:06 +0000117 return V.getPtr();
118 }
119 };
120} // end llvm namespace
121
122//===----------------------------------------------------------------------===//
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000123// ValueManager.
Ted Kremenekd27f8162008-01-15 23:55:06 +0000124//===----------------------------------------------------------------------===//
125
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000126namespace {
127
Ted Kremenek5ee4ff82008-01-25 22:55:56 +0000128typedef llvm::ImmutableSet<APSInt > APSIntSetTy;
129
130
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000131class VISIBILITY_HIDDEN ValueManager {
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000132 APSIntSetTy::Factory APSIntSetFactory;
Ted Kremenek874d63f2008-01-24 02:02:54 +0000133 ASTContext* Ctx;
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000134
135public:
136 ValueManager() {}
137 ~ValueManager() {}
138
Ted Kremenek874d63f2008-01-24 02:02:54 +0000139 void setContext(ASTContext* ctx) { Ctx = ctx; }
140 ASTContext* getContext() const { return Ctx; }
141
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000142 APSIntSetTy GetEmptyAPSIntSet() {
143 return APSIntSetFactory.GetEmptySet();
144 }
145
Ted Kremenek5ee4ff82008-01-25 22:55:56 +0000146 APSIntSetTy AddToSet(const APSIntSetTy& Set, const APSInt& Val) {
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000147 return APSIntSetFactory.Add(Set, Val);
Ted Kremenekd27f8162008-01-15 23:55:06 +0000148 }
149};
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000150} // end anonymous namespace
151
Ted Kremenekcc1c3652008-01-25 23:43:12 +0000152template <template <typename T> class OpTy>
Ted Kremenek5ee4ff82008-01-25 22:55:56 +0000153static inline APSIntSetTy APSIntSetOp(ValueManager& ValMgr,
Ted Kremenekcc1c3652008-01-25 23:43:12 +0000154 APSIntSetTy S1, APSIntSetTy S2) {
Ted Kremenek5ee4ff82008-01-25 22:55:56 +0000155
156 APSIntSetTy M = ValMgr.GetEmptyAPSIntSet();
157
Ted Kremenekcc1c3652008-01-25 23:43:12 +0000158 OpTy<APSInt> Op;
159
Ted Kremenek5ee4ff82008-01-25 22:55:56 +0000160 for (APSIntSetTy::iterator I1=S1.begin(), E1=S2.end(); I1!=E1; ++I1)
161 for (APSIntSetTy::iterator I2=S2.begin(), E2=S2.end(); I2!=E2; ++I2)
Ted Kremenekcc1c3652008-01-25 23:43:12 +0000162 M = ValMgr.AddToSet(M, Op(*I1, *I2));
Ted Kremenek5ee4ff82008-01-25 22:55:56 +0000163
164 return M;
165}
166
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000167//===----------------------------------------------------------------------===//
168// Expression Values.
169//===----------------------------------------------------------------------===//
Ted Kremenekf13794e2008-01-24 23:19:54 +0000170
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000171namespace {
172
173class VISIBILITY_HIDDEN ExprValue {
174public:
Ted Kremenekf13794e2008-01-24 23:19:54 +0000175 enum BaseKind { LValueKind=0x1, RValueKind=0x2, InvalidKind=0x0 };
176
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000177private:
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000178 void* Data;
Ted Kremenekf13794e2008-01-24 23:19:54 +0000179 unsigned Kind;
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000180
181protected:
Ted Kremenekf13794e2008-01-24 23:19:54 +0000182 ExprValue(void* d, bool isRValue, unsigned ValKind)
183 : Data(d),
184 Kind((isRValue ? RValueKind : LValueKind) | (ValKind << 2)) {}
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000185
Ted Kremenekf13794e2008-01-24 23:19:54 +0000186 ExprValue() : Data(NULL), Kind(0) {}
187
188 void* getRawPtr() const { return Data; }
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000189
190public:
191 ~ExprValue() {};
192
Ted Kremenek874d63f2008-01-24 02:02:54 +0000193 ExprValue EvalCast(ValueManager& ValMgr, Expr* CastExpr) const;
194
Ted Kremenekf13794e2008-01-24 23:19:54 +0000195 unsigned getRawKind() const { return Kind; }
196 BaseKind getBaseKind() const { return (BaseKind) (Kind & 0x3); }
197 unsigned getSubKind() const { return (Kind & ~0x3) >> 2; }
198
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000199 void Profile(llvm::FoldingSetNodeID& ID) const {
Ted Kremenekf13794e2008-01-24 23:19:54 +0000200 ID.AddInteger((unsigned) getRawKind());
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000201 ID.AddPointer(Data);
202 }
203
204 bool operator==(const ExprValue& RHS) const {
Ted Kremenekf13794e2008-01-24 23:19:54 +0000205 return getRawKind() == RHS.getRawKind() && Data == RHS.Data;
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000206 }
207
Ted Kremenekf13794e2008-01-24 23:19:54 +0000208 inline bool isValid() const { return getRawKind() != InvalidKind; }
209 inline bool isInvalid() const { return getRawKind() == InvalidKind; }
210
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000211
212 void print(std::ostream& OS) const;
213 void print() const { print(*llvm::cerr.stream()); }
214
215 // Implement isa<T> support.
216 static inline bool classof(const ExprValue*) { return true; }
217};
218
219class VISIBILITY_HIDDEN InvalidValue : public ExprValue {
220public:
Ted Kremenekf13794e2008-01-24 23:19:54 +0000221 InvalidValue() {}
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000222
223 static inline bool classof(const ExprValue* V) {
Ted Kremenekf13794e2008-01-24 23:19:54 +0000224 return V->getBaseKind() == InvalidKind;
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000225 }
226};
227
Ted Kremenekf13794e2008-01-24 23:19:54 +0000228class VISIBILITY_HIDDEN LValue : public ExprValue {
229protected:
230 LValue(unsigned SubKind, void* D) : ExprValue(D, false, SubKind) {}
231
232public:
233 // Implement isa<T> support.
234 static inline bool classof(const ExprValue* V) {
235 return V->getBaseKind() == LValueKind;
236 }
237};
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000238
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000239class VISIBILITY_HIDDEN RValue : public ExprValue {
240protected:
Ted Kremenekf13794e2008-01-24 23:19:54 +0000241 RValue(unsigned SubKind, void* d) : ExprValue(d, true, SubKind) {}
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000242
243public:
Ted Kremenekf13794e2008-01-24 23:19:54 +0000244 void print(std::ostream& Out) const;
245
Ted Kremenek874d63f2008-01-24 02:02:54 +0000246 RValue EvalAdd(ValueManager& ValMgr, const RValue& RHS) const;
247 RValue EvalSub(ValueManager& ValMgr, const RValue& RHS) const;
248 RValue EvalMul(ValueManager& ValMgr, const RValue& RHS) const;
Ted Kremenek5ee4ff82008-01-25 22:55:56 +0000249 RValue EvalDiv(ValueManager& ValMgr, const RValue& RHS) const;
Ted Kremenekdacbb4f2008-01-24 08:20:02 +0000250 RValue EvalMinus(ValueManager& ValMgr, UnaryOperator* U) const;
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000251
Ted Kremenek5ee4ff82008-01-25 22:55:56 +0000252 static RValue GetRValue(ValueManager& ValMgr, const APSInt& V);
Ted Kremenekdacbb4f2008-01-24 08:20:02 +0000253 static RValue GetRValue(ValueManager& ValMgr, IntegerLiteral* I);
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000254
255 // Implement isa<T> support.
256 static inline bool classof(const ExprValue* V) {
Ted Kremenekf13794e2008-01-24 23:19:54 +0000257 return V->getBaseKind() == RValueKind;
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000258 }
259};
Ted Kremenekf13794e2008-01-24 23:19:54 +0000260
261} // end anonymous namespace
262
263//===----------------------------------------------------------------------===//
264// "R-Values": Interface.
265//===----------------------------------------------------------------------===//
266
267namespace {
268
Ted Kremenek5ee4ff82008-01-25 22:55:56 +0000269enum { RValEqualityORSetKind,
270 RValInequalityANDSetKind,
271 NumRValueKind };
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000272
Ted Kremenek5ee4ff82008-01-25 22:55:56 +0000273class VISIBILITY_HIDDEN RValEqualityORSet : public RValue {
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000274public:
Ted Kremenek5ee4ff82008-01-25 22:55:56 +0000275 RValEqualityORSet(const APSIntSetTy& S)
276 : RValue(RValEqualityORSetKind, S.getRoot()) {}
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000277
278 APSIntSetTy GetValues() const {
279 return APSIntSetTy(reinterpret_cast<APSIntSetTy::TreeTy*>(getRawPtr()));
280 }
281
Ted Kremenek5ee4ff82008-01-25 22:55:56 +0000282 RValEqualityORSet
283 EvalAdd(ValueManager& ValMgr, const RValEqualityORSet& V) const {
Ted Kremenekcc1c3652008-01-25 23:43:12 +0000284 return APSIntSetOp<std::plus>(ValMgr, GetValues(), V.GetValues());
Ted Kremenek5ee4ff82008-01-25 22:55:56 +0000285 }
Ted Kremenek874d63f2008-01-24 02:02:54 +0000286
Ted Kremenek5ee4ff82008-01-25 22:55:56 +0000287 RValEqualityORSet
288 EvalSub(ValueManager& ValMgr, const RValEqualityORSet& V) const {
Ted Kremenekcc1c3652008-01-25 23:43:12 +0000289 return APSIntSetOp<std::minus>(ValMgr, GetValues(), V.GetValues());
Ted Kremenek5ee4ff82008-01-25 22:55:56 +0000290 }
Ted Kremenek874d63f2008-01-24 02:02:54 +0000291
Ted Kremenek5ee4ff82008-01-25 22:55:56 +0000292 RValEqualityORSet
293 EvalMul(ValueManager& ValMgr, const RValEqualityORSet& V) const {
Ted Kremenekcc1c3652008-01-25 23:43:12 +0000294 return APSIntSetOp<std::multiplies>(ValMgr, GetValues(), V.GetValues());
Ted Kremenek5ee4ff82008-01-25 22:55:56 +0000295 }
296
297 RValEqualityORSet
298 EvalDiv(ValueManager& ValMgr, const RValEqualityORSet& V) const {
Ted Kremenekcc1c3652008-01-25 23:43:12 +0000299 return APSIntSetOp<std::divides>(ValMgr, GetValues(), V.GetValues());
Ted Kremenek5ee4ff82008-01-25 22:55:56 +0000300 }
Ted Kremenek874d63f2008-01-24 02:02:54 +0000301
Ted Kremenek5ee4ff82008-01-25 22:55:56 +0000302 RValEqualityORSet
Ted Kremenek2cd65c82008-01-25 22:06:07 +0000303 EvalCast(ValueManager& ValMgr, Expr* CastExpr) const;
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000304
Ted Kremenek5ee4ff82008-01-25 22:55:56 +0000305 RValEqualityORSet
Ted Kremenek2cd65c82008-01-25 22:06:07 +0000306 EvalMinus(ValueManager& ValMgr, UnaryOperator* U) const;
Ted Kremenekdacbb4f2008-01-24 08:20:02 +0000307
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000308 // Implement isa<T> support.
309 static inline bool classof(const ExprValue* V) {
Ted Kremenek5ee4ff82008-01-25 22:55:56 +0000310 return V->getSubKind() == RValEqualityORSetKind;
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000311 }
312};
Ted Kremenek5ee4ff82008-01-25 22:55:56 +0000313
314class VISIBILITY_HIDDEN RValInequalityANDSet : public RValue {
315public:
316 RValInequalityANDSet(const APSIntSetTy& S)
317 : RValue(RValInequalityANDSetKind, S.getRoot()) {}
318
319 APSIntSetTy GetValues() const {
320 return APSIntSetTy(reinterpret_cast<APSIntSetTy::TreeTy*>(getRawPtr()));
321 }
322
323 RValInequalityANDSet
324 EvalAdd(ValueManager& ValMgr, const RValInequalityANDSet& V) const;
325
326 RValInequalityANDSet
327 EvalSub(ValueManager& ValMgr, const RValInequalityANDSet& V) const;
328
329 RValInequalityANDSet
330 EvalMul(ValueManager& ValMgr, const RValInequalityANDSet& V) const;
331
332 RValInequalityANDSet
333 EvalDiv(ValueManager& ValMgr, const RValInequalityANDSet& V) const;
334
335 RValInequalityANDSet
336 EvalCast(ValueManager& ValMgr, Expr* CastExpr) const;
337
338 RValInequalityANDSet
339 EvalMinus(ValueManager& ValMgr, UnaryOperator* U) const;
340
341 // Implement isa<T> support.
342 static inline bool classof(const ExprValue* V) {
343 return V->getSubKind() == RValInequalityANDSetKind;
344 }
345};
346
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000347} // end anonymous namespace
348
349//===----------------------------------------------------------------------===//
Ted Kremenek874d63f2008-01-24 02:02:54 +0000350// Transfer functions: Casts.
351//===----------------------------------------------------------------------===//
352
353ExprValue ExprValue::EvalCast(ValueManager& ValMgr, Expr* CastExpr) const {
Ted Kremenekf13794e2008-01-24 23:19:54 +0000354 switch (getSubKind()) {
Ted Kremenek5ee4ff82008-01-25 22:55:56 +0000355 case RValEqualityORSetKind:
356 return cast<RValEqualityORSet>(this)->EvalCast(ValMgr, CastExpr);
Ted Kremenek874d63f2008-01-24 02:02:54 +0000357 default:
358 return InvalidValue();
359 }
360}
361
Ted Kremenek5ee4ff82008-01-25 22:55:56 +0000362RValEqualityORSet
363RValEqualityORSet::EvalCast(ValueManager& ValMgr, Expr* CastExpr) const {
Ted Kremenek874d63f2008-01-24 02:02:54 +0000364 QualType T = CastExpr->getType();
365 assert (T->isIntegerType());
366
367 APSIntSetTy S1 = GetValues();
368 APSIntSetTy S2 = ValMgr.GetEmptyAPSIntSet();
369
370 for (APSIntSetTy::iterator I=S1.begin(), E=S1.end(); I!=E; ++I) {
Ted Kremenek5ee4ff82008-01-25 22:55:56 +0000371 APSInt X = *I;
Ted Kremenek874d63f2008-01-24 02:02:54 +0000372 X.setIsSigned(T->isSignedIntegerType());
373 X.extOrTrunc(ValMgr.getContext()->getTypeSize(T,CastExpr->getLocStart()));
374 S2 = ValMgr.AddToSet(S2, X);
375 }
376
377 return S2;
378}
379
380//===----------------------------------------------------------------------===//
Ted Kremenekdacbb4f2008-01-24 08:20:02 +0000381// Transfer functions: Unary Operations over R-Values.
382//===----------------------------------------------------------------------===//
383
384RValue RValue::EvalMinus(ValueManager& ValMgr, UnaryOperator* U) const {
Ted Kremenekf13794e2008-01-24 23:19:54 +0000385 switch (getSubKind()) {
Ted Kremenek5ee4ff82008-01-25 22:55:56 +0000386 case RValEqualityORSetKind:
387 return cast<RValEqualityORSet>(this)->EvalMinus(ValMgr, U);
Ted Kremenekdacbb4f2008-01-24 08:20:02 +0000388 default:
389 return cast<RValue>(InvalidValue());
390 }
391}
392
Ted Kremenek5ee4ff82008-01-25 22:55:56 +0000393RValEqualityORSet
394RValEqualityORSet::EvalMinus(ValueManager& ValMgr, UnaryOperator* U) const{
Ted Kremenekdacbb4f2008-01-24 08:20:02 +0000395
396 assert (U->getType() == U->getSubExpr()->getType());
397 assert (U->getType()->isIntegerType());
398
399 APSIntSetTy S1 = GetValues();
400 APSIntSetTy S2 = ValMgr.GetEmptyAPSIntSet();
401
402 for (APSIntSetTy::iterator I=S1.begin(), E=S1.end(); I!=E; ++I) {
403 assert ((*I).isSigned());
404
405 // FIXME: Shouldn't operator- on APSInt return an APSInt with the proper
406 // sign?
Ted Kremenek5ee4ff82008-01-25 22:55:56 +0000407 APSInt X(-(*I));
Ted Kremenekdacbb4f2008-01-24 08:20:02 +0000408 X.setIsSigned(true);
409
410 S2 = ValMgr.AddToSet(S2, X);
411 }
412
413 return S2;
414}
415
Ted Kremenekdacbb4f2008-01-24 08:20:02 +0000416//===----------------------------------------------------------------------===//
Ted Kremenek874d63f2008-01-24 02:02:54 +0000417// Transfer functions: Binary Operations over R-Values.
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000418//===----------------------------------------------------------------------===//
419
420#define RVALUE_DISPATCH_CASE(k1,k2,Op)\
Ted Kremenekf13794e2008-01-24 23:19:54 +0000421case (k1##Kind*NumRValueKind+k2##Kind):\
Ted Kremenek874d63f2008-01-24 02:02:54 +0000422 return cast<k1>(*this).Eval##Op(ValMgr,cast<k2>(RHS));
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000423
424#define RVALUE_DISPATCH(Op)\
Ted Kremenekf13794e2008-01-24 23:19:54 +0000425switch (getSubKind()*NumRValueKind+RHS.getSubKind()){\
Ted Kremenek5ee4ff82008-01-25 22:55:56 +0000426 RVALUE_DISPATCH_CASE(RValEqualityORSet,RValEqualityORSet,Op)\
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000427 default:\
428 assert (!isValid() || !RHS.isValid() && "Missing case.");\
429 break;\
430}\
431return cast<RValue>(InvalidValue());
432
Ted Kremenek874d63f2008-01-24 02:02:54 +0000433RValue RValue::EvalAdd(ValueManager& ValMgr, const RValue& RHS) const {
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000434 RVALUE_DISPATCH(Add)
435}
436
Ted Kremenek874d63f2008-01-24 02:02:54 +0000437RValue RValue::EvalSub(ValueManager& ValMgr, const RValue& RHS) const {
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000438 RVALUE_DISPATCH(Sub)
439}
440
Ted Kremenek874d63f2008-01-24 02:02:54 +0000441RValue RValue::EvalMul(ValueManager& ValMgr, const RValue& RHS) const {
Ted Kremenek2eafd0e2008-01-23 23:42:27 +0000442 RVALUE_DISPATCH(Mul)
443}
444
Ted Kremenek5ee4ff82008-01-25 22:55:56 +0000445RValue RValue::EvalDiv(ValueManager& ValMgr, const RValue& RHS) const {
446 RVALUE_DISPATCH(Div)
447}
448
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000449#undef RVALUE_DISPATCH_CASE
450#undef RVALUE_DISPATCH
451
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000452
Ted Kremenek5ee4ff82008-01-25 22:55:56 +0000453RValue RValue::GetRValue(ValueManager& ValMgr, const APSInt& V) {
454 return RValEqualityORSet(ValMgr.AddToSet(ValMgr.GetEmptyAPSIntSet(), V));
Ted Kremenekdacbb4f2008-01-24 08:20:02 +0000455}
456
457RValue RValue::GetRValue(ValueManager& ValMgr, IntegerLiteral* I) {
Ted Kremenek5ee4ff82008-01-25 22:55:56 +0000458 return GetRValue(ValMgr,
459 APSInt(I->getValue(),I->getType()->isUnsignedIntegerType()));
Ted Kremenekdacbb4f2008-01-24 08:20:02 +0000460}
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000461
462//===----------------------------------------------------------------------===//
463// "L-Values".
464//===----------------------------------------------------------------------===//
465
466namespace {
Ted Kremenekf13794e2008-01-24 23:19:54 +0000467
Ted Kremenek5ee4ff82008-01-25 22:55:56 +0000468enum { LValueDeclKind, MaxLValueKind };
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000469
470class VISIBILITY_HIDDEN LValueDecl : public LValue {
471public:
Ted Kremenek9de04c42008-01-24 20:55:43 +0000472 LValueDecl(const ValueDecl* vd)
473 : LValue(LValueDeclKind,const_cast<ValueDecl*>(vd)) {}
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000474
475 ValueDecl* getDecl() const {
476 return static_cast<ValueDecl*>(getRawPtr());
477 }
478
479 // Implement isa<T> support.
480 static inline bool classof(const ExprValue* V) {
Ted Kremenekf13794e2008-01-24 23:19:54 +0000481 return V->getSubKind() == LValueDeclKind;
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000482 }
483};
484} // end anonymous namespace
485
486//===----------------------------------------------------------------------===//
487// Pretty-Printing.
488//===----------------------------------------------------------------------===//
489
490void ExprValue::print(std::ostream& Out) const {
Ted Kremenekf13794e2008-01-24 23:19:54 +0000491 switch (getBaseKind()) {
492 case InvalidKind:
493 Out << "Invalid";
494 break;
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000495
Ted Kremenekf13794e2008-01-24 23:19:54 +0000496 case RValueKind:
497 cast<RValue>(this)->print(Out);
498 break;
499
500 case LValueKind:
501 assert (false && "FIXME: LValue printing not implemented.");
502 break;
503
504 default:
505 assert (false && "Invalid ExprValue.");
506 }
507}
508
509void RValue::print(std::ostream& Out) const {
510 switch (getSubKind()) {
Ted Kremenek5ee4ff82008-01-25 22:55:56 +0000511 case RValEqualityORSetKind: {
512 APSIntSetTy S = cast<RValEqualityORSet>(this)->GetValues();
Ted Kremenek803c9ed2008-01-23 22:30:44 +0000513 bool first = true;
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000514
Ted Kremenek803c9ed2008-01-23 22:30:44 +0000515 for (APSIntSetTy::iterator I=S.begin(), E=S.end(); I!=E; ++I) {
516 if (first) first = false;
517 else Out << " | ";
518
519 Out << (*I).toString();
520 }
521
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000522 break;
523 }
524
525 default:
Ted Kremenekf13794e2008-01-24 23:19:54 +0000526 assert (false && "Pretty-printed not implemented for this RValue.");
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000527 break;
528 }
529}
530
531//===----------------------------------------------------------------------===//
532// ValueMapTy - A ImmutableMap type Stmt*/Decl* to ExprValues.
533//===----------------------------------------------------------------------===//
534
535typedef llvm::ImmutableMap<ValueKey,ExprValue> ValueMapTy;
536
537namespace clang {
538 template<>
539 struct VISIBILITY_HIDDEN GRTrait<ValueMapTy> {
540 static inline void* toPtr(ValueMapTy M) {
541 return reinterpret_cast<void*>(M.getRoot());
542 }
543 static inline ValueMapTy toState(void* P) {
544 return ValueMapTy(static_cast<ValueMapTy::TreeTy*>(P));
545 }
546 };
Ted Kremenekd27f8162008-01-15 23:55:06 +0000547}
548
549//===----------------------------------------------------------------------===//
550// The Checker!
551//===----------------------------------------------------------------------===//
552
553namespace {
Ted Kremenekd27f8162008-01-15 23:55:06 +0000554
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000555class VISIBILITY_HIDDEN GRConstants {
Ted Kremenekd27f8162008-01-15 23:55:06 +0000556
557public:
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000558 typedef ValueMapTy StateTy;
Ted Kremenekd27f8162008-01-15 23:55:06 +0000559 typedef GRNodeBuilder<GRConstants> NodeBuilder;
560 typedef ExplodedNode<StateTy> NodeTy;
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000561
562 class NodeSet {
563 typedef llvm::SmallVector<NodeTy*,3> ImplTy;
564 ImplTy Impl;
565 public:
566
567 NodeSet() {}
568 NodeSet(NodeTy* N) { assert (N && !N->isInfeasible()); Impl.push_back(N); }
569
570 void Add(NodeTy* N) { if (N && !N->isInfeasible()) Impl.push_back(N); }
571
572 typedef ImplTy::iterator iterator;
573 typedef ImplTy::const_iterator const_iterator;
574
575 unsigned size() const { return Impl.size(); }
Ted Kremenek9de04c42008-01-24 20:55:43 +0000576 bool empty() const { return Impl.empty(); }
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000577
578 iterator begin() { return Impl.begin(); }
579 iterator end() { return Impl.end(); }
580
581 const_iterator begin() const { return Impl.begin(); }
582 const_iterator end() const { return Impl.end(); }
583 };
Ted Kremenekd27f8162008-01-15 23:55:06 +0000584
585protected:
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000586 /// Liveness - live-variables information the ValueDecl* and block-level
587 /// Expr* in the CFG. Used to prune out dead state.
Ted Kremenekd27f8162008-01-15 23:55:06 +0000588 LiveVariables* Liveness;
589
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000590 /// Builder - The current GRNodeBuilder which is used when building the nodes
591 /// for a given statement.
Ted Kremenekd27f8162008-01-15 23:55:06 +0000592 NodeBuilder* Builder;
593
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000594 /// StateMgr - Object that manages the data for all created states.
595 ValueMapTy::Factory StateMgr;
Ted Kremenekd27f8162008-01-15 23:55:06 +0000596
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000597 /// ValueMgr - Object that manages the data for all created ExprValues.
598 ValueManager ValMgr;
599
600 /// cfg - the current CFG.
Ted Kremenekd27f8162008-01-15 23:55:06 +0000601 CFG* cfg;
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000602
603 /// StmtEntryNode - The immediate predecessor node.
604 NodeTy* StmtEntryNode;
605
606 /// CurrentStmt - The current block-level statement.
607 Stmt* CurrentStmt;
608
609 bool StateCleaned;
Ted Kremenekd27f8162008-01-15 23:55:06 +0000610
Ted Kremenek7b8009a2008-01-24 02:28:56 +0000611 ASTContext* getContext() const { return ValMgr.getContext(); }
612
Ted Kremenekd27f8162008-01-15 23:55:06 +0000613public:
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000614 GRConstants() : Liveness(NULL), Builder(NULL), cfg(NULL),
615 StmtEntryNode(NULL), CurrentStmt(NULL) {}
Ted Kremenekd27f8162008-01-15 23:55:06 +0000616
617 ~GRConstants() { delete Liveness; }
618
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000619 /// getCFG - Returns the CFG associated with this analysis.
Ted Kremenekd27f8162008-01-15 23:55:06 +0000620 CFG& getCFG() { assert (cfg); return *cfg; }
621
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000622 /// Initialize - Initialize the checker's state based on the specified
623 /// CFG. This results in liveness information being computed for
624 /// each block-level statement in the CFG.
Ted Kremenek874d63f2008-01-24 02:02:54 +0000625 void Initialize(CFG& c, ASTContext& ctx) {
626 cfg = &c;
627 ValMgr.setContext(&ctx);
Ted Kremenekd27f8162008-01-15 23:55:06 +0000628 Liveness = new LiveVariables(c);
629 Liveness->runOnCFG(c);
Ted Kremenek79649df2008-01-17 18:25:22 +0000630 Liveness->runOnAllBlocks(c, NULL, true);
Ted Kremenekd27f8162008-01-15 23:55:06 +0000631 }
632
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000633 /// getInitialState - Return the initial state used for the root vertex
634 /// in the ExplodedGraph.
Ted Kremenekd27f8162008-01-15 23:55:06 +0000635 StateTy getInitialState() {
Ted Kremenekcb448ca2008-01-16 00:53:15 +0000636 return StateMgr.GetEmptyMap();
Ted Kremenekd27f8162008-01-15 23:55:06 +0000637 }
Ted Kremenekd27f8162008-01-15 23:55:06 +0000638
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000639 /// ProcessStmt - Called by GREngine. Used to generate new successor
640 /// nodes by processing the 'effects' of a block-level statement.
641 void ProcessStmt(Stmt* S, NodeBuilder& builder);
642
643 /// RemoveDeadBindings - Return a new state that is the same as 'M' except
644 /// that all subexpression mappings are removed and that any
645 /// block-level expressions that are not live at 'S' also have their
646 /// mappings removed.
647 StateTy RemoveDeadBindings(Stmt* S, StateTy M);
648
Ted Kremenek9de04c42008-01-24 20:55:43 +0000649 StateTy SetValue(StateTy St, Stmt* S, const ExprValue& V);
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000650
Ted Kremenek9de04c42008-01-24 20:55:43 +0000651 StateTy SetValue(StateTy St, const Stmt* S, const ExprValue& V) {
652 return SetValue(St, const_cast<Stmt*>(S), V);
653 }
654
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000655 StateTy SetValue(StateTy St, const LValue& LV, const ExprValue& V);
Ted Kremenek1ccd31c2008-01-16 19:42:59 +0000656
Ted Kremenek9de04c42008-01-24 20:55:43 +0000657 ExprValue GetValue(const StateTy& St, Stmt* S);
658 inline ExprValue GetValue(const StateTy& St, const Stmt* S) {
659 return GetValue(St, const_cast<Stmt*>(S));
660 }
661
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000662 ExprValue GetValue(const StateTy& St, const LValue& LV);
663 LValue GetLValue(const StateTy& St, Stmt* S);
Ted Kremenekd27f8162008-01-15 23:55:06 +0000664
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000665 void Nodify(NodeSet& Dst, Stmt* S, NodeTy* Pred, StateTy St);
Ted Kremenekd27f8162008-01-15 23:55:06 +0000666
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000667 /// Visit - Transfer function logic for all statements. Dispatches to
668 /// other functions that handle specific kinds of statements.
669 void Visit(Stmt* S, NodeTy* Pred, NodeSet& Dst);
Ted Kremenek874d63f2008-01-24 02:02:54 +0000670
671 /// VisitCast - Transfer function logic for all casts (implicit and explicit).
672 void VisitCast(Expr* CastE, Expr* E, NodeTy* Pred, NodeSet& Dst);
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000673
Ted Kremenek7b8009a2008-01-24 02:28:56 +0000674 /// VisitUnaryOperator - Transfer function logic for unary operators.
675 void VisitUnaryOperator(UnaryOperator* B, NodeTy* Pred, NodeSet& Dst);
676
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000677 /// VisitBinaryOperator - Transfer function logic for binary operators.
Ted Kremenek9de04c42008-01-24 20:55:43 +0000678 void VisitBinaryOperator(BinaryOperator* B, NodeTy* Pred, NodeSet& Dst);
679
680 /// VisitDeclStmt - Transfer function logic for DeclStmts.
681 void VisitDeclStmt(DeclStmt* DS, NodeTy* Pred, NodeSet& Dst);
Ted Kremenekd27f8162008-01-15 23:55:06 +0000682};
683} // end anonymous namespace
684
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000685
Ted Kremenekd27f8162008-01-15 23:55:06 +0000686void GRConstants::ProcessStmt(Stmt* S, NodeBuilder& builder) {
687 Builder = &builder;
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000688
689 StmtEntryNode = builder.getLastNode();
690 CurrentStmt = S;
691 NodeSet Dst;
692 StateCleaned = false;
693
694 Visit(S, StmtEntryNode, Dst);
695
696 // If no nodes were generated, generate a new node that has all the
697 // dead mappings removed.
698 if (Dst.size() == 1 && *Dst.begin() == StmtEntryNode) {
699 StateTy St = RemoveDeadBindings(S, StmtEntryNode->getState());
700 builder.generateNode(S, St, StmtEntryNode);
701 }
Ted Kremenekf84469b2008-01-18 00:41:32 +0000702
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000703 CurrentStmt = NULL;
704 StmtEntryNode = NULL;
705 Builder = NULL;
Ted Kremenekd27f8162008-01-15 23:55:06 +0000706}
707
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000708
709ExprValue GRConstants::GetValue(const StateTy& St, const LValue& LV) {
Ted Kremenekf13794e2008-01-24 23:19:54 +0000710 switch (LV.getSubKind()) {
711 case LValueDeclKind: {
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000712 StateTy::TreeTy* T = St.SlimFind(cast<LValueDecl>(LV).getDecl());
713 return T ? T->getValue().second : InvalidValue();
714 }
715 default:
716 assert (false && "Invalid LValue.");
Ted Kremenekca3e8572008-01-16 22:28:08 +0000717 break;
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000718 }
719
720 return InvalidValue();
721}
722
723ExprValue GRConstants::GetValue(const StateTy& St, Stmt* S) {
Ted Kremenek671c9e82008-01-24 00:50:08 +0000724 for (;;) {
725 switch (S->getStmtClass()) {
726 case Stmt::ParenExprClass:
727 S = cast<ParenExpr>(S)->getSubExpr();
728 continue;
729
730 case Stmt::DeclRefExprClass:
731 return GetValue(St, LValueDecl(cast<DeclRefExpr>(S)->getDecl()));
Ted Kremenekca3e8572008-01-16 22:28:08 +0000732
Ted Kremenek671c9e82008-01-24 00:50:08 +0000733 case Stmt::IntegerLiteralClass:
Ted Kremenekdacbb4f2008-01-24 08:20:02 +0000734 return RValue::GetRValue(ValMgr, cast<IntegerLiteral>(S));
Ted Kremenek874d63f2008-01-24 02:02:54 +0000735
736 case Stmt::ImplicitCastExprClass: {
737 ImplicitCastExpr* C = cast<ImplicitCastExpr>(S);
738 if (C->getType() == C->getSubExpr()->getType()) {
739 S = C->getSubExpr();
740 continue;
741 }
742 break;
743 }
744
745 case Stmt::CastExprClass: {
746 CastExpr* C = cast<CastExpr>(S);
747 if (C->getType() == C->getSubExpr()->getType()) {
748 S = C->getSubExpr();
749 continue;
750 }
751 break;
752 }
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000753
Ted Kremenek671c9e82008-01-24 00:50:08 +0000754 default:
755 break;
756 };
757
758 break;
759 }
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000760
Ted Kremenek5c1b9962008-01-24 19:43:37 +0000761 StateTy::TreeTy* T = St.SlimFind(S);
Ted Kremenek874d63f2008-01-24 02:02:54 +0000762
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000763 return T ? T->getValue().second : InvalidValue();
764}
765
766LValue GRConstants::GetLValue(const StateTy& St, Stmt* S) {
767 if (Expr* E = dyn_cast<Expr>(S))
768 S = E->IgnoreParens();
769
770 if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(S))
771 return LValueDecl(DR->getDecl());
772
773 return cast<LValue>(GetValue(St, S));
774}
775
776GRConstants::StateTy GRConstants::SetValue(StateTy St, Stmt* S,
Ted Kremenekdaadf452008-01-24 19:28:01 +0000777 const ExprValue& V) {
Ted Kremenekcc1c3652008-01-25 23:43:12 +0000778 assert (S);
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000779
780 if (!StateCleaned) {
781 St = RemoveDeadBindings(CurrentStmt, St);
782 StateCleaned = true;
783 }
784
Ted Kremenek9ff731d2008-01-24 22:27:20 +0000785 bool isBlkExpr = false;
786
787 if (S == CurrentStmt) {
788 isBlkExpr = getCFG().isBlkExpr(S);
789
790 if (!isBlkExpr)
791 return St;
792 }
Ted Kremenekdaadf452008-01-24 19:28:01 +0000793
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000794 return V.isValid() ? StateMgr.Add(St, ValueKey(S,isBlkExpr), V)
795 : St;
796}
797
798GRConstants::StateTy GRConstants::SetValue(StateTy St, const LValue& LV,
799 const ExprValue& V) {
800 if (!LV.isValid())
801 return St;
802
803 if (!StateCleaned) {
804 St = RemoveDeadBindings(CurrentStmt, St);
805 StateCleaned = true;
Ted Kremenekca3e8572008-01-16 22:28:08 +0000806 }
Ted Kremenek0525a4f2008-01-16 19:47:19 +0000807
Ted Kremenekf13794e2008-01-24 23:19:54 +0000808 switch (LV.getSubKind()) {
809 case LValueDeclKind:
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000810 return V.isValid() ? StateMgr.Add(St, cast<LValueDecl>(LV).getDecl(), V)
811 : StateMgr.Remove(St, cast<LValueDecl>(LV).getDecl());
812
813 default:
814 assert ("SetValue for given LValue type not yet implemented.");
815 return St;
816 }
Ted Kremenekd27f8162008-01-15 23:55:06 +0000817}
818
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000819GRConstants::StateTy GRConstants::RemoveDeadBindings(Stmt* Loc, StateTy M) {
Ted Kremenekf84469b2008-01-18 00:41:32 +0000820 // Note: in the code below, we can assign a new map to M since the
821 // iterators are iterating over the tree of the *original* map.
Ted Kremenekf84469b2008-01-18 00:41:32 +0000822 StateTy::iterator I = M.begin(), E = M.end();
823
Ted Kremenek5c1b9962008-01-24 19:43:37 +0000824 // Remove old bindings for subexpressions and "dead" block-level expressions.
825 for (; I!=E && !I.getKey().isDecl(); ++I) {
826 if (I.getKey().isSubExpr() || !Liveness->isLive(Loc,cast<Stmt>(I.getKey())))
827 M = StateMgr.Remove(M, I.getKey());
828 }
Ted Kremenekf84469b2008-01-18 00:41:32 +0000829
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000830 // Remove bindings for "dead" decls.
Ted Kremenek5c1b9962008-01-24 19:43:37 +0000831 for (; I!=E ; ++I) {
832 assert (I.getKey().isDecl());
833
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000834 if (VarDecl* V = dyn_cast<VarDecl>(cast<ValueDecl>(I.getKey())))
835 if (!Liveness->isLive(Loc, V))
836 M = StateMgr.Remove(M, I.getKey());
Ted Kremenek5c1b9962008-01-24 19:43:37 +0000837 }
Ted Kremenek565256e2008-01-24 22:44:24 +0000838
Ted Kremeneke00fe3f2008-01-17 00:52:48 +0000839 return M;
Ted Kremeneke00fe3f2008-01-17 00:52:48 +0000840}
841
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000842void GRConstants::Nodify(NodeSet& Dst, Stmt* S, GRConstants::NodeTy* Pred,
843 GRConstants::StateTy St) {
844
845 // If the state hasn't changed, don't generate a new node.
846 if (St == Pred->getState())
847 return;
Ted Kremenekcb448ca2008-01-16 00:53:15 +0000848
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000849 Dst.Add(Builder->generateNode(S, St, Pred));
Ted Kremenekcb448ca2008-01-16 00:53:15 +0000850}
Ted Kremenekd27f8162008-01-15 23:55:06 +0000851
Ted Kremenek874d63f2008-01-24 02:02:54 +0000852void GRConstants::VisitCast(Expr* CastE, Expr* E, GRConstants::NodeTy* Pred,
853 GRConstants::NodeSet& Dst) {
854
855 QualType T = CastE->getType();
856
857 // Check for redundant casts.
858 if (E->getType() == T) {
859 Dst.Add(Pred);
860 return;
861 }
862
863 NodeSet S1;
864 Visit(E, Pred, S1);
865
866 for (NodeSet::iterator I1=S1.begin(), E1=S1.end(); I1 != E1; ++I1) {
867 NodeTy* N = *I1;
868 StateTy St = N->getState();
869 const ExprValue& V = GetValue(St, E);
870 Nodify(Dst, CastE, N, SetValue(St, CastE, V.EvalCast(ValMgr, CastE)));
871 }
Ted Kremenek9de04c42008-01-24 20:55:43 +0000872}
873
874void GRConstants::VisitDeclStmt(DeclStmt* DS, GRConstants::NodeTy* Pred,
875 GRConstants::NodeSet& Dst) {
876
877 StateTy St = Pred->getState();
878
879 for (const ScopedDecl* D = DS->getDecl(); D; D = D->getNextDeclarator())
880 if (const VarDecl* VD = dyn_cast<VarDecl>(D))
881 St = SetValue(St, LValueDecl(VD), GetValue(St, VD->getInit()));
882
883 Nodify(Dst, DS, Pred, St);
884
885 if (Dst.empty())
886 Dst.Add(Pred);
887}
Ted Kremenek874d63f2008-01-24 02:02:54 +0000888
Ted Kremenek7b8009a2008-01-24 02:28:56 +0000889void GRConstants::VisitUnaryOperator(UnaryOperator* U,
890 GRConstants::NodeTy* Pred,
891 GRConstants::NodeSet& Dst) {
892 NodeSet S1;
893 Visit(U->getSubExpr(), Pred, S1);
894
895 for (NodeSet::iterator I1=S1.begin(), E1=S1.end(); I1 != E1; ++I1) {
896 NodeTy* N1 = *I1;
897 StateTy St = N1->getState();
898
899 switch (U->getOpcode()) {
900 case UnaryOperator::PostInc: {
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());
Ted Kremenek5ee4ff82008-01-25 22:55:56 +0000906 APSInt One(llvm::APInt(bits, 1), T->isUnsignedIntegerType());
Ted Kremeneke0cf9c82008-01-24 19:00:57 +0000907 RValue R2 = RValue::GetRValue(ValMgr, One);
908
Ted Kremenek7b8009a2008-01-24 02:28:56 +0000909 RValue Result = R1.EvalAdd(ValMgr, R2);
910 Nodify(Dst, U, N1, SetValue(SetValue(St, U, R1), L1, Result));
911 break;
912 }
913
914 case UnaryOperator::PostDec: {
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());
Ted Kremenek5ee4ff82008-01-25 22:55:56 +0000920 APSInt One(llvm::APInt(bits, 1), T->isUnsignedIntegerType());
Ted Kremeneke0cf9c82008-01-24 19:00:57 +0000921 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, R1), L1, Result));
925 break;
926 }
927
928 case UnaryOperator::PreInc: {
929 const LValue& L1 = GetLValue(St, U->getSubExpr());
930 RValue R1 = cast<RValue>(GetValue(St, L1));
931
932 QualType T = U->getType();
Ted Kremeneke0cf9c82008-01-24 19:00:57 +0000933 unsigned bits = getContext()->getTypeSize(T, U->getLocStart());
Ted Kremenek5ee4ff82008-01-25 22:55:56 +0000934 APSInt One(llvm::APInt(bits, 1), T->isUnsignedIntegerType());
Ted Kremenek7b8009a2008-01-24 02:28:56 +0000935 RValue R2 = RValue::GetRValue(ValMgr, One);
936
937 RValue Result = R1.EvalAdd(ValMgr, R2);
938 Nodify(Dst, U, N1, SetValue(SetValue(St, U, Result), L1, Result));
939 break;
940 }
941
942 case UnaryOperator::PreDec: {
943 const LValue& L1 = GetLValue(St, U->getSubExpr());
944 RValue R1 = cast<RValue>(GetValue(St, L1));
945
946 QualType T = U->getType();
Ted Kremeneke0cf9c82008-01-24 19:00:57 +0000947 unsigned bits = getContext()->getTypeSize(T, U->getLocStart());
Ted Kremenek5ee4ff82008-01-25 22:55:56 +0000948 APSInt One(llvm::APInt(bits, 1), T->isUnsignedIntegerType());
Ted Kremeneke0cf9c82008-01-24 19:00:57 +0000949 RValue R2 = RValue::GetRValue(ValMgr, One);
Ted Kremenek7b8009a2008-01-24 02:28:56 +0000950
951 RValue Result = R1.EvalSub(ValMgr, R2);
952 Nodify(Dst, U, N1, SetValue(SetValue(St, U, Result), L1, Result));
953 break;
954 }
955
Ted Kremenekdacbb4f2008-01-24 08:20:02 +0000956 case UnaryOperator::Minus: {
957 const RValue& R1 = cast<RValue>(GetValue(St, U->getSubExpr()));
958 Nodify(Dst, U, N1, SetValue(St, U, R1.EvalMinus(ValMgr, U)));
959 break;
960 }
961
Ted Kremenek7b8009a2008-01-24 02:28:56 +0000962 default: ;
963 assert (false && "Not implemented.");
964 }
965 }
966}
967
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000968void GRConstants::VisitBinaryOperator(BinaryOperator* B,
969 GRConstants::NodeTy* Pred,
970 GRConstants::NodeSet& Dst) {
971 NodeSet S1;
972 Visit(B->getLHS(), Pred, S1);
Ted Kremenekcb448ca2008-01-16 00:53:15 +0000973
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000974 for (NodeSet::iterator I1=S1.begin(), E1=S1.end(); I1 != E1; ++I1) {
975 NodeTy* N1 = *I1;
Ted Kremeneke00fe3f2008-01-17 00:52:48 +0000976
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000977 // When getting the value for the LHS, check if we are in an assignment.
978 // In such cases, we want to (initially) treat the LHS as an LValue,
979 // so we use GetLValue instead of GetValue so that DeclRefExpr's are
980 // evaluated to LValueDecl's instead of to an RValue.
981 const ExprValue& V1 =
982 B->isAssignmentOp() ? GetLValue(N1->getState(), B->getLHS())
983 : GetValue(N1->getState(), B->getLHS());
Ted Kremenekcb448ca2008-01-16 00:53:15 +0000984
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000985 NodeSet S2;
986 Visit(B->getRHS(), N1, S2);
987
988 for (NodeSet::iterator I2=S2.begin(), E2=S2.end(); I2 != E2; ++I2) {
989 NodeTy* N2 = *I2;
990 StateTy St = N2->getState();
991 const ExprValue& V2 = GetValue(St, B->getRHS());
992
993 switch (B->getOpcode()) {
994 case BinaryOperator::Add: {
995 const RValue& R1 = cast<RValue>(V1);
996 const RValue& R2 = cast<RValue>(V2);
997
Ted Kremenek874d63f2008-01-24 02:02:54 +0000998 Nodify(Dst, B, N2, SetValue(St, B, R1.EvalAdd(ValMgr, R2)));
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000999 break;
1000 }
1001
1002 case BinaryOperator::Sub: {
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.EvalSub(ValMgr, R2)));
Ted Kremenekab2b8c52008-01-23 19:59:44 +00001006 break;
1007 }
1008
Ted Kremenek2eafd0e2008-01-23 23:42:27 +00001009 case BinaryOperator::Mul: {
1010 const RValue& R1 = cast<RValue>(V1);
1011 const RValue& R2 = cast<RValue>(V2);
Ted Kremenek874d63f2008-01-24 02:02:54 +00001012 Nodify(Dst, B, N2, SetValue(St, B, R1.EvalMul(ValMgr, R2)));
Ted Kremenek2eafd0e2008-01-23 23:42:27 +00001013 break;
1014 }
1015
Ted Kremenek5ee4ff82008-01-25 22:55:56 +00001016 case BinaryOperator::Div: {
1017 const RValue& R1 = cast<RValue>(V1);
1018 const RValue& R2 = cast<RValue>(V2);
1019 Nodify(Dst, B, N2, SetValue(St, B, R1.EvalDiv(ValMgr, R2)));
1020 break;
1021 }
1022
Ted Kremenekab2b8c52008-01-23 19:59:44 +00001023 case BinaryOperator::Assign: {
1024 const LValue& L1 = cast<LValue>(V1);
1025 const RValue& R2 = cast<RValue>(V2);
Ted Kremenekab2b8c52008-01-23 19:59:44 +00001026 Nodify(Dst, B, N2, SetValue(SetValue(St, B, R2), L1, R2));
1027 break;
1028 }
Ted Kremenekb4ae33f2008-01-23 23:38:00 +00001029
1030 case BinaryOperator::AddAssign: {
1031 const LValue& L1 = cast<LValue>(V1);
1032 RValue R1 = cast<RValue>(GetValue(N1->getState(), L1));
Ted Kremenek874d63f2008-01-24 02:02:54 +00001033 RValue Result = R1.EvalAdd(ValMgr, cast<RValue>(V2));
Ted Kremenekb4ae33f2008-01-23 23:38:00 +00001034 Nodify(Dst, B, N2, SetValue(SetValue(St, B, Result), L1, Result));
1035 break;
1036 }
1037
1038 case BinaryOperator::SubAssign: {
1039 const LValue& L1 = cast<LValue>(V1);
1040 RValue R1 = cast<RValue>(GetValue(N1->getState(), L1));
Ted Kremenek874d63f2008-01-24 02:02:54 +00001041 RValue Result = R1.EvalSub(ValMgr, cast<RValue>(V2));
Ted Kremenekb4ae33f2008-01-23 23:38:00 +00001042 Nodify(Dst, B, N2, SetValue(SetValue(St, B, Result), L1, Result));
1043 break;
1044 }
Ted Kremenek2eafd0e2008-01-23 23:42:27 +00001045
1046 case BinaryOperator::MulAssign: {
1047 const LValue& L1 = cast<LValue>(V1);
1048 RValue R1 = cast<RValue>(GetValue(N1->getState(), L1));
Ted Kremenek874d63f2008-01-24 02:02:54 +00001049 RValue Result = R1.EvalMul(ValMgr, cast<RValue>(V2));
Ted Kremenek2eafd0e2008-01-23 23:42:27 +00001050 Nodify(Dst, B, N2, SetValue(SetValue(St, B, Result), L1, Result));
1051 break;
1052 }
Ted Kremenek5c1e2622008-01-25 23:45:34 +00001053
1054 case BinaryOperator::DivAssign: {
1055 const LValue& L1 = cast<LValue>(V1);
1056 RValue R1 = cast<RValue>(GetValue(N1->getState(), L1));
1057 RValue Result = R1.EvalDiv(ValMgr, cast<RValue>(V2));
1058 Nodify(Dst, B, N2, SetValue(SetValue(St, B, Result), L1, Result));
1059 break;
1060 }
Ted Kremenekab2b8c52008-01-23 19:59:44 +00001061
1062 default:
1063 Dst.Add(N2);
1064 break;
1065 }
Ted Kremenekcb448ca2008-01-16 00:53:15 +00001066 }
Ted Kremenekd27f8162008-01-15 23:55:06 +00001067 }
Ted Kremenekd27f8162008-01-15 23:55:06 +00001068}
Ted Kremenekee985462008-01-16 18:18:48 +00001069
Ted Kremenek1ccd31c2008-01-16 19:42:59 +00001070
Ted Kremenekab2b8c52008-01-23 19:59:44 +00001071void GRConstants::Visit(Stmt* S, GRConstants::NodeTy* Pred,
1072 GRConstants::NodeSet& Dst) {
1073
1074 // FIXME: add metadata to the CFG so that we can disable
1075 // this check when we KNOW that there is no block-level subexpression.
1076 // The motivation is that this check requires a hashtable lookup.
1077
1078 if (S != CurrentStmt && getCFG().isBlkExpr(S)) {
1079 Dst.Add(Pred);
1080 return;
1081 }
1082
1083 switch (S->getStmtClass()) {
1084 case Stmt::BinaryOperatorClass:
Ted Kremenekb4ae33f2008-01-23 23:38:00 +00001085 case Stmt::CompoundAssignOperatorClass:
Ted Kremenekab2b8c52008-01-23 19:59:44 +00001086 VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Dst);
1087 break;
1088
Ted Kremenek7b8009a2008-01-24 02:28:56 +00001089 case Stmt::UnaryOperatorClass:
1090 VisitUnaryOperator(cast<UnaryOperator>(S), Pred, Dst);
1091 break;
1092
Ted Kremenekab2b8c52008-01-23 19:59:44 +00001093 case Stmt::ParenExprClass:
1094 Visit(cast<ParenExpr>(S)->getSubExpr(), Pred, Dst);
1095 break;
1096
Ted Kremenek874d63f2008-01-24 02:02:54 +00001097 case Stmt::ImplicitCastExprClass: {
1098 ImplicitCastExpr* C = cast<ImplicitCastExpr>(S);
1099 VisitCast(C, C->getSubExpr(), Pred, Dst);
1100 break;
1101 }
1102
1103 case Stmt::CastExprClass: {
1104 CastExpr* C = cast<CastExpr>(S);
1105 VisitCast(C, C->getSubExpr(), Pred, Dst);
1106 break;
1107 }
1108
Ted Kremenek9de04c42008-01-24 20:55:43 +00001109 case Stmt::DeclStmtClass:
1110 VisitDeclStmt(cast<DeclStmt>(S), Pred, Dst);
1111 break;
1112
Ted Kremenekab2b8c52008-01-23 19:59:44 +00001113 default:
1114 Dst.Add(Pred); // No-op. Simply propagate the current state unchanged.
1115 break;
Ted Kremenek79649df2008-01-17 18:25:22 +00001116 }
Ted Kremenek1ccd31c2008-01-16 19:42:59 +00001117}
1118
Ted Kremenekee985462008-01-16 18:18:48 +00001119//===----------------------------------------------------------------------===//
1120// Driver.
1121//===----------------------------------------------------------------------===//
1122
Ted Kremenekaa66a322008-01-16 21:46:15 +00001123#ifndef NDEBUG
1124namespace llvm {
1125template<>
1126struct VISIBILITY_HIDDEN DOTGraphTraits<GRConstants::NodeTy*> :
1127 public DefaultDOTGraphTraits {
Ted Kremenek9ff731d2008-01-24 22:27:20 +00001128
1129 static void PrintKindLabel(std::ostream& Out, ValueKey::Kind kind) {
Ted Kremenek803c9ed2008-01-23 22:30:44 +00001130 switch (kind) {
Ted Kremenek565256e2008-01-24 22:44:24 +00001131 case ValueKey::IsSubExpr: Out << "Sub-Expressions:\\l"; break;
Ted Kremenek803c9ed2008-01-23 22:30:44 +00001132 case ValueKey::IsDecl: Out << "Variables:\\l"; break;
1133 case ValueKey::IsBlkExpr: Out << "Block-level Expressions:\\l"; break;
1134 default: assert (false && "Unknown ValueKey type.");
1135 }
1136 }
1137
Ted Kremenek9ff731d2008-01-24 22:27:20 +00001138 static void PrintKind(std::ostream& Out, GRConstants::StateTy M,
1139 ValueKey::Kind kind, bool isFirstGroup = false) {
1140 bool isFirst = true;
1141
1142 for (GRConstants::StateTy::iterator I=M.begin(), E=M.end();I!=E;++I) {
1143 if (I.getKey().getKind() != kind)
1144 continue;
1145
1146 if (isFirst) {
1147 if (!isFirstGroup) Out << "\\l\\l";
1148 PrintKindLabel(Out, kind);
1149 isFirst = false;
1150 }
1151 else
1152 Out << "\\l";
1153
1154 Out << ' ';
1155
1156 if (ValueDecl* V = dyn_cast<ValueDecl>(I.getKey()))
1157 Out << V->getName();
1158 else {
1159 Stmt* E = cast<Stmt>(I.getKey());
1160 Out << " (" << (void*) E << ") ";
1161 E->printPretty(Out);
1162 }
1163
1164 Out << " : ";
1165 I.getData().print(Out);
1166 }
1167 }
1168
Ted Kremenekaa66a322008-01-16 21:46:15 +00001169 static std::string getNodeLabel(const GRConstants::NodeTy* N, void*) {
1170 std::ostringstream Out;
Ted Kremenek803c9ed2008-01-23 22:30:44 +00001171
1172 // Program Location.
Ted Kremenekaa66a322008-01-16 21:46:15 +00001173 ProgramPoint Loc = N->getLocation();
1174
1175 switch (Loc.getKind()) {
1176 case ProgramPoint::BlockEntranceKind:
1177 Out << "Block Entrance: B"
1178 << cast<BlockEntrance>(Loc).getBlock()->getBlockID();
1179 break;
1180
1181 case ProgramPoint::BlockExitKind:
1182 assert (false);
1183 break;
1184
1185 case ProgramPoint::PostStmtKind: {
1186 const PostStmt& L = cast<PostStmt>(Loc);
Ted Kremenek9ff731d2008-01-24 22:27:20 +00001187 Out << L.getStmt()->getStmtClassName() << ':'
1188 << (void*) L.getStmt() << ' ';
1189
Ted Kremenekaa66a322008-01-16 21:46:15 +00001190 L.getStmt()->printPretty(Out);
1191 break;
1192 }
1193
1194 default: {
1195 const BlockEdge& E = cast<BlockEdge>(Loc);
1196 Out << "Edge: (B" << E.getSrc()->getBlockID() << ", B"
1197 << E.getDst()->getBlockID() << ')';
1198 }
1199 }
1200
Ted Kremenek803c9ed2008-01-23 22:30:44 +00001201 Out << "\\|";
Ted Kremenekaa66a322008-01-16 21:46:15 +00001202
Ted Kremenek9ff731d2008-01-24 22:27:20 +00001203 PrintKind(Out, N->getState(), ValueKey::IsDecl, true);
1204 PrintKind(Out, N->getState(), ValueKey::IsBlkExpr);
Ted Kremenek565256e2008-01-24 22:44:24 +00001205 PrintKind(Out, N->getState(), ValueKey::IsSubExpr);
Ted Kremenek803c9ed2008-01-23 22:30:44 +00001206
Ted Kremenek803c9ed2008-01-23 22:30:44 +00001207 Out << "\\l";
Ted Kremenekaa66a322008-01-16 21:46:15 +00001208 return Out.str();
1209 }
1210};
1211} // end llvm namespace
1212#endif
1213
Ted Kremenekee985462008-01-16 18:18:48 +00001214namespace clang {
Ted Kremenek874d63f2008-01-24 02:02:54 +00001215void RunGRConstants(CFG& cfg, ASTContext& Ctx) {
1216 GREngine<GRConstants> Engine(cfg, Ctx);
Ted Kremenekee985462008-01-16 18:18:48 +00001217 Engine.ExecuteWorkList();
Ted Kremenekaa66a322008-01-16 21:46:15 +00001218#ifndef NDEBUG
1219 llvm::ViewGraph(*Engine.getGraph().roots_begin(),"GRConstants");
1220#endif
Ted Kremenekee985462008-01-16 18:18:48 +00001221}
Ted Kremenekab2b8c52008-01-23 19:59:44 +00001222} // end clang namespace