blob: 27f7a639a276e56354b8f5c66276736064381966 [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
Ted Kremenek2cd65c82008-01-25 22:06:07 +0000247enum { RValueDisjunctiveEqualKind = 0x0, NumRValueKind };
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000248
Ted Kremenek2cd65c82008-01-25 22:06:07 +0000249class VISIBILITY_HIDDEN RValueDisjunctiveEqual : public RValue {
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000250public:
Ted Kremenek2cd65c82008-01-25 22:06:07 +0000251 RValueDisjunctiveEqual(const APSIntSetTy& S)
252 : RValue(RValueDisjunctiveEqualKind, S.getRoot()) {}
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000253
254 APSIntSetTy GetValues() const {
255 return APSIntSetTy(reinterpret_cast<APSIntSetTy::TreeTy*>(getRawPtr()));
256 }
257
Ted Kremenek2cd65c82008-01-25 22:06:07 +0000258 RValueDisjunctiveEqual
259 EvalAdd(ValueManager& ValMgr, const RValueDisjunctiveEqual& V) const;
Ted Kremenek874d63f2008-01-24 02:02:54 +0000260
Ted Kremenek2cd65c82008-01-25 22:06:07 +0000261 RValueDisjunctiveEqual
262 EvalSub(ValueManager& ValMgr, const RValueDisjunctiveEqual& V) const;
Ted Kremenek874d63f2008-01-24 02:02:54 +0000263
Ted Kremenek2cd65c82008-01-25 22:06:07 +0000264 RValueDisjunctiveEqual
265 EvalMul(ValueManager& ValMgr, const RValueDisjunctiveEqual& V) const;
Ted Kremenek874d63f2008-01-24 02:02:54 +0000266
Ted Kremenek2cd65c82008-01-25 22:06:07 +0000267 RValueDisjunctiveEqual
268 EvalCast(ValueManager& ValMgr, Expr* CastExpr) const;
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000269
Ted Kremenek2cd65c82008-01-25 22:06:07 +0000270 RValueDisjunctiveEqual
271 EvalMinus(ValueManager& ValMgr, UnaryOperator* U) const;
Ted Kremenekdacbb4f2008-01-24 08:20:02 +0000272
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000273 // Implement isa<T> support.
274 static inline bool classof(const ExprValue* V) {
Ted Kremenek2cd65c82008-01-25 22:06:07 +0000275 return V->getSubKind() == RValueDisjunctiveEqualKind;
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000276 }
277};
278} // end anonymous namespace
279
280//===----------------------------------------------------------------------===//
Ted Kremenek874d63f2008-01-24 02:02:54 +0000281// Transfer functions: Casts.
282//===----------------------------------------------------------------------===//
283
284ExprValue ExprValue::EvalCast(ValueManager& ValMgr, Expr* CastExpr) const {
Ted Kremenekf13794e2008-01-24 23:19:54 +0000285 switch (getSubKind()) {
Ted Kremenek2cd65c82008-01-25 22:06:07 +0000286 case RValueDisjunctiveEqualKind:
287 return cast<RValueDisjunctiveEqual>(this)->EvalCast(ValMgr, CastExpr);
Ted Kremenek874d63f2008-01-24 02:02:54 +0000288 default:
289 return InvalidValue();
290 }
291}
292
Ted Kremenek2cd65c82008-01-25 22:06:07 +0000293RValueDisjunctiveEqual
294RValueDisjunctiveEqual::EvalCast(ValueManager& ValMgr, Expr* CastExpr) const {
Ted Kremenek874d63f2008-01-24 02:02:54 +0000295 QualType T = CastExpr->getType();
296 assert (T->isIntegerType());
297
298 APSIntSetTy S1 = GetValues();
299 APSIntSetTy S2 = ValMgr.GetEmptyAPSIntSet();
300
301 for (APSIntSetTy::iterator I=S1.begin(), E=S1.end(); I!=E; ++I) {
302 llvm::APSInt X = *I;
303 X.setIsSigned(T->isSignedIntegerType());
304 X.extOrTrunc(ValMgr.getContext()->getTypeSize(T,CastExpr->getLocStart()));
305 S2 = ValMgr.AddToSet(S2, X);
306 }
307
308 return S2;
309}
310
311//===----------------------------------------------------------------------===//
Ted Kremenekdacbb4f2008-01-24 08:20:02 +0000312// Transfer functions: Unary Operations over R-Values.
313//===----------------------------------------------------------------------===//
314
315RValue RValue::EvalMinus(ValueManager& ValMgr, UnaryOperator* U) const {
Ted Kremenekf13794e2008-01-24 23:19:54 +0000316 switch (getSubKind()) {
Ted Kremenek2cd65c82008-01-25 22:06:07 +0000317 case RValueDisjunctiveEqualKind:
318 return cast<RValueDisjunctiveEqual>(this)->EvalMinus(ValMgr, U);
Ted Kremenekdacbb4f2008-01-24 08:20:02 +0000319 default:
320 return cast<RValue>(InvalidValue());
321 }
322}
323
Ted Kremenek2cd65c82008-01-25 22:06:07 +0000324RValueDisjunctiveEqual
325RValueDisjunctiveEqual::EvalMinus(ValueManager& ValMgr, UnaryOperator* U) const{
Ted Kremenekdacbb4f2008-01-24 08:20:02 +0000326
327 assert (U->getType() == U->getSubExpr()->getType());
328 assert (U->getType()->isIntegerType());
329
330 APSIntSetTy S1 = GetValues();
331 APSIntSetTy S2 = ValMgr.GetEmptyAPSIntSet();
332
333 for (APSIntSetTy::iterator I=S1.begin(), E=S1.end(); I!=E; ++I) {
334 assert ((*I).isSigned());
335
336 // FIXME: Shouldn't operator- on APSInt return an APSInt with the proper
337 // sign?
338 llvm::APSInt X(-(*I));
339 X.setIsSigned(true);
340
341 S2 = ValMgr.AddToSet(S2, X);
342 }
343
344 return S2;
345}
346
Ted Kremenekdacbb4f2008-01-24 08:20:02 +0000347//===----------------------------------------------------------------------===//
Ted Kremenek874d63f2008-01-24 02:02:54 +0000348// Transfer functions: Binary Operations over R-Values.
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000349//===----------------------------------------------------------------------===//
350
351#define RVALUE_DISPATCH_CASE(k1,k2,Op)\
Ted Kremenekf13794e2008-01-24 23:19:54 +0000352case (k1##Kind*NumRValueKind+k2##Kind):\
Ted Kremenek874d63f2008-01-24 02:02:54 +0000353 return cast<k1>(*this).Eval##Op(ValMgr,cast<k2>(RHS));
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000354
355#define RVALUE_DISPATCH(Op)\
Ted Kremenekf13794e2008-01-24 23:19:54 +0000356switch (getSubKind()*NumRValueKind+RHS.getSubKind()){\
Ted Kremenek2cd65c82008-01-25 22:06:07 +0000357 RVALUE_DISPATCH_CASE(RValueDisjunctiveEqual,RValueDisjunctiveEqual,Op)\
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000358 default:\
359 assert (!isValid() || !RHS.isValid() && "Missing case.");\
360 break;\
361}\
362return cast<RValue>(InvalidValue());
363
Ted Kremenek874d63f2008-01-24 02:02:54 +0000364RValue RValue::EvalAdd(ValueManager& ValMgr, const RValue& RHS) const {
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000365 RVALUE_DISPATCH(Add)
366}
367
Ted Kremenek874d63f2008-01-24 02:02:54 +0000368RValue RValue::EvalSub(ValueManager& ValMgr, const RValue& RHS) const {
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000369 RVALUE_DISPATCH(Sub)
370}
371
Ted Kremenek874d63f2008-01-24 02:02:54 +0000372RValue RValue::EvalMul(ValueManager& ValMgr, const RValue& RHS) const {
Ted Kremenek2eafd0e2008-01-23 23:42:27 +0000373 RVALUE_DISPATCH(Mul)
374}
375
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000376#undef RVALUE_DISPATCH_CASE
377#undef RVALUE_DISPATCH
378
Ted Kremenek2cd65c82008-01-25 22:06:07 +0000379RValueDisjunctiveEqual
380RValueDisjunctiveEqual::EvalAdd(ValueManager& ValMgr,
381 const RValueDisjunctiveEqual& RHS) const {
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000382
383 APSIntSetTy S1 = GetValues();
384 APSIntSetTy S2 = RHS.GetValues();
385
386 APSIntSetTy M = ValMgr.GetEmptyAPSIntSet();
387
388 for (APSIntSetTy::iterator I1=S1.begin(), E1=S2.end(); I1!=E1; ++I1)
Ted Kremenekdacbb4f2008-01-24 08:20:02 +0000389 for (APSIntSetTy::iterator I2=S2.begin(), E2=S2.end(); I2!=E2; ++I2) {
390 // FIXME: operator- on APSInt is really operator* on APInt, which loses
391 // the "signess" information (although the bits are correct).
392 const llvm::APSInt& X = *I1;
393 llvm::APSInt Y = X + *I2;
394 Y.setIsSigned(X.isSigned());
395 M = ValMgr.AddToSet(M, Y);
396 }
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000397
398 return M;
399}
400
Ted Kremenek2cd65c82008-01-25 22:06:07 +0000401RValueDisjunctiveEqual
402RValueDisjunctiveEqual::EvalSub(ValueManager& ValMgr,
403 const RValueDisjunctiveEqual& RHS) const {
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000404
405 APSIntSetTy S1 = GetValues();
406 APSIntSetTy S2 = RHS.GetValues();
407
408 APSIntSetTy M = ValMgr.GetEmptyAPSIntSet();
409
410 for (APSIntSetTy::iterator I1=S1.begin(), E1=S2.end(); I1!=E1; ++I1)
Ted Kremenekdacbb4f2008-01-24 08:20:02 +0000411 for (APSIntSetTy::iterator I2=S2.begin(), E2=S2.end(); I2!=E2; ++I2) {
412 // FIXME: operator- on APSInt is really operator* on APInt, which loses
413 // the "signess" information (although the bits are correct).
414 const llvm::APSInt& X = *I1;
415 llvm::APSInt Y = X - *I2;
416 Y.setIsSigned(X.isSigned());
417 M = ValMgr.AddToSet(M, Y);
418 }
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000419
420 return M;
421}
422
Ted Kremenek2cd65c82008-01-25 22:06:07 +0000423RValueDisjunctiveEqual
424RValueDisjunctiveEqual::EvalMul(ValueManager& ValMgr,
425 const RValueDisjunctiveEqual& RHS) const {
Ted Kremenek2eafd0e2008-01-23 23:42:27 +0000426
427 APSIntSetTy S1 = GetValues();
428 APSIntSetTy S2 = RHS.GetValues();
429
430 APSIntSetTy M = ValMgr.GetEmptyAPSIntSet();
431
432 for (APSIntSetTy::iterator I1=S1.begin(), E1=S2.end(); I1!=E1; ++I1)
Ted Kremenekdacbb4f2008-01-24 08:20:02 +0000433 for (APSIntSetTy::iterator I2=S2.begin(), E2=S2.end(); I2!=E2; ++I2) {
434 // FIXME: operator* on APSInt is really operator* on APInt, which loses
435 // the "signess" information (although the bits are correct).
436 const llvm::APSInt& X = *I1;
437 llvm::APSInt Y = X * *I2;
438 Y.setIsSigned(X.isSigned());
439 M = ValMgr.AddToSet(M, Y);
440 }
Ted Kremenek2eafd0e2008-01-23 23:42:27 +0000441
442 return M;
443}
444
Ted Kremenek7b8009a2008-01-24 02:28:56 +0000445RValue RValue::GetRValue(ValueManager& ValMgr, const llvm::APSInt& V) {
Ted Kremenek2cd65c82008-01-25 22:06:07 +0000446 return RValueDisjunctiveEqual(ValMgr.AddToSet(ValMgr.GetEmptyAPSIntSet(), V));
Ted Kremenekdacbb4f2008-01-24 08:20:02 +0000447}
448
449RValue RValue::GetRValue(ValueManager& ValMgr, IntegerLiteral* I) {
450 llvm::APSInt X(I->getValue());
451 X.setIsSigned(I->getType()->isSignedIntegerType());
452 return GetRValue(ValMgr, X);
453}
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000454
455//===----------------------------------------------------------------------===//
456// "L-Values".
457//===----------------------------------------------------------------------===//
458
459namespace {
Ted Kremenekf13794e2008-01-24 23:19:54 +0000460
461enum { LValueDeclKind=0x0, MaxLValueKind };
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000462
463class VISIBILITY_HIDDEN LValueDecl : public LValue {
464public:
Ted Kremenek9de04c42008-01-24 20:55:43 +0000465 LValueDecl(const ValueDecl* vd)
466 : LValue(LValueDeclKind,const_cast<ValueDecl*>(vd)) {}
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000467
468 ValueDecl* getDecl() const {
469 return static_cast<ValueDecl*>(getRawPtr());
470 }
471
472 // Implement isa<T> support.
473 static inline bool classof(const ExprValue* V) {
Ted Kremenekf13794e2008-01-24 23:19:54 +0000474 return V->getSubKind() == LValueDeclKind;
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000475 }
476};
477} // end anonymous namespace
478
479//===----------------------------------------------------------------------===//
480// Pretty-Printing.
481//===----------------------------------------------------------------------===//
482
483void ExprValue::print(std::ostream& Out) const {
Ted Kremenekf13794e2008-01-24 23:19:54 +0000484 switch (getBaseKind()) {
485 case InvalidKind:
486 Out << "Invalid";
487 break;
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000488
Ted Kremenekf13794e2008-01-24 23:19:54 +0000489 case RValueKind:
490 cast<RValue>(this)->print(Out);
491 break;
492
493 case LValueKind:
494 assert (false && "FIXME: LValue printing not implemented.");
495 break;
496
497 default:
498 assert (false && "Invalid ExprValue.");
499 }
500}
501
502void RValue::print(std::ostream& Out) const {
503 switch (getSubKind()) {
Ted Kremenek2cd65c82008-01-25 22:06:07 +0000504 case RValueDisjunctiveEqualKind: {
505 APSIntSetTy S = cast<RValueDisjunctiveEqual>(this)->GetValues();
Ted Kremenek803c9ed2008-01-23 22:30:44 +0000506 bool first = true;
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000507
Ted Kremenek803c9ed2008-01-23 22:30:44 +0000508 for (APSIntSetTy::iterator I=S.begin(), E=S.end(); I!=E; ++I) {
509 if (first) first = false;
510 else Out << " | ";
511
512 Out << (*I).toString();
513 }
514
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000515 break;
516 }
517
518 default:
Ted Kremenekf13794e2008-01-24 23:19:54 +0000519 assert (false && "Pretty-printed not implemented for this RValue.");
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000520 break;
521 }
522}
523
524//===----------------------------------------------------------------------===//
525// ValueMapTy - A ImmutableMap type Stmt*/Decl* to ExprValues.
526//===----------------------------------------------------------------------===//
527
528typedef llvm::ImmutableMap<ValueKey,ExprValue> ValueMapTy;
529
530namespace clang {
531 template<>
532 struct VISIBILITY_HIDDEN GRTrait<ValueMapTy> {
533 static inline void* toPtr(ValueMapTy M) {
534 return reinterpret_cast<void*>(M.getRoot());
535 }
536 static inline ValueMapTy toState(void* P) {
537 return ValueMapTy(static_cast<ValueMapTy::TreeTy*>(P));
538 }
539 };
Ted Kremenekd27f8162008-01-15 23:55:06 +0000540}
541
542//===----------------------------------------------------------------------===//
543// The Checker!
544//===----------------------------------------------------------------------===//
545
546namespace {
Ted Kremenekd27f8162008-01-15 23:55:06 +0000547
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000548class VISIBILITY_HIDDEN GRConstants {
Ted Kremenekd27f8162008-01-15 23:55:06 +0000549
550public:
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000551 typedef ValueMapTy StateTy;
Ted Kremenekd27f8162008-01-15 23:55:06 +0000552 typedef GRNodeBuilder<GRConstants> NodeBuilder;
553 typedef ExplodedNode<StateTy> NodeTy;
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000554
555 class NodeSet {
556 typedef llvm::SmallVector<NodeTy*,3> ImplTy;
557 ImplTy Impl;
558 public:
559
560 NodeSet() {}
561 NodeSet(NodeTy* N) { assert (N && !N->isInfeasible()); Impl.push_back(N); }
562
563 void Add(NodeTy* N) { if (N && !N->isInfeasible()) Impl.push_back(N); }
564
565 typedef ImplTy::iterator iterator;
566 typedef ImplTy::const_iterator const_iterator;
567
568 unsigned size() const { return Impl.size(); }
Ted Kremenek9de04c42008-01-24 20:55:43 +0000569 bool empty() const { return Impl.empty(); }
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000570
571 iterator begin() { return Impl.begin(); }
572 iterator end() { return Impl.end(); }
573
574 const_iterator begin() const { return Impl.begin(); }
575 const_iterator end() const { return Impl.end(); }
576 };
Ted Kremenekd27f8162008-01-15 23:55:06 +0000577
578protected:
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000579 /// Liveness - live-variables information the ValueDecl* and block-level
580 /// Expr* in the CFG. Used to prune out dead state.
Ted Kremenekd27f8162008-01-15 23:55:06 +0000581 LiveVariables* Liveness;
582
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000583 /// Builder - The current GRNodeBuilder which is used when building the nodes
584 /// for a given statement.
Ted Kremenekd27f8162008-01-15 23:55:06 +0000585 NodeBuilder* Builder;
586
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000587 /// StateMgr - Object that manages the data for all created states.
588 ValueMapTy::Factory StateMgr;
Ted Kremenekd27f8162008-01-15 23:55:06 +0000589
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000590 /// ValueMgr - Object that manages the data for all created ExprValues.
591 ValueManager ValMgr;
592
593 /// cfg - the current CFG.
Ted Kremenekd27f8162008-01-15 23:55:06 +0000594 CFG* cfg;
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000595
596 /// StmtEntryNode - The immediate predecessor node.
597 NodeTy* StmtEntryNode;
598
599 /// CurrentStmt - The current block-level statement.
600 Stmt* CurrentStmt;
601
602 bool StateCleaned;
Ted Kremenekd27f8162008-01-15 23:55:06 +0000603
Ted Kremenek7b8009a2008-01-24 02:28:56 +0000604 ASTContext* getContext() const { return ValMgr.getContext(); }
605
Ted Kremenekd27f8162008-01-15 23:55:06 +0000606public:
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000607 GRConstants() : Liveness(NULL), Builder(NULL), cfg(NULL),
608 StmtEntryNode(NULL), CurrentStmt(NULL) {}
Ted Kremenekd27f8162008-01-15 23:55:06 +0000609
610 ~GRConstants() { delete Liveness; }
611
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000612 /// getCFG - Returns the CFG associated with this analysis.
Ted Kremenekd27f8162008-01-15 23:55:06 +0000613 CFG& getCFG() { assert (cfg); return *cfg; }
614
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000615 /// Initialize - Initialize the checker's state based on the specified
616 /// CFG. This results in liveness information being computed for
617 /// each block-level statement in the CFG.
Ted Kremenek874d63f2008-01-24 02:02:54 +0000618 void Initialize(CFG& c, ASTContext& ctx) {
619 cfg = &c;
620 ValMgr.setContext(&ctx);
Ted Kremenekd27f8162008-01-15 23:55:06 +0000621 Liveness = new LiveVariables(c);
622 Liveness->runOnCFG(c);
Ted Kremenek79649df2008-01-17 18:25:22 +0000623 Liveness->runOnAllBlocks(c, NULL, true);
Ted Kremenekd27f8162008-01-15 23:55:06 +0000624 }
625
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000626 /// getInitialState - Return the initial state used for the root vertex
627 /// in the ExplodedGraph.
Ted Kremenekd27f8162008-01-15 23:55:06 +0000628 StateTy getInitialState() {
Ted Kremenekcb448ca2008-01-16 00:53:15 +0000629 return StateMgr.GetEmptyMap();
Ted Kremenekd27f8162008-01-15 23:55:06 +0000630 }
Ted Kremenekd27f8162008-01-15 23:55:06 +0000631
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000632 /// ProcessStmt - Called by GREngine. Used to generate new successor
633 /// nodes by processing the 'effects' of a block-level statement.
634 void ProcessStmt(Stmt* S, NodeBuilder& builder);
635
636 /// RemoveDeadBindings - Return a new state that is the same as 'M' except
637 /// that all subexpression mappings are removed and that any
638 /// block-level expressions that are not live at 'S' also have their
639 /// mappings removed.
640 StateTy RemoveDeadBindings(Stmt* S, StateTy M);
641
Ted Kremenek9de04c42008-01-24 20:55:43 +0000642 StateTy SetValue(StateTy St, Stmt* S, const ExprValue& V);
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000643
Ted Kremenek9de04c42008-01-24 20:55:43 +0000644 StateTy SetValue(StateTy St, const Stmt* S, const ExprValue& V) {
645 return SetValue(St, const_cast<Stmt*>(S), V);
646 }
647
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000648 StateTy SetValue(StateTy St, const LValue& LV, const ExprValue& V);
Ted Kremenek1ccd31c2008-01-16 19:42:59 +0000649
Ted Kremenek9de04c42008-01-24 20:55:43 +0000650 ExprValue GetValue(const StateTy& St, Stmt* S);
651 inline ExprValue GetValue(const StateTy& St, const Stmt* S) {
652 return GetValue(St, const_cast<Stmt*>(S));
653 }
654
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000655 ExprValue GetValue(const StateTy& St, const LValue& LV);
656 LValue GetLValue(const StateTy& St, Stmt* S);
Ted Kremenekd27f8162008-01-15 23:55:06 +0000657
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000658 void Nodify(NodeSet& Dst, Stmt* S, NodeTy* Pred, StateTy St);
Ted Kremenekd27f8162008-01-15 23:55:06 +0000659
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000660 /// Visit - Transfer function logic for all statements. Dispatches to
661 /// other functions that handle specific kinds of statements.
662 void Visit(Stmt* S, NodeTy* Pred, NodeSet& Dst);
Ted Kremenek874d63f2008-01-24 02:02:54 +0000663
664 /// VisitCast - Transfer function logic for all casts (implicit and explicit).
665 void VisitCast(Expr* CastE, Expr* E, NodeTy* Pred, NodeSet& Dst);
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000666
Ted Kremenek7b8009a2008-01-24 02:28:56 +0000667 /// VisitUnaryOperator - Transfer function logic for unary operators.
668 void VisitUnaryOperator(UnaryOperator* B, NodeTy* Pred, NodeSet& Dst);
669
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000670 /// VisitBinaryOperator - Transfer function logic for binary operators.
Ted Kremenek9de04c42008-01-24 20:55:43 +0000671 void VisitBinaryOperator(BinaryOperator* B, NodeTy* Pred, NodeSet& Dst);
672
673 /// VisitDeclStmt - Transfer function logic for DeclStmts.
674 void VisitDeclStmt(DeclStmt* DS, NodeTy* Pred, NodeSet& Dst);
Ted Kremenekd27f8162008-01-15 23:55:06 +0000675};
676} // end anonymous namespace
677
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000678
Ted Kremenekd27f8162008-01-15 23:55:06 +0000679void GRConstants::ProcessStmt(Stmt* S, NodeBuilder& builder) {
680 Builder = &builder;
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000681
682 StmtEntryNode = builder.getLastNode();
683 CurrentStmt = S;
684 NodeSet Dst;
685 StateCleaned = false;
686
687 Visit(S, StmtEntryNode, Dst);
688
689 // If no nodes were generated, generate a new node that has all the
690 // dead mappings removed.
691 if (Dst.size() == 1 && *Dst.begin() == StmtEntryNode) {
692 StateTy St = RemoveDeadBindings(S, StmtEntryNode->getState());
693 builder.generateNode(S, St, StmtEntryNode);
694 }
Ted Kremenekf84469b2008-01-18 00:41:32 +0000695
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000696 CurrentStmt = NULL;
697 StmtEntryNode = NULL;
698 Builder = NULL;
Ted Kremenekd27f8162008-01-15 23:55:06 +0000699}
700
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000701
702ExprValue GRConstants::GetValue(const StateTy& St, const LValue& LV) {
Ted Kremenekf13794e2008-01-24 23:19:54 +0000703 switch (LV.getSubKind()) {
704 case LValueDeclKind: {
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000705 StateTy::TreeTy* T = St.SlimFind(cast<LValueDecl>(LV).getDecl());
706 return T ? T->getValue().second : InvalidValue();
707 }
708 default:
709 assert (false && "Invalid LValue.");
Ted Kremenekca3e8572008-01-16 22:28:08 +0000710 break;
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000711 }
712
713 return InvalidValue();
714}
715
716ExprValue GRConstants::GetValue(const StateTy& St, Stmt* S) {
Ted Kremenek671c9e82008-01-24 00:50:08 +0000717 for (;;) {
718 switch (S->getStmtClass()) {
719 case Stmt::ParenExprClass:
720 S = cast<ParenExpr>(S)->getSubExpr();
721 continue;
722
723 case Stmt::DeclRefExprClass:
724 return GetValue(St, LValueDecl(cast<DeclRefExpr>(S)->getDecl()));
Ted Kremenekca3e8572008-01-16 22:28:08 +0000725
Ted Kremenek671c9e82008-01-24 00:50:08 +0000726 case Stmt::IntegerLiteralClass:
Ted Kremenekdacbb4f2008-01-24 08:20:02 +0000727 return RValue::GetRValue(ValMgr, cast<IntegerLiteral>(S));
Ted Kremenek874d63f2008-01-24 02:02:54 +0000728
729 case Stmt::ImplicitCastExprClass: {
730 ImplicitCastExpr* C = cast<ImplicitCastExpr>(S);
731 if (C->getType() == C->getSubExpr()->getType()) {
732 S = C->getSubExpr();
733 continue;
734 }
735 break;
736 }
737
738 case Stmt::CastExprClass: {
739 CastExpr* C = cast<CastExpr>(S);
740 if (C->getType() == C->getSubExpr()->getType()) {
741 S = C->getSubExpr();
742 continue;
743 }
744 break;
745 }
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000746
Ted Kremenek671c9e82008-01-24 00:50:08 +0000747 default:
748 break;
749 };
750
751 break;
752 }
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000753
Ted Kremenek5c1b9962008-01-24 19:43:37 +0000754 StateTy::TreeTy* T = St.SlimFind(S);
Ted Kremenek874d63f2008-01-24 02:02:54 +0000755
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000756 return T ? T->getValue().second : InvalidValue();
757}
758
759LValue GRConstants::GetLValue(const StateTy& St, Stmt* S) {
760 if (Expr* E = dyn_cast<Expr>(S))
761 S = E->IgnoreParens();
762
763 if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(S))
764 return LValueDecl(DR->getDecl());
765
766 return cast<LValue>(GetValue(St, S));
767}
768
769GRConstants::StateTy GRConstants::SetValue(StateTy St, Stmt* S,
Ted Kremenekdaadf452008-01-24 19:28:01 +0000770 const ExprValue& V) {
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000771
772 if (!StateCleaned) {
773 St = RemoveDeadBindings(CurrentStmt, St);
774 StateCleaned = true;
775 }
776
Ted Kremenek9ff731d2008-01-24 22:27:20 +0000777 bool isBlkExpr = false;
778
779 if (S == CurrentStmt) {
780 isBlkExpr = getCFG().isBlkExpr(S);
781
782 if (!isBlkExpr)
783 return St;
784 }
Ted Kremenekdaadf452008-01-24 19:28:01 +0000785
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000786 return V.isValid() ? StateMgr.Add(St, ValueKey(S,isBlkExpr), V)
787 : St;
788}
789
790GRConstants::StateTy GRConstants::SetValue(StateTy St, const LValue& LV,
791 const ExprValue& V) {
792 if (!LV.isValid())
793 return St;
794
795 if (!StateCleaned) {
796 St = RemoveDeadBindings(CurrentStmt, St);
797 StateCleaned = true;
Ted Kremenekca3e8572008-01-16 22:28:08 +0000798 }
Ted Kremenek0525a4f2008-01-16 19:47:19 +0000799
Ted Kremenekf13794e2008-01-24 23:19:54 +0000800 switch (LV.getSubKind()) {
801 case LValueDeclKind:
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000802 return V.isValid() ? StateMgr.Add(St, cast<LValueDecl>(LV).getDecl(), V)
803 : StateMgr.Remove(St, cast<LValueDecl>(LV).getDecl());
804
805 default:
806 assert ("SetValue for given LValue type not yet implemented.");
807 return St;
808 }
Ted Kremenekd27f8162008-01-15 23:55:06 +0000809}
810
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000811GRConstants::StateTy GRConstants::RemoveDeadBindings(Stmt* Loc, StateTy M) {
Ted Kremenekf84469b2008-01-18 00:41:32 +0000812 // Note: in the code below, we can assign a new map to M since the
813 // iterators are iterating over the tree of the *original* map.
Ted Kremenekf84469b2008-01-18 00:41:32 +0000814 StateTy::iterator I = M.begin(), E = M.end();
815
Ted Kremenek5c1b9962008-01-24 19:43:37 +0000816 // Remove old bindings for subexpressions and "dead" block-level expressions.
817 for (; I!=E && !I.getKey().isDecl(); ++I) {
818 if (I.getKey().isSubExpr() || !Liveness->isLive(Loc,cast<Stmt>(I.getKey())))
819 M = StateMgr.Remove(M, I.getKey());
820 }
Ted Kremenekf84469b2008-01-18 00:41:32 +0000821
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000822 // Remove bindings for "dead" decls.
Ted Kremenek5c1b9962008-01-24 19:43:37 +0000823 for (; I!=E ; ++I) {
824 assert (I.getKey().isDecl());
825
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000826 if (VarDecl* V = dyn_cast<VarDecl>(cast<ValueDecl>(I.getKey())))
827 if (!Liveness->isLive(Loc, V))
828 M = StateMgr.Remove(M, I.getKey());
Ted Kremenek5c1b9962008-01-24 19:43:37 +0000829 }
Ted Kremenek565256e2008-01-24 22:44:24 +0000830
Ted Kremeneke00fe3f2008-01-17 00:52:48 +0000831 return M;
Ted Kremeneke00fe3f2008-01-17 00:52:48 +0000832}
833
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000834void GRConstants::Nodify(NodeSet& Dst, Stmt* S, GRConstants::NodeTy* Pred,
835 GRConstants::StateTy St) {
836
837 // If the state hasn't changed, don't generate a new node.
838 if (St == Pred->getState())
839 return;
Ted Kremenekcb448ca2008-01-16 00:53:15 +0000840
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000841 Dst.Add(Builder->generateNode(S, St, Pred));
Ted Kremenekcb448ca2008-01-16 00:53:15 +0000842}
Ted Kremenekd27f8162008-01-15 23:55:06 +0000843
Ted Kremenek874d63f2008-01-24 02:02:54 +0000844void GRConstants::VisitCast(Expr* CastE, Expr* E, GRConstants::NodeTy* Pred,
845 GRConstants::NodeSet& Dst) {
846
847 QualType T = CastE->getType();
848
849 // Check for redundant casts.
850 if (E->getType() == T) {
851 Dst.Add(Pred);
852 return;
853 }
854
855 NodeSet S1;
856 Visit(E, Pred, S1);
857
858 for (NodeSet::iterator I1=S1.begin(), E1=S1.end(); I1 != E1; ++I1) {
859 NodeTy* N = *I1;
860 StateTy St = N->getState();
861 const ExprValue& V = GetValue(St, E);
862 Nodify(Dst, CastE, N, SetValue(St, CastE, V.EvalCast(ValMgr, CastE)));
863 }
Ted Kremenek9de04c42008-01-24 20:55:43 +0000864}
865
866void GRConstants::VisitDeclStmt(DeclStmt* DS, GRConstants::NodeTy* Pred,
867 GRConstants::NodeSet& Dst) {
868
869 StateTy St = Pred->getState();
870
871 for (const ScopedDecl* D = DS->getDecl(); D; D = D->getNextDeclarator())
872 if (const VarDecl* VD = dyn_cast<VarDecl>(D))
873 St = SetValue(St, LValueDecl(VD), GetValue(St, VD->getInit()));
874
875 Nodify(Dst, DS, Pred, St);
876
877 if (Dst.empty())
878 Dst.Add(Pred);
879}
Ted Kremenek874d63f2008-01-24 02:02:54 +0000880
Ted Kremenek7b8009a2008-01-24 02:28:56 +0000881void GRConstants::VisitUnaryOperator(UnaryOperator* U,
882 GRConstants::NodeTy* Pred,
883 GRConstants::NodeSet& Dst) {
884 NodeSet S1;
885 Visit(U->getSubExpr(), Pred, S1);
886
887 for (NodeSet::iterator I1=S1.begin(), E1=S1.end(); I1 != E1; ++I1) {
888 NodeTy* N1 = *I1;
889 StateTy St = N1->getState();
890
891 switch (U->getOpcode()) {
892 case UnaryOperator::PostInc: {
893 const LValue& L1 = GetLValue(St, U->getSubExpr());
894 RValue R1 = cast<RValue>(GetValue(St, L1));
895
896 QualType T = U->getType();
Ted Kremeneke0cf9c82008-01-24 19:00:57 +0000897 unsigned bits = getContext()->getTypeSize(T, U->getLocStart());
898 llvm::APSInt One(llvm::APInt(bits, 1), T->isUnsignedIntegerType());
899 RValue R2 = RValue::GetRValue(ValMgr, One);
900
Ted Kremenek7b8009a2008-01-24 02:28:56 +0000901 RValue Result = R1.EvalAdd(ValMgr, R2);
902 Nodify(Dst, U, N1, SetValue(SetValue(St, U, R1), L1, Result));
903 break;
904 }
905
906 case UnaryOperator::PostDec: {
907 const LValue& L1 = GetLValue(St, U->getSubExpr());
908 RValue R1 = cast<RValue>(GetValue(St, L1));
909
910 QualType T = U->getType();
Ted Kremeneke0cf9c82008-01-24 19:00:57 +0000911 unsigned bits = getContext()->getTypeSize(T, U->getLocStart());
912 llvm::APSInt One(llvm::APInt(bits, 1), T->isUnsignedIntegerType());
913 RValue R2 = RValue::GetRValue(ValMgr, One);
Ted Kremenek7b8009a2008-01-24 02:28:56 +0000914
915 RValue Result = R1.EvalSub(ValMgr, R2);
916 Nodify(Dst, U, N1, SetValue(SetValue(St, U, R1), L1, Result));
917 break;
918 }
919
920 case UnaryOperator::PreInc: {
921 const LValue& L1 = GetLValue(St, U->getSubExpr());
922 RValue R1 = cast<RValue>(GetValue(St, L1));
923
924 QualType T = U->getType();
Ted Kremeneke0cf9c82008-01-24 19:00:57 +0000925 unsigned bits = getContext()->getTypeSize(T, U->getLocStart());
926 llvm::APSInt One(llvm::APInt(bits, 1), T->isUnsignedIntegerType());
Ted Kremenek7b8009a2008-01-24 02:28:56 +0000927 RValue R2 = RValue::GetRValue(ValMgr, One);
928
929 RValue Result = R1.EvalAdd(ValMgr, R2);
930 Nodify(Dst, U, N1, SetValue(SetValue(St, U, Result), L1, Result));
931 break;
932 }
933
934 case UnaryOperator::PreDec: {
935 const LValue& L1 = GetLValue(St, U->getSubExpr());
936 RValue R1 = cast<RValue>(GetValue(St, L1));
937
938 QualType T = U->getType();
Ted Kremeneke0cf9c82008-01-24 19:00:57 +0000939 unsigned bits = getContext()->getTypeSize(T, U->getLocStart());
940 llvm::APSInt One(llvm::APInt(bits, 1), T->isUnsignedIntegerType());
941 RValue R2 = RValue::GetRValue(ValMgr, One);
Ted Kremenek7b8009a2008-01-24 02:28:56 +0000942
943 RValue Result = R1.EvalSub(ValMgr, R2);
944 Nodify(Dst, U, N1, SetValue(SetValue(St, U, Result), L1, Result));
945 break;
946 }
947
Ted Kremenekdacbb4f2008-01-24 08:20:02 +0000948 case UnaryOperator::Minus: {
949 const RValue& R1 = cast<RValue>(GetValue(St, U->getSubExpr()));
950 Nodify(Dst, U, N1, SetValue(St, U, R1.EvalMinus(ValMgr, U)));
951 break;
952 }
953
Ted Kremenek7b8009a2008-01-24 02:28:56 +0000954 default: ;
955 assert (false && "Not implemented.");
956 }
957 }
958}
959
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000960void GRConstants::VisitBinaryOperator(BinaryOperator* B,
961 GRConstants::NodeTy* Pred,
962 GRConstants::NodeSet& Dst) {
963 NodeSet S1;
964 Visit(B->getLHS(), Pred, S1);
Ted Kremenekcb448ca2008-01-16 00:53:15 +0000965
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000966 for (NodeSet::iterator I1=S1.begin(), E1=S1.end(); I1 != E1; ++I1) {
967 NodeTy* N1 = *I1;
Ted Kremeneke00fe3f2008-01-17 00:52:48 +0000968
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000969 // When getting the value for the LHS, check if we are in an assignment.
970 // In such cases, we want to (initially) treat the LHS as an LValue,
971 // so we use GetLValue instead of GetValue so that DeclRefExpr's are
972 // evaluated to LValueDecl's instead of to an RValue.
973 const ExprValue& V1 =
974 B->isAssignmentOp() ? GetLValue(N1->getState(), B->getLHS())
975 : GetValue(N1->getState(), B->getLHS());
Ted Kremenekcb448ca2008-01-16 00:53:15 +0000976
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000977 NodeSet S2;
978 Visit(B->getRHS(), N1, S2);
979
980 for (NodeSet::iterator I2=S2.begin(), E2=S2.end(); I2 != E2; ++I2) {
981 NodeTy* N2 = *I2;
982 StateTy St = N2->getState();
983 const ExprValue& V2 = GetValue(St, B->getRHS());
984
985 switch (B->getOpcode()) {
986 case BinaryOperator::Add: {
987 const RValue& R1 = cast<RValue>(V1);
988 const RValue& R2 = cast<RValue>(V2);
989
Ted Kremenek874d63f2008-01-24 02:02:54 +0000990 Nodify(Dst, B, N2, SetValue(St, B, R1.EvalAdd(ValMgr, R2)));
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000991 break;
992 }
993
994 case BinaryOperator::Sub: {
995 const RValue& R1 = cast<RValue>(V1);
996 const RValue& R2 = cast<RValue>(V2);
Ted Kremenek874d63f2008-01-24 02:02:54 +0000997 Nodify(Dst, B, N2, SetValue(St, B, R1.EvalSub(ValMgr, R2)));
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000998 break;
999 }
1000
Ted Kremenek2eafd0e2008-01-23 23:42:27 +00001001 case BinaryOperator::Mul: {
1002 const RValue& R1 = cast<RValue>(V1);
1003 const RValue& R2 = cast<RValue>(V2);
Ted Kremenek874d63f2008-01-24 02:02:54 +00001004 Nodify(Dst, B, N2, SetValue(St, B, R1.EvalMul(ValMgr, R2)));
Ted Kremenek2eafd0e2008-01-23 23:42:27 +00001005 break;
1006 }
1007
Ted Kremenekab2b8c52008-01-23 19:59:44 +00001008 case BinaryOperator::Assign: {
1009 const LValue& L1 = cast<LValue>(V1);
1010 const RValue& R2 = cast<RValue>(V2);
Ted Kremenekab2b8c52008-01-23 19:59:44 +00001011 Nodify(Dst, B, N2, SetValue(SetValue(St, B, R2), L1, R2));
1012 break;
1013 }
Ted Kremenekb4ae33f2008-01-23 23:38:00 +00001014
1015 case BinaryOperator::AddAssign: {
1016 const LValue& L1 = cast<LValue>(V1);
1017 RValue R1 = cast<RValue>(GetValue(N1->getState(), L1));
Ted Kremenek874d63f2008-01-24 02:02:54 +00001018 RValue Result = R1.EvalAdd(ValMgr, cast<RValue>(V2));
Ted Kremenekb4ae33f2008-01-23 23:38:00 +00001019 Nodify(Dst, B, N2, SetValue(SetValue(St, B, Result), L1, Result));
1020 break;
1021 }
1022
1023 case BinaryOperator::SubAssign: {
1024 const LValue& L1 = cast<LValue>(V1);
1025 RValue R1 = cast<RValue>(GetValue(N1->getState(), L1));
Ted Kremenek874d63f2008-01-24 02:02:54 +00001026 RValue Result = R1.EvalSub(ValMgr, cast<RValue>(V2));
Ted Kremenekb4ae33f2008-01-23 23:38:00 +00001027 Nodify(Dst, B, N2, SetValue(SetValue(St, B, Result), L1, Result));
1028 break;
1029 }
Ted Kremenek2eafd0e2008-01-23 23:42:27 +00001030
1031 case BinaryOperator::MulAssign: {
1032 const LValue& L1 = cast<LValue>(V1);
1033 RValue R1 = cast<RValue>(GetValue(N1->getState(), L1));
Ted Kremenek874d63f2008-01-24 02:02:54 +00001034 RValue Result = R1.EvalMul(ValMgr, cast<RValue>(V2));
Ted Kremenek2eafd0e2008-01-23 23:42:27 +00001035 Nodify(Dst, B, N2, SetValue(SetValue(St, B, Result), L1, Result));
1036 break;
1037 }
Ted Kremenekab2b8c52008-01-23 19:59:44 +00001038
1039 default:
1040 Dst.Add(N2);
1041 break;
1042 }
Ted Kremenekcb448ca2008-01-16 00:53:15 +00001043 }
Ted Kremenekd27f8162008-01-15 23:55:06 +00001044 }
Ted Kremenekd27f8162008-01-15 23:55:06 +00001045}
Ted Kremenekee985462008-01-16 18:18:48 +00001046
Ted Kremenek1ccd31c2008-01-16 19:42:59 +00001047
Ted Kremenekab2b8c52008-01-23 19:59:44 +00001048void GRConstants::Visit(Stmt* S, GRConstants::NodeTy* Pred,
1049 GRConstants::NodeSet& Dst) {
1050
1051 // FIXME: add metadata to the CFG so that we can disable
1052 // this check when we KNOW that there is no block-level subexpression.
1053 // The motivation is that this check requires a hashtable lookup.
1054
1055 if (S != CurrentStmt && getCFG().isBlkExpr(S)) {
1056 Dst.Add(Pred);
1057 return;
1058 }
1059
1060 switch (S->getStmtClass()) {
1061 case Stmt::BinaryOperatorClass:
Ted Kremenekb4ae33f2008-01-23 23:38:00 +00001062 case Stmt::CompoundAssignOperatorClass:
Ted Kremenekab2b8c52008-01-23 19:59:44 +00001063 VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Dst);
1064 break;
1065
Ted Kremenek7b8009a2008-01-24 02:28:56 +00001066 case Stmt::UnaryOperatorClass:
1067 VisitUnaryOperator(cast<UnaryOperator>(S), Pred, Dst);
1068 break;
1069
Ted Kremenekab2b8c52008-01-23 19:59:44 +00001070 case Stmt::ParenExprClass:
1071 Visit(cast<ParenExpr>(S)->getSubExpr(), Pred, Dst);
1072 break;
1073
Ted Kremenek874d63f2008-01-24 02:02:54 +00001074 case Stmt::ImplicitCastExprClass: {
1075 ImplicitCastExpr* C = cast<ImplicitCastExpr>(S);
1076 VisitCast(C, C->getSubExpr(), Pred, Dst);
1077 break;
1078 }
1079
1080 case Stmt::CastExprClass: {
1081 CastExpr* C = cast<CastExpr>(S);
1082 VisitCast(C, C->getSubExpr(), Pred, Dst);
1083 break;
1084 }
1085
Ted Kremenek9de04c42008-01-24 20:55:43 +00001086 case Stmt::DeclStmtClass:
1087 VisitDeclStmt(cast<DeclStmt>(S), Pred, Dst);
1088 break;
1089
Ted Kremenekab2b8c52008-01-23 19:59:44 +00001090 default:
1091 Dst.Add(Pred); // No-op. Simply propagate the current state unchanged.
1092 break;
Ted Kremenek79649df2008-01-17 18:25:22 +00001093 }
Ted Kremenek1ccd31c2008-01-16 19:42:59 +00001094}
1095
Ted Kremenekee985462008-01-16 18:18:48 +00001096//===----------------------------------------------------------------------===//
1097// Driver.
1098//===----------------------------------------------------------------------===//
1099
Ted Kremenekaa66a322008-01-16 21:46:15 +00001100#ifndef NDEBUG
1101namespace llvm {
1102template<>
1103struct VISIBILITY_HIDDEN DOTGraphTraits<GRConstants::NodeTy*> :
1104 public DefaultDOTGraphTraits {
Ted Kremenek9ff731d2008-01-24 22:27:20 +00001105
1106 static void PrintKindLabel(std::ostream& Out, ValueKey::Kind kind) {
Ted Kremenek803c9ed2008-01-23 22:30:44 +00001107 switch (kind) {
Ted Kremenek565256e2008-01-24 22:44:24 +00001108 case ValueKey::IsSubExpr: Out << "Sub-Expressions:\\l"; break;
Ted Kremenek803c9ed2008-01-23 22:30:44 +00001109 case ValueKey::IsDecl: Out << "Variables:\\l"; break;
1110 case ValueKey::IsBlkExpr: Out << "Block-level Expressions:\\l"; break;
1111 default: assert (false && "Unknown ValueKey type.");
1112 }
1113 }
1114
Ted Kremenek9ff731d2008-01-24 22:27:20 +00001115 static void PrintKind(std::ostream& Out, GRConstants::StateTy M,
1116 ValueKey::Kind kind, bool isFirstGroup = false) {
1117 bool isFirst = true;
1118
1119 for (GRConstants::StateTy::iterator I=M.begin(), E=M.end();I!=E;++I) {
1120 if (I.getKey().getKind() != kind)
1121 continue;
1122
1123 if (isFirst) {
1124 if (!isFirstGroup) Out << "\\l\\l";
1125 PrintKindLabel(Out, kind);
1126 isFirst = false;
1127 }
1128 else
1129 Out << "\\l";
1130
1131 Out << ' ';
1132
1133 if (ValueDecl* V = dyn_cast<ValueDecl>(I.getKey()))
1134 Out << V->getName();
1135 else {
1136 Stmt* E = cast<Stmt>(I.getKey());
1137 Out << " (" << (void*) E << ") ";
1138 E->printPretty(Out);
1139 }
1140
1141 Out << " : ";
1142 I.getData().print(Out);
1143 }
1144 }
1145
Ted Kremenekaa66a322008-01-16 21:46:15 +00001146 static std::string getNodeLabel(const GRConstants::NodeTy* N, void*) {
1147 std::ostringstream Out;
Ted Kremenek803c9ed2008-01-23 22:30:44 +00001148
1149 // Program Location.
Ted Kremenekaa66a322008-01-16 21:46:15 +00001150 ProgramPoint Loc = N->getLocation();
1151
1152 switch (Loc.getKind()) {
1153 case ProgramPoint::BlockEntranceKind:
1154 Out << "Block Entrance: B"
1155 << cast<BlockEntrance>(Loc).getBlock()->getBlockID();
1156 break;
1157
1158 case ProgramPoint::BlockExitKind:
1159 assert (false);
1160 break;
1161
1162 case ProgramPoint::PostStmtKind: {
1163 const PostStmt& L = cast<PostStmt>(Loc);
Ted Kremenek9ff731d2008-01-24 22:27:20 +00001164 Out << L.getStmt()->getStmtClassName() << ':'
1165 << (void*) L.getStmt() << ' ';
1166
Ted Kremenekaa66a322008-01-16 21:46:15 +00001167 L.getStmt()->printPretty(Out);
1168 break;
1169 }
1170
1171 default: {
1172 const BlockEdge& E = cast<BlockEdge>(Loc);
1173 Out << "Edge: (B" << E.getSrc()->getBlockID() << ", B"
1174 << E.getDst()->getBlockID() << ')';
1175 }
1176 }
1177
Ted Kremenek803c9ed2008-01-23 22:30:44 +00001178 Out << "\\|";
Ted Kremenekaa66a322008-01-16 21:46:15 +00001179
Ted Kremenek9ff731d2008-01-24 22:27:20 +00001180 PrintKind(Out, N->getState(), ValueKey::IsDecl, true);
1181 PrintKind(Out, N->getState(), ValueKey::IsBlkExpr);
Ted Kremenek565256e2008-01-24 22:44:24 +00001182 PrintKind(Out, N->getState(), ValueKey::IsSubExpr);
Ted Kremenek803c9ed2008-01-23 22:30:44 +00001183
Ted Kremenek803c9ed2008-01-23 22:30:44 +00001184 Out << "\\l";
Ted Kremenekaa66a322008-01-16 21:46:15 +00001185 return Out.str();
1186 }
1187};
1188} // end llvm namespace
1189#endif
1190
Ted Kremenekee985462008-01-16 18:18:48 +00001191namespace clang {
Ted Kremenek874d63f2008-01-24 02:02:54 +00001192void RunGRConstants(CFG& cfg, ASTContext& Ctx) {
1193 GREngine<GRConstants> Engine(cfg, Ctx);
Ted Kremenekee985462008-01-16 18:18:48 +00001194 Engine.ExecuteWorkList();
Ted Kremenekaa66a322008-01-16 21:46:15 +00001195#ifndef NDEBUG
1196 llvm::ViewGraph(*Engine.getGraph().roots_begin(),"GRConstants");
1197#endif
Ted Kremenekee985462008-01-16 18:18:48 +00001198}
Ted Kremenekab2b8c52008-01-23 19:59:44 +00001199} // end clang namespace