blob: 46f828bac29563ac8bc37ca75b9d188cf13b859d [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 Kremenekbd03f1d2008-01-28 22:09:13 +000050
Ted Kremenekf2645622008-01-28 22:25:21 +000051typedef unsigned SymbolID;
Ted Kremenekab2b8c52008-01-23 19:59:44 +000052
53class VISIBILITY_HIDDEN ValueKey {
Ted Kremenekbd03f1d2008-01-28 22:09:13 +000054 uintptr_t Raw;
Ted Kremenekcc1c3652008-01-25 23:43:12 +000055 void operator=(const ValueKey& RHS); // Do not implement.
Ted Kremenekbd03f1d2008-01-28 22:09:13 +000056
Ted Kremenekd27f8162008-01-15 23:55:06 +000057public:
Ted Kremenekbd03f1d2008-01-28 22:09:13 +000058 enum Kind { IsSubExpr=0x0, IsBlkExpr=0x1, IsDecl=0x2, // L-Value Bindings.
59 IsSymbol=0x3, // Symbol Bindings.
60 Flags=0x3 };
61
62 inline Kind getKind() const {
63 return (Kind) (Raw & Flags);
64 }
65
66 inline void* getPtr() const {
67 assert (getKind() != IsSymbol);
68 return reinterpret_cast<void*>(Raw & ~Flags);
69 }
70
71 inline SymbolID getSymbolID() const {
72 assert (getKind() == IsSymbol);
Ted Kremenekf2645622008-01-28 22:25:21 +000073 return (SymbolID) (Raw >> 2);
Ted Kremenekbd03f1d2008-01-28 22:09:13 +000074 }
Ted Kremenekd27f8162008-01-15 23:55:06 +000075
Ted Kremenekab2b8c52008-01-23 19:59:44 +000076 ValueKey(const ValueDecl* VD)
Ted Kremenekbd03f1d2008-01-28 22:09:13 +000077 : Raw(reinterpret_cast<uintptr_t>(VD) | IsDecl) {
78 assert(VD && "ValueDecl cannot be NULL.");
79 }
Ted Kremenekab2b8c52008-01-23 19:59:44 +000080
Ted Kremenek5c1b9962008-01-24 19:43:37 +000081 ValueKey(Stmt* S, bool isBlkExpr = false)
Ted Kremenekcc1c3652008-01-25 23:43:12 +000082 : Raw(reinterpret_cast<uintptr_t>(S) | (isBlkExpr ? IsBlkExpr : IsSubExpr)){
Ted Kremenekbd03f1d2008-01-28 22:09:13 +000083 assert(S && "Tracked statement cannot be NULL.");
Ted Kremenekcc1c3652008-01-25 23:43:12 +000084 }
Ted Kremenekd27f8162008-01-15 23:55:06 +000085
Ted Kremenekbd03f1d2008-01-28 22:09:13 +000086 ValueKey(SymbolID V)
87 : Raw((V << 2) | IsSymbol) {}
88
89 bool isSymbol() const { return getKind() == IsSymbol; }
Ted Kremenek565256e2008-01-24 22:44:24 +000090 bool isSubExpr() const { return getKind() == IsSubExpr; }
Ted Kremenek65cac132008-01-29 05:25:31 +000091 bool isBlkExpr() const { return getKind() == IsBlkExpr; }
Ted Kremenekbd03f1d2008-01-28 22:09:13 +000092 bool isDecl() const { return getKind() == IsDecl; }
Ted Kremenek65cac132008-01-29 05:25:31 +000093 bool isStmt() const { return getKind() <= IsBlkExpr; }
Ted Kremenekd27f8162008-01-15 23:55:06 +000094
95 inline void Profile(llvm::FoldingSetNodeID& ID) const {
Ted Kremenekbd03f1d2008-01-28 22:09:13 +000096 ID.AddInteger(isSymbol() ? 1 : 0);
97
98 if (isSymbol())
Ted Kremenekf2645622008-01-28 22:25:21 +000099 ID.AddInteger(getSymbolID());
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000100 else
101 ID.AddPointer(getPtr());
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000102 }
103
104 inline bool operator==(const ValueKey& X) const {
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000105 return isSymbol() ? getSymbolID() == X.getSymbolID()
106 : getPtr() == X.getPtr();
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000107 }
108
109 inline bool operator!=(const ValueKey& X) const {
110 return !operator==(X);
111 }
112
113 inline bool operator<(const ValueKey& X) const {
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000114 if (isSymbol())
115 return X.isSymbol() ? getSymbolID() < X.getSymbolID() : false;
Ted Kremenek5c1b9962008-01-24 19:43:37 +0000116
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000117 return getPtr() < X.getPtr();
Ted Kremenekb3d2dca2008-01-16 23:33:44 +0000118 }
Ted Kremenekd27f8162008-01-15 23:55:06 +0000119};
120} // end anonymous namespace
121
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000122// Machinery to get cast<> and dyn_cast<> working with ValueKey.
Ted Kremenekd27f8162008-01-15 23:55:06 +0000123namespace llvm {
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000124 template<> inline bool isa<ValueDecl,ValueKey>(const ValueKey& V) {
125 return V.getKind() == ValueKey::IsDecl;
Ted Kremenekd27f8162008-01-15 23:55:06 +0000126 }
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000127 template<> inline bool isa<Stmt,ValueKey>(const ValueKey& V) {
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000128 return ((unsigned) V.getKind()) < ValueKey::IsDecl;
Ted Kremenekd27f8162008-01-15 23:55:06 +0000129 }
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000130 template<> struct VISIBILITY_HIDDEN cast_retty_impl<ValueDecl,ValueKey> {
Ted Kremenekaa66a322008-01-16 21:46:15 +0000131 typedef const ValueDecl* ret_type;
Ted Kremenekd27f8162008-01-15 23:55:06 +0000132 };
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000133 template<> struct VISIBILITY_HIDDEN cast_retty_impl<Stmt,ValueKey> {
Ted Kremenekd27f8162008-01-15 23:55:06 +0000134 typedef const Stmt* ret_type;
135 };
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000136 template<> struct VISIBILITY_HIDDEN simplify_type<ValueKey> {
Ted Kremenekd27f8162008-01-15 23:55:06 +0000137 typedef void* SimpleType;
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000138 static inline SimpleType getSimplifiedValue(const ValueKey &V) {
Ted Kremenekd27f8162008-01-15 23:55:06 +0000139 return V.getPtr();
140 }
141 };
142} // end llvm namespace
143
144//===----------------------------------------------------------------------===//
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000145// ValueManager.
Ted Kremenekd27f8162008-01-15 23:55:06 +0000146//===----------------------------------------------------------------------===//
147
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000148namespace {
149
Ted Kremenek5ee4ff82008-01-25 22:55:56 +0000150typedef llvm::ImmutableSet<APSInt > APSIntSetTy;
151
152
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000153class VISIBILITY_HIDDEN ValueManager {
Ted Kremenekcb48b9c2008-01-29 00:33:40 +0000154 ASTContext& Ctx;
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000155
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000156 typedef llvm::FoldingSet<llvm::FoldingSetNodeWrapper<APSInt> > APSIntSetTy;
157 APSIntSetTy APSIntSet;
158
159 llvm::BumpPtrAllocator BPAlloc;
160
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000161public:
Ted Kremenekcb48b9c2008-01-29 00:33:40 +0000162 ValueManager(ASTContext& ctx) : Ctx(ctx) {}
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000163 ~ValueManager();
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000164
Ted Kremenekcb48b9c2008-01-29 00:33:40 +0000165 ASTContext& getContext() const { return Ctx; }
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000166 APSInt& getValue(const APSInt& X);
167
Ted Kremenekd27f8162008-01-15 23:55:06 +0000168};
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000169} // end anonymous namespace
170
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000171ValueManager::~ValueManager() {
172 // Note that the dstor for the contents of APSIntSet will never be called,
173 // so we iterate over the set and invoke the dstor for each APSInt. This
174 // frees an aux. memory allocated to represent very large constants.
175 for (APSIntSetTy::iterator I=APSIntSet.begin(), E=APSIntSet.end(); I!=E; ++I)
176 I->getValue().~APSInt();
177}
Ted Kremenek5ee4ff82008-01-25 22:55:56 +0000178
Ted Kremenek5ee4ff82008-01-25 22:55:56 +0000179
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000180
181APSInt& ValueManager::getValue(const APSInt& X) {
182 llvm::FoldingSetNodeID ID;
183 void* InsertPos;
184 typedef llvm::FoldingSetNodeWrapper<APSInt> FoldNodeTy;
Ted Kremenekcc1c3652008-01-25 23:43:12 +0000185
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000186 X.Profile(ID);
187 FoldNodeTy* P = APSIntSet.FindNodeOrInsertPos(ID, InsertPos);
Ted Kremenek5ee4ff82008-01-25 22:55:56 +0000188
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000189 if (!P) {
190 P = (FoldNodeTy*) BPAlloc.Allocate<FoldNodeTy>();
191 new (P) FoldNodeTy(X);
192 APSIntSet.InsertNode(P, InsertPos);
193 }
194
195 return *P;
Ted Kremenek5ee4ff82008-01-25 22:55:56 +0000196}
197
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000198//===----------------------------------------------------------------------===//
199// Expression Values.
200//===----------------------------------------------------------------------===//
Ted Kremenekf13794e2008-01-24 23:19:54 +0000201
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000202namespace {
203
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000204class VISIBILITY_HIDDEN RValue {
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000205public:
Ted Kremenek403c1812008-01-28 22:51:57 +0000206 enum BaseKind { LValueKind=0x0, NonLValueKind=0x1,
207 UninitializedKind=0x2, InvalidKind=0x3, BaseFlags = 0x3 };
Ted Kremenekf13794e2008-01-24 23:19:54 +0000208
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000209private:
Ted Kremenekf2645622008-01-28 22:25:21 +0000210 void* Data;
Ted Kremenekf13794e2008-01-24 23:19:54 +0000211 unsigned Kind;
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000212
213protected:
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000214 RValue(const void* d, bool isLValue, unsigned ValKind)
Ted Kremenekf2645622008-01-28 22:25:21 +0000215 : Data(const_cast<void*>(d)),
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000216 Kind((isLValue ? LValueKind : NonLValueKind) | (ValKind << 2)) {}
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000217
Ted Kremenek403c1812008-01-28 22:51:57 +0000218 explicit RValue(BaseKind k)
219 : Data(0), Kind(k) {}
Ted Kremenekf2645622008-01-28 22:25:21 +0000220
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000221 void* getRawPtr() const {
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000222 return reinterpret_cast<void*>(Data);
223 }
224
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000225public:
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000226 ~RValue() {};
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000227
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000228 RValue Cast(ValueManager& ValMgr, Expr* CastExpr) const;
Ted Kremenek874d63f2008-01-24 02:02:54 +0000229
Ted Kremenekf13794e2008-01-24 23:19:54 +0000230 unsigned getRawKind() const { return Kind; }
231 BaseKind getBaseKind() const { return (BaseKind) (Kind & 0x3); }
232 unsigned getSubKind() const { return (Kind & ~0x3) >> 2; }
233
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000234 void Profile(llvm::FoldingSetNodeID& ID) const {
Ted Kremenekf13794e2008-01-24 23:19:54 +0000235 ID.AddInteger((unsigned) getRawKind());
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000236 ID.AddPointer(reinterpret_cast<void*>(Data));
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000237 }
238
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000239 bool operator==(const RValue& RHS) const {
Ted Kremenekf13794e2008-01-24 23:19:54 +0000240 return getRawKind() == RHS.getRawKind() && Data == RHS.Data;
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000241 }
242
Ted Kremenekf13794e2008-01-24 23:19:54 +0000243 inline bool isValid() const { return getRawKind() != InvalidKind; }
244 inline bool isInvalid() const { return getRawKind() == InvalidKind; }
245
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000246 void print(std::ostream& OS) const;
247 void print() const { print(*llvm::cerr.stream()); }
248
249 // Implement isa<T> support.
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000250 static inline bool classof(const RValue*) { return true; }
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000251};
252
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000253class VISIBILITY_HIDDEN InvalidValue : public RValue {
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000254public:
Ted Kremenek403c1812008-01-28 22:51:57 +0000255 InvalidValue() : RValue(InvalidKind) {}
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000256
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000257 static inline bool classof(const RValue* V) {
Ted Kremenekf13794e2008-01-24 23:19:54 +0000258 return V->getBaseKind() == InvalidKind;
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000259 }
260};
Ted Kremenek403c1812008-01-28 22:51:57 +0000261
262class VISIBILITY_HIDDEN UninitializedValue : public RValue {
263public:
264 UninitializedValue() : RValue(UninitializedKind) {}
265
266 static inline bool classof(const RValue* V) {
267 return V->getBaseKind() == UninitializedKind;
268 }
269};
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000270
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000271class VISIBILITY_HIDDEN LValue : public RValue {
Ted Kremenekf13794e2008-01-24 23:19:54 +0000272protected:
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000273 LValue(unsigned SubKind, void* D) : RValue(D, true, SubKind) {}
Ted Kremenekf13794e2008-01-24 23:19:54 +0000274
275public:
276 // Implement isa<T> support.
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000277 static inline bool classof(const RValue* V) {
Ted Kremenekf13794e2008-01-24 23:19:54 +0000278 return V->getBaseKind() == LValueKind;
279 }
280};
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000281
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000282class VISIBILITY_HIDDEN NonLValue : public RValue {
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000283protected:
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000284 NonLValue(unsigned SubKind, const void* d) : RValue(d, false, SubKind) {}
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000285
286public:
Ted Kremenekf13794e2008-01-24 23:19:54 +0000287 void print(std::ostream& Out) const;
288
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000289 NonLValue Add(ValueManager& ValMgr, const NonLValue& RHS) const;
290 NonLValue Sub(ValueManager& ValMgr, const NonLValue& RHS) const;
291 NonLValue Mul(ValueManager& ValMgr, const NonLValue& RHS) const;
292 NonLValue Div(ValueManager& ValMgr, const NonLValue& RHS) const;
293 NonLValue Rem(ValueManager& ValMgr, const NonLValue& RHS) const;
294 NonLValue UnaryMinus(ValueManager& ValMgr, UnaryOperator* U) const;
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000295
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000296 static NonLValue GetValue(ValueManager& ValMgr, const APSInt& V);
297 static NonLValue GetValue(ValueManager& ValMgr, IntegerLiteral* I);
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000298
299 // Implement isa<T> support.
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000300 static inline bool classof(const RValue* V) {
Ted Kremenek403c1812008-01-28 22:51:57 +0000301 return V->getBaseKind() >= NonLValueKind;
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000302 }
303};
Ted Kremenekf13794e2008-01-24 23:19:54 +0000304
305} // end anonymous namespace
306
307//===----------------------------------------------------------------------===//
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000308// LValues.
Ted Kremenekf13794e2008-01-24 23:19:54 +0000309//===----------------------------------------------------------------------===//
310
311namespace {
312
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000313enum { LValueDeclKind, NumLValueKind };
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000314
315class VISIBILITY_HIDDEN LValueDecl : public LValue {
316public:
Ted Kremenek9de04c42008-01-24 20:55:43 +0000317 LValueDecl(const ValueDecl* vd)
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000318 : LValue(LValueDeclKind,const_cast<ValueDecl*>(vd)) {}
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000319
320 ValueDecl* getDecl() const {
321 return static_cast<ValueDecl*>(getRawPtr());
322 }
323
324 // Implement isa<T> support.
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000325 static inline bool classof(const RValue* V) {
Ted Kremenekf13794e2008-01-24 23:19:54 +0000326 return V->getSubKind() == LValueDeclKind;
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000327 }
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000328};
329
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000330} // end anonymous namespace
331
332//===----------------------------------------------------------------------===//
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000333// Non-LValues.
334//===----------------------------------------------------------------------===//
335
336namespace {
337
Ted Kremenekf2645622008-01-28 22:25:21 +0000338enum { SymbolicNonLValueKind, ConcreteIntKind, ConstrainedIntegerKind,
339 NumNonLValueKind };
340
341class VISIBILITY_HIDDEN SymbolicNonLValue : public NonLValue {
342public:
343 SymbolicNonLValue(unsigned SymID)
344 : NonLValue(SymbolicNonLValueKind,
345 reinterpret_cast<void*>((uintptr_t) SymID)) {}
346
347 SymbolID getSymbolID() const {
348 return (SymbolID) reinterpret_cast<uintptr_t>(getRawPtr());
349 }
350
351 static inline bool classof(const RValue* V) {
352 return V->getSubKind() == SymbolicNonLValueKind;
353 }
354};
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000355
356class VISIBILITY_HIDDEN ConcreteInt : public NonLValue {
357public:
358 ConcreteInt(const APSInt& V) : NonLValue(ConcreteIntKind, &V) {}
359
360 const APSInt& getValue() const {
361 return *static_cast<APSInt*>(getRawPtr());
362 }
363
364 ConcreteInt Add(ValueManager& ValMgr, const ConcreteInt& V) const {
365 return ValMgr.getValue(getValue() + V.getValue());
366 }
367
368 ConcreteInt Sub(ValueManager& ValMgr, const ConcreteInt& V) const {
369 return ValMgr.getValue(getValue() - V.getValue());
370 }
371
372 ConcreteInt Mul(ValueManager& ValMgr, const ConcreteInt& V) const {
373 return ValMgr.getValue(getValue() * V.getValue());
374 }
375
376 ConcreteInt Div(ValueManager& ValMgr, const ConcreteInt& V) const {
377 return ValMgr.getValue(getValue() / V.getValue());
378 }
379
380 ConcreteInt Rem(ValueManager& ValMgr, const ConcreteInt& V) const {
381 return ValMgr.getValue(getValue() % V.getValue());
382 }
383
384 ConcreteInt Cast(ValueManager& ValMgr, Expr* CastExpr) const {
385 assert (CastExpr->getType()->isIntegerType());
386
387 APSInt X(getValue());
Ted Kremenekcb48b9c2008-01-29 00:33:40 +0000388 X.extOrTrunc(ValMgr.getContext().getTypeSize(CastExpr->getType(),
389 CastExpr->getLocStart()));
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000390 return ValMgr.getValue(X);
391 }
392
393 ConcreteInt UnaryMinus(ValueManager& ValMgr, UnaryOperator* U) const {
394 assert (U->getType() == U->getSubExpr()->getType());
395 assert (U->getType()->isIntegerType());
396 return ValMgr.getValue(-getValue());
397 }
398
399 // Implement isa<T> support.
400 static inline bool classof(const RValue* V) {
401 return V->getSubKind() == ConcreteIntKind;
402 }
403};
404
405} // end anonymous namespace
406
407//===----------------------------------------------------------------------===//
408// Transfer function dispatch.
409//===----------------------------------------------------------------------===//
410
411RValue RValue::Cast(ValueManager& ValMgr, Expr* CastExpr) const {
412 switch (getSubKind()) {
413 case ConcreteIntKind:
414 return cast<ConcreteInt>(this)->Cast(ValMgr, CastExpr);
415 default:
416 return InvalidValue();
417 }
418}
419
420NonLValue NonLValue::UnaryMinus(ValueManager& ValMgr, UnaryOperator* U) const {
421 switch (getSubKind()) {
422 case ConcreteIntKind:
423 return cast<ConcreteInt>(this)->UnaryMinus(ValMgr, U);
424 default:
425 return cast<NonLValue>(InvalidValue());
426 }
427}
428
429#define RVALUE_DISPATCH_CASE(k1,k2,Op)\
430case (k1##Kind*NumNonLValueKind+k2##Kind):\
431 return cast<k1>(*this).Op(ValMgr,cast<k2>(RHS));
432
433#define RVALUE_DISPATCH(Op)\
434switch (getSubKind()*NumNonLValueKind+RHS.getSubKind()){\
435 RVALUE_DISPATCH_CASE(ConcreteInt,ConcreteInt,Op)\
436 default:\
Ted Kremenek403c1812008-01-28 22:51:57 +0000437 if (getBaseKind() == UninitializedKind ||\
438 RHS.getBaseKind() == UninitializedKind)\
439 return cast<NonLValue>(UninitializedValue());\
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000440 assert (!isValid() || !RHS.isValid() && "Missing case.");\
441 break;\
442}\
443return cast<NonLValue>(InvalidValue());
444
445NonLValue NonLValue::Add(ValueManager& ValMgr, const NonLValue& RHS) const {
446 RVALUE_DISPATCH(Add)
447}
448
449NonLValue NonLValue::Sub(ValueManager& ValMgr, const NonLValue& RHS) const {
450 RVALUE_DISPATCH(Sub)
451}
452
453NonLValue NonLValue::Mul(ValueManager& ValMgr, const NonLValue& RHS) const {
454 RVALUE_DISPATCH(Mul)
455}
456
457NonLValue NonLValue::Div(ValueManager& ValMgr, const NonLValue& RHS) const {
458 RVALUE_DISPATCH(Div)
459}
460
461NonLValue NonLValue::Rem(ValueManager& ValMgr, const NonLValue& RHS) const {
462 RVALUE_DISPATCH(Rem)
463}
464
465
466#undef RVALUE_DISPATCH_CASE
467#undef RVALUE_DISPATCH
468
469//===----------------------------------------------------------------------===//
470// Utility methods for constructing RValues.
471//===----------------------------------------------------------------------===//
472
473NonLValue NonLValue::GetValue(ValueManager& ValMgr, const APSInt& V) {
474 return ConcreteInt(ValMgr.getValue(V));
475}
476
477NonLValue NonLValue::GetValue(ValueManager& ValMgr, IntegerLiteral* I) {
478 return ConcreteInt(ValMgr.getValue(APSInt(I->getValue(),
479 I->getType()->isUnsignedIntegerType())));
480}
481
482//===----------------------------------------------------------------------===//
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000483// Pretty-Printing.
484//===----------------------------------------------------------------------===//
485
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000486void RValue::print(std::ostream& Out) const {
Ted Kremenekf13794e2008-01-24 23:19:54 +0000487 switch (getBaseKind()) {
488 case InvalidKind:
489 Out << "Invalid";
490 break;
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000491
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000492 case NonLValueKind:
493 cast<NonLValue>(this)->print(Out);
Ted Kremenekf13794e2008-01-24 23:19:54 +0000494 break;
495
496 case LValueKind:
497 assert (false && "FIXME: LValue printing not implemented.");
498 break;
499
Ted Kremenek403c1812008-01-28 22:51:57 +0000500 case UninitializedKind:
501 Out << "Uninitialized";
502 break;
503
Ted Kremenekf13794e2008-01-24 23:19:54 +0000504 default:
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000505 assert (false && "Invalid RValue.");
Ted Kremenekf13794e2008-01-24 23:19:54 +0000506 }
507}
508
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000509void NonLValue::print(std::ostream& Out) const {
Ted Kremenekf13794e2008-01-24 23:19:54 +0000510 switch (getSubKind()) {
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000511 case ConcreteIntKind:
512 Out << cast<ConcreteInt>(this)->getValue().toString();
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000513 break;
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000514
515 default:
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000516 assert (false && "Pretty-printed not implemented for this NonLValue.");
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000517 break;
518 }
519}
520
521//===----------------------------------------------------------------------===//
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000522// ValueMapTy - A ImmutableMap type Stmt*/Decl*/Symbols to RValues.
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000523//===----------------------------------------------------------------------===//
524
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000525typedef llvm::ImmutableMap<ValueKey,RValue> ValueMapTy;
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000526
527namespace clang {
528 template<>
529 struct VISIBILITY_HIDDEN GRTrait<ValueMapTy> {
530 static inline void* toPtr(ValueMapTy M) {
531 return reinterpret_cast<void*>(M.getRoot());
532 }
533 static inline ValueMapTy toState(void* P) {
534 return ValueMapTy(static_cast<ValueMapTy::TreeTy*>(P));
535 }
536 };
Ted Kremenekd27f8162008-01-15 23:55:06 +0000537}
538
539//===----------------------------------------------------------------------===//
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000540// The Checker.
Ted Kremenekd27f8162008-01-15 23:55:06 +0000541//===----------------------------------------------------------------------===//
542
543namespace {
Ted Kremenekd27f8162008-01-15 23:55:06 +0000544
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000545class VISIBILITY_HIDDEN GRConstants {
Ted Kremenekd27f8162008-01-15 23:55:06 +0000546
547public:
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000548 typedef ValueMapTy StateTy;
Ted Kremenekd27f8162008-01-15 23:55:06 +0000549 typedef GRNodeBuilder<GRConstants> NodeBuilder;
Ted Kremenekcb48b9c2008-01-29 00:33:40 +0000550 typedef ExplodedGraph<GRConstants> GraphTy;
551 typedef GraphTy::NodeTy NodeTy;
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000552
553 class NodeSet {
554 typedef llvm::SmallVector<NodeTy*,3> ImplTy;
555 ImplTy Impl;
556 public:
557
558 NodeSet() {}
559 NodeSet(NodeTy* N) { assert (N && !N->isInfeasible()); Impl.push_back(N); }
560
561 void Add(NodeTy* N) { if (N && !N->isInfeasible()) Impl.push_back(N); }
562
563 typedef ImplTy::iterator iterator;
564 typedef ImplTy::const_iterator const_iterator;
565
566 unsigned size() const { return Impl.size(); }
Ted Kremenek9de04c42008-01-24 20:55:43 +0000567 bool empty() const { return Impl.empty(); }
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000568
569 iterator begin() { return Impl.begin(); }
570 iterator end() { return Impl.end(); }
571
572 const_iterator begin() const { return Impl.begin(); }
573 const_iterator end() const { return Impl.end(); }
574 };
Ted Kremenekd27f8162008-01-15 23:55:06 +0000575
576protected:
Ted Kremenekcb48b9c2008-01-29 00:33:40 +0000577 /// G - the simulation graph.
578 GraphTy& G;
579
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000580 /// Liveness - live-variables information the ValueDecl* and block-level
581 /// Expr* in the CFG. Used to prune out dead state.
Ted Kremenekbffaa832008-01-29 05:13:23 +0000582 LiveVariables Liveness;
Ted Kremenekd27f8162008-01-15 23:55:06 +0000583
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000584 /// Builder - The current GRNodeBuilder which is used when building the nodes
585 /// for a given statement.
Ted Kremenekd27f8162008-01-15 23:55:06 +0000586 NodeBuilder* Builder;
587
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000588 /// StateMgr - Object that manages the data for all created states.
589 ValueMapTy::Factory StateMgr;
Ted Kremenekd27f8162008-01-15 23:55:06 +0000590
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000591 /// ValueMgr - Object that manages the data for all created RValues.
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000592 ValueManager ValMgr;
593
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000594 /// StmtEntryNode - The immediate predecessor node.
595 NodeTy* StmtEntryNode;
596
597 /// CurrentStmt - The current block-level statement.
598 Stmt* CurrentStmt;
599
600 bool StateCleaned;
Ted Kremenekd27f8162008-01-15 23:55:06 +0000601
Ted Kremenekcb48b9c2008-01-29 00:33:40 +0000602 ASTContext& getContext() const { return G.getContext(); }
Ted Kremenek7b8009a2008-01-24 02:28:56 +0000603
Ted Kremenekd27f8162008-01-15 23:55:06 +0000604public:
Ted Kremenekbffaa832008-01-29 05:13:23 +0000605 GRConstants(GraphTy& g) : G(g), Liveness(G.getCFG(), G.getFunctionDecl()),
606 Builder(NULL), ValMgr(G.getContext()), StmtEntryNode(NULL),
607 CurrentStmt(NULL) {
Ted Kremenekd27f8162008-01-15 23:55:06 +0000608
Ted Kremenekcb48b9c2008-01-29 00:33:40 +0000609 // Compute liveness information.
Ted Kremenekbffaa832008-01-29 05:13:23 +0000610 Liveness.runOnCFG(G.getCFG());
611 Liveness.runOnAllBlocks(G.getCFG(), NULL, true);
Ted Kremenekd27f8162008-01-15 23:55:06 +0000612 }
Ted Kremenekcb48b9c2008-01-29 00:33:40 +0000613
614 /// getCFG - Returns the CFG associated with this analysis.
615 CFG& getCFG() { return G.getCFG(); }
Ted Kremenekd27f8162008-01-15 23:55:06 +0000616
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000617 /// getInitialState - Return the initial state used for the root vertex
618 /// in the ExplodedGraph.
Ted Kremenekd27f8162008-01-15 23:55:06 +0000619 StateTy getInitialState() {
Ted Kremenekcb48b9c2008-01-29 00:33:40 +0000620 StateTy St = StateMgr.GetEmptyMap();
Ted Kremenekff6e3c52008-01-29 00:43:03 +0000621
622 // Iterate the parameters.
623 FunctionDecl& F = G.getFunctionDecl();
624
625 for (FunctionDecl::param_iterator I=F.param_begin(), E=F.param_end();
626 I!=E; ++I) {
627
628 // For now we only support symbolic values for non-pointer types.
629 if ((*I)->getType()->isPointerType() ||
630 (*I)->getType()->isReferenceType())
631 continue;
632
633 // FIXME: Set these values to a symbol, not Uninitialized.
634 St = SetValue(St, LValueDecl(*I), UninitializedValue());
635 }
636
Ted Kremenekcb48b9c2008-01-29 00:33:40 +0000637 return St;
Ted Kremenekd27f8162008-01-15 23:55:06 +0000638 }
Ted Kremenekd27f8162008-01-15 23:55:06 +0000639
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000640 /// ProcessStmt - Called by GREngine. Used to generate new successor
641 /// nodes by processing the 'effects' of a block-level statement.
642 void ProcessStmt(Stmt* S, NodeBuilder& builder);
643
644 /// RemoveDeadBindings - Return a new state that is the same as 'M' except
645 /// that all subexpression mappings are removed and that any
646 /// block-level expressions that are not live at 'S' also have their
647 /// mappings removed.
648 StateTy RemoveDeadBindings(Stmt* S, StateTy M);
649
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000650 StateTy SetValue(StateTy St, Stmt* S, const RValue& V);
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000651
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000652 StateTy SetValue(StateTy St, const Stmt* S, const RValue& V) {
Ted Kremenek9de04c42008-01-24 20:55:43 +0000653 return SetValue(St, const_cast<Stmt*>(S), V);
654 }
655
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000656 StateTy SetValue(StateTy St, const LValue& LV, const RValue& V);
Ted Kremenek1ccd31c2008-01-16 19:42:59 +0000657
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000658 RValue GetValue(const StateTy& St, Stmt* S);
659 inline RValue GetValue(const StateTy& St, const Stmt* S) {
Ted Kremenek9de04c42008-01-24 20:55:43 +0000660 return GetValue(St, const_cast<Stmt*>(S));
661 }
662
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000663 RValue GetValue(const StateTy& St, const LValue& LV);
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000664 LValue GetLValue(const StateTy& St, Stmt* S);
Ted Kremenekd27f8162008-01-15 23:55:06 +0000665
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000666 void Nodify(NodeSet& Dst, Stmt* S, NodeTy* Pred, StateTy St);
Ted Kremenekd27f8162008-01-15 23:55:06 +0000667
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000668 /// Visit - Transfer function logic for all statements. Dispatches to
669 /// other functions that handle specific kinds of statements.
670 void Visit(Stmt* S, NodeTy* Pred, NodeSet& Dst);
Ted Kremenek874d63f2008-01-24 02:02:54 +0000671
672 /// VisitCast - Transfer function logic for all casts (implicit and explicit).
673 void VisitCast(Expr* CastE, Expr* E, NodeTy* Pred, NodeSet& Dst);
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000674
Ted Kremenek7b8009a2008-01-24 02:28:56 +0000675 /// VisitUnaryOperator - Transfer function logic for unary operators.
676 void VisitUnaryOperator(UnaryOperator* B, NodeTy* Pred, NodeSet& Dst);
677
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000678 /// VisitBinaryOperator - Transfer function logic for binary operators.
Ted Kremenek9de04c42008-01-24 20:55:43 +0000679 void VisitBinaryOperator(BinaryOperator* B, NodeTy* Pred, NodeSet& Dst);
680
681 /// VisitDeclStmt - Transfer function logic for DeclStmts.
682 void VisitDeclStmt(DeclStmt* DS, NodeTy* Pred, NodeSet& Dst);
Ted Kremenekd27f8162008-01-15 23:55:06 +0000683};
684} // end anonymous namespace
685
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000686
Ted Kremenekd27f8162008-01-15 23:55:06 +0000687void GRConstants::ProcessStmt(Stmt* S, NodeBuilder& builder) {
688 Builder = &builder;
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000689
690 StmtEntryNode = builder.getLastNode();
691 CurrentStmt = S;
692 NodeSet Dst;
693 StateCleaned = false;
694
695 Visit(S, StmtEntryNode, Dst);
696
697 // If no nodes were generated, generate a new node that has all the
698 // dead mappings removed.
699 if (Dst.size() == 1 && *Dst.begin() == StmtEntryNode) {
700 StateTy St = RemoveDeadBindings(S, StmtEntryNode->getState());
701 builder.generateNode(S, St, StmtEntryNode);
702 }
Ted Kremenekf84469b2008-01-18 00:41:32 +0000703
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000704 CurrentStmt = NULL;
705 StmtEntryNode = NULL;
706 Builder = NULL;
Ted Kremenekd27f8162008-01-15 23:55:06 +0000707}
708
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000709
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000710RValue GRConstants::GetValue(const StateTy& St, const LValue& LV) {
Ted Kremenekf13794e2008-01-24 23:19:54 +0000711 switch (LV.getSubKind()) {
712 case LValueDeclKind: {
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000713 StateTy::TreeTy* T = St.SlimFind(cast<LValueDecl>(LV).getDecl());
714 return T ? T->getValue().second : InvalidValue();
715 }
716 default:
717 assert (false && "Invalid LValue.");
Ted Kremenekca3e8572008-01-16 22:28:08 +0000718 break;
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000719 }
720
721 return InvalidValue();
722}
723
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000724RValue GRConstants::GetValue(const StateTy& St, Stmt* S) {
Ted Kremenek671c9e82008-01-24 00:50:08 +0000725 for (;;) {
726 switch (S->getStmtClass()) {
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000727
728 // ParenExprs are no-ops.
729
Ted Kremenek671c9e82008-01-24 00:50:08 +0000730 case Stmt::ParenExprClass:
731 S = cast<ParenExpr>(S)->getSubExpr();
732 continue;
733
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000734 // DeclRefExprs can either evaluate to an LValue or a Non-LValue
735 // (assuming an implicit "load") depending on the context. In this
736 // context we assume that we are retrieving the value contained
737 // within the referenced variables.
738
Ted Kremenek671c9e82008-01-24 00:50:08 +0000739 case Stmt::DeclRefExprClass:
740 return GetValue(St, LValueDecl(cast<DeclRefExpr>(S)->getDecl()));
Ted Kremenekca3e8572008-01-16 22:28:08 +0000741
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000742 // Integer literals evaluate to an RValue. Simply retrieve the
743 // RValue for the literal.
744
Ted Kremenek671c9e82008-01-24 00:50:08 +0000745 case Stmt::IntegerLiteralClass:
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000746 return NonLValue::GetValue(ValMgr, cast<IntegerLiteral>(S));
747
748 // Casts where the source and target type are the same
749 // are no-ops. We blast through these to get the descendant
750 // subexpression that has a value.
751
Ted Kremenek874d63f2008-01-24 02:02:54 +0000752 case Stmt::ImplicitCastExprClass: {
753 ImplicitCastExpr* C = cast<ImplicitCastExpr>(S);
754 if (C->getType() == C->getSubExpr()->getType()) {
755 S = C->getSubExpr();
756 continue;
757 }
758 break;
759 }
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000760
Ted Kremenek874d63f2008-01-24 02:02:54 +0000761 case Stmt::CastExprClass: {
762 CastExpr* C = cast<CastExpr>(S);
763 if (C->getType() == C->getSubExpr()->getType()) {
764 S = C->getSubExpr();
765 continue;
766 }
767 break;
768 }
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000769
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000770 // Handle all other Stmt* using a lookup.
771
Ted Kremenek671c9e82008-01-24 00:50:08 +0000772 default:
773 break;
774 };
775
776 break;
777 }
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000778
Ted Kremenek5c1b9962008-01-24 19:43:37 +0000779 StateTy::TreeTy* T = St.SlimFind(S);
Ted Kremenek874d63f2008-01-24 02:02:54 +0000780
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000781 return T ? T->getValue().second : InvalidValue();
782}
783
784LValue GRConstants::GetLValue(const StateTy& St, Stmt* S) {
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000785 while (ParenExpr* P = dyn_cast<ParenExpr>(S))
786 S = P->getSubExpr();
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000787
788 if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(S))
789 return LValueDecl(DR->getDecl());
790
791 return cast<LValue>(GetValue(St, S));
792}
793
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000794
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000795GRConstants::StateTy GRConstants::SetValue(StateTy St, Stmt* S,
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000796 const RValue& V) {
Ted Kremenekcc1c3652008-01-25 23:43:12 +0000797 assert (S);
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000798
799 if (!StateCleaned) {
800 St = RemoveDeadBindings(CurrentStmt, St);
801 StateCleaned = true;
802 }
803
Ted Kremenek9ff731d2008-01-24 22:27:20 +0000804 bool isBlkExpr = false;
805
806 if (S == CurrentStmt) {
807 isBlkExpr = getCFG().isBlkExpr(S);
808
809 if (!isBlkExpr)
810 return St;
811 }
Ted Kremenekdaadf452008-01-24 19:28:01 +0000812
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000813 return V.isValid() ? StateMgr.Add(St, ValueKey(S,isBlkExpr), V)
814 : St;
815}
816
817GRConstants::StateTy GRConstants::SetValue(StateTy St, const LValue& LV,
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000818 const RValue& V) {
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000819 if (!LV.isValid())
820 return St;
821
822 if (!StateCleaned) {
823 St = RemoveDeadBindings(CurrentStmt, St);
824 StateCleaned = true;
Ted Kremenekca3e8572008-01-16 22:28:08 +0000825 }
Ted Kremenek0525a4f2008-01-16 19:47:19 +0000826
Ted Kremenekf13794e2008-01-24 23:19:54 +0000827 switch (LV.getSubKind()) {
828 case LValueDeclKind:
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000829 return V.isValid() ? StateMgr.Add(St, cast<LValueDecl>(LV).getDecl(), V)
830 : StateMgr.Remove(St, cast<LValueDecl>(LV).getDecl());
831
832 default:
833 assert ("SetValue for given LValue type not yet implemented.");
834 return St;
835 }
Ted Kremenekd27f8162008-01-15 23:55:06 +0000836}
837
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000838GRConstants::StateTy GRConstants::RemoveDeadBindings(Stmt* Loc, StateTy M) {
Ted Kremenekf84469b2008-01-18 00:41:32 +0000839 // Note: in the code below, we can assign a new map to M since the
840 // iterators are iterating over the tree of the *original* map.
Ted Kremenekf84469b2008-01-18 00:41:32 +0000841 StateTy::iterator I = M.begin(), E = M.end();
842
Ted Kremenekf84469b2008-01-18 00:41:32 +0000843
Ted Kremenek65cac132008-01-29 05:25:31 +0000844 for (; I!=E && !I.getKey().isSymbol(); ++I) {
845 // Remove old bindings for subexpressions and "dead"
846 // block-level expressions.
847 if (I.getKey().isSubExpr() ||
848 I.getKey().isBlkExpr() && !Liveness.isLive(Loc,cast<Stmt>(I.getKey()))){
849 M = StateMgr.Remove(M, I.getKey());
850 }
851 else if (I.getKey().isDecl()) { // Remove bindings for "dead" decls.
852 if (VarDecl* V = dyn_cast<VarDecl>(cast<ValueDecl>(I.getKey())))
853 if (!Liveness.isLive(Loc, V))
854 M = StateMgr.Remove(M, I.getKey());
855 }
856 }
Ted Kremenek565256e2008-01-24 22:44:24 +0000857
Ted Kremeneke00fe3f2008-01-17 00:52:48 +0000858 return M;
Ted Kremeneke00fe3f2008-01-17 00:52:48 +0000859}
860
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000861void GRConstants::Nodify(NodeSet& Dst, Stmt* S, GRConstants::NodeTy* Pred,
862 GRConstants::StateTy St) {
863
864 // If the state hasn't changed, don't generate a new node.
865 if (St == Pred->getState())
866 return;
Ted Kremenekcb448ca2008-01-16 00:53:15 +0000867
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000868 Dst.Add(Builder->generateNode(S, St, Pred));
Ted Kremenekcb448ca2008-01-16 00:53:15 +0000869}
Ted Kremenekd27f8162008-01-15 23:55:06 +0000870
Ted Kremenek874d63f2008-01-24 02:02:54 +0000871void GRConstants::VisitCast(Expr* CastE, Expr* E, GRConstants::NodeTy* Pred,
872 GRConstants::NodeSet& Dst) {
873
874 QualType T = CastE->getType();
875
876 // Check for redundant casts.
877 if (E->getType() == T) {
878 Dst.Add(Pred);
879 return;
880 }
881
882 NodeSet S1;
883 Visit(E, Pred, S1);
884
885 for (NodeSet::iterator I1=S1.begin(), E1=S1.end(); I1 != E1; ++I1) {
886 NodeTy* N = *I1;
887 StateTy St = N->getState();
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000888 const RValue& V = GetValue(St, E);
889 Nodify(Dst, CastE, N, SetValue(St, CastE, V.Cast(ValMgr, CastE)));
Ted Kremenek874d63f2008-01-24 02:02:54 +0000890 }
Ted Kremenek9de04c42008-01-24 20:55:43 +0000891}
892
893void GRConstants::VisitDeclStmt(DeclStmt* DS, GRConstants::NodeTy* Pred,
894 GRConstants::NodeSet& Dst) {
895
896 StateTy St = Pred->getState();
897
898 for (const ScopedDecl* D = DS->getDecl(); D; D = D->getNextDeclarator())
Ted Kremenek403c1812008-01-28 22:51:57 +0000899 if (const VarDecl* VD = dyn_cast<VarDecl>(D)) {
900 const Expr* E = VD->getInit();
901 St = SetValue(St, LValueDecl(VD),
902 E ? GetValue(St, E) : UninitializedValue());
903 }
Ted Kremenek9de04c42008-01-24 20:55:43 +0000904
905 Nodify(Dst, DS, Pred, St);
906
907 if (Dst.empty())
908 Dst.Add(Pred);
909}
Ted Kremenek874d63f2008-01-24 02:02:54 +0000910
Ted Kremenek7b8009a2008-01-24 02:28:56 +0000911void GRConstants::VisitUnaryOperator(UnaryOperator* U,
912 GRConstants::NodeTy* Pred,
913 GRConstants::NodeSet& Dst) {
914 NodeSet S1;
915 Visit(U->getSubExpr(), Pred, S1);
916
917 for (NodeSet::iterator I1=S1.begin(), E1=S1.end(); I1 != E1; ++I1) {
918 NodeTy* N1 = *I1;
919 StateTy St = N1->getState();
920
921 switch (U->getOpcode()) {
922 case UnaryOperator::PostInc: {
923 const LValue& L1 = GetLValue(St, U->getSubExpr());
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000924 NonLValue R1 = cast<NonLValue>(GetValue(St, L1));
Ted Kremenek7b8009a2008-01-24 02:28:56 +0000925
926 QualType T = U->getType();
Ted Kremenekcb48b9c2008-01-29 00:33:40 +0000927 unsigned bits = getContext().getTypeSize(T, U->getLocStart());
Ted Kremenek5ee4ff82008-01-25 22:55:56 +0000928 APSInt One(llvm::APInt(bits, 1), T->isUnsignedIntegerType());
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000929 NonLValue R2 = NonLValue::GetValue(ValMgr, One);
Ted Kremeneke0cf9c82008-01-24 19:00:57 +0000930
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000931 NonLValue Result = R1.Add(ValMgr, R2);
Ted Kremenek7b8009a2008-01-24 02:28:56 +0000932 Nodify(Dst, U, N1, SetValue(SetValue(St, U, R1), L1, Result));
933 break;
934 }
935
936 case UnaryOperator::PostDec: {
937 const LValue& L1 = GetLValue(St, U->getSubExpr());
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000938 NonLValue R1 = cast<NonLValue>(GetValue(St, L1));
Ted Kremenek7b8009a2008-01-24 02:28:56 +0000939
940 QualType T = U->getType();
Ted Kremenekcb48b9c2008-01-29 00:33:40 +0000941 unsigned bits = getContext().getTypeSize(T, U->getLocStart());
Ted Kremenek5ee4ff82008-01-25 22:55:56 +0000942 APSInt One(llvm::APInt(bits, 1), T->isUnsignedIntegerType());
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000943 NonLValue R2 = NonLValue::GetValue(ValMgr, One);
Ted Kremenek7b8009a2008-01-24 02:28:56 +0000944
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000945 NonLValue Result = R1.Sub(ValMgr, R2);
Ted Kremenek7b8009a2008-01-24 02:28:56 +0000946 Nodify(Dst, U, N1, SetValue(SetValue(St, U, R1), L1, Result));
947 break;
948 }
949
950 case UnaryOperator::PreInc: {
951 const LValue& L1 = GetLValue(St, U->getSubExpr());
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000952 NonLValue R1 = cast<NonLValue>(GetValue(St, L1));
Ted Kremenek7b8009a2008-01-24 02:28:56 +0000953
954 QualType T = U->getType();
Ted Kremenekcb48b9c2008-01-29 00:33:40 +0000955 unsigned bits = getContext().getTypeSize(T, U->getLocStart());
Ted Kremenek5ee4ff82008-01-25 22:55:56 +0000956 APSInt One(llvm::APInt(bits, 1), T->isUnsignedIntegerType());
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000957 NonLValue R2 = NonLValue::GetValue(ValMgr, One);
Ted Kremenek7b8009a2008-01-24 02:28:56 +0000958
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000959 NonLValue Result = R1.Add(ValMgr, R2);
Ted Kremenek7b8009a2008-01-24 02:28:56 +0000960 Nodify(Dst, U, N1, SetValue(SetValue(St, U, Result), L1, Result));
961 break;
962 }
963
964 case UnaryOperator::PreDec: {
965 const LValue& L1 = GetLValue(St, U->getSubExpr());
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000966 NonLValue R1 = cast<NonLValue>(GetValue(St, L1));
Ted Kremenek7b8009a2008-01-24 02:28:56 +0000967
968 QualType T = U->getType();
Ted Kremenekcb48b9c2008-01-29 00:33:40 +0000969 unsigned bits = getContext().getTypeSize(T, U->getLocStart());
Ted Kremenek5ee4ff82008-01-25 22:55:56 +0000970 APSInt One(llvm::APInt(bits, 1), T->isUnsignedIntegerType());
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000971 NonLValue R2 = NonLValue::GetValue(ValMgr, One);
Ted Kremenek7b8009a2008-01-24 02:28:56 +0000972
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000973 NonLValue Result = R1.Sub(ValMgr, R2);
Ted Kremenek7b8009a2008-01-24 02:28:56 +0000974 Nodify(Dst, U, N1, SetValue(SetValue(St, U, Result), L1, Result));
975 break;
976 }
977
Ted Kremenekdacbb4f2008-01-24 08:20:02 +0000978 case UnaryOperator::Minus: {
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000979 const NonLValue& R1 = cast<NonLValue>(GetValue(St, U->getSubExpr()));
980 Nodify(Dst, U, N1, SetValue(St, U, R1.UnaryMinus(ValMgr, U)));
Ted Kremenekdacbb4f2008-01-24 08:20:02 +0000981 break;
982 }
983
Ted Kremenek7b8009a2008-01-24 02:28:56 +0000984 default: ;
985 assert (false && "Not implemented.");
986 }
987 }
988}
989
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000990void GRConstants::VisitBinaryOperator(BinaryOperator* B,
991 GRConstants::NodeTy* Pred,
992 GRConstants::NodeSet& Dst) {
993 NodeSet S1;
994 Visit(B->getLHS(), Pred, S1);
Ted Kremenekcb448ca2008-01-16 00:53:15 +0000995
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000996 for (NodeSet::iterator I1=S1.begin(), E1=S1.end(); I1 != E1; ++I1) {
997 NodeTy* N1 = *I1;
Ted Kremeneke00fe3f2008-01-17 00:52:48 +0000998
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000999 // When getting the value for the LHS, check if we are in an assignment.
1000 // In such cases, we want to (initially) treat the LHS as an LValue,
1001 // so we use GetLValue instead of GetValue so that DeclRefExpr's are
Ted Kremenekbd03f1d2008-01-28 22:09:13 +00001002 // evaluated to LValueDecl's instead of to an NonLValue.
1003 const RValue& V1 =
Ted Kremenekab2b8c52008-01-23 19:59:44 +00001004 B->isAssignmentOp() ? GetLValue(N1->getState(), B->getLHS())
1005 : GetValue(N1->getState(), B->getLHS());
Ted Kremenekcb448ca2008-01-16 00:53:15 +00001006
Ted Kremenekab2b8c52008-01-23 19:59:44 +00001007 NodeSet S2;
1008 Visit(B->getRHS(), N1, S2);
1009
1010 for (NodeSet::iterator I2=S2.begin(), E2=S2.end(); I2 != E2; ++I2) {
1011 NodeTy* N2 = *I2;
1012 StateTy St = N2->getState();
Ted Kremenekbd03f1d2008-01-28 22:09:13 +00001013 const RValue& V2 = GetValue(St, B->getRHS());
Ted Kremenekab2b8c52008-01-23 19:59:44 +00001014
1015 switch (B->getOpcode()) {
1016 case BinaryOperator::Add: {
Ted Kremenekbd03f1d2008-01-28 22:09:13 +00001017 const NonLValue& R1 = cast<NonLValue>(V1);
1018 const NonLValue& R2 = cast<NonLValue>(V2);
Ted Kremenekab2b8c52008-01-23 19:59:44 +00001019
Ted Kremenekbd03f1d2008-01-28 22:09:13 +00001020 Nodify(Dst, B, N2, SetValue(St, B, R1.Add(ValMgr, R2)));
Ted Kremenekab2b8c52008-01-23 19:59:44 +00001021 break;
1022 }
1023
1024 case BinaryOperator::Sub: {
Ted Kremenekbd03f1d2008-01-28 22:09:13 +00001025 const NonLValue& R1 = cast<NonLValue>(V1);
1026 const NonLValue& R2 = cast<NonLValue>(V2);
1027 Nodify(Dst, B, N2, SetValue(St, B, R1.Sub(ValMgr, R2)));
Ted Kremenekab2b8c52008-01-23 19:59:44 +00001028 break;
1029 }
1030
Ted Kremenek2eafd0e2008-01-23 23:42:27 +00001031 case BinaryOperator::Mul: {
Ted Kremenekbd03f1d2008-01-28 22:09:13 +00001032 const NonLValue& R1 = cast<NonLValue>(V1);
1033 const NonLValue& R2 = cast<NonLValue>(V2);
1034 Nodify(Dst, B, N2, SetValue(St, B, R1.Mul(ValMgr, R2)));
Ted Kremenek2eafd0e2008-01-23 23:42:27 +00001035 break;
1036 }
1037
Ted Kremenek5ee4ff82008-01-25 22:55:56 +00001038 case BinaryOperator::Div: {
Ted Kremenekbd03f1d2008-01-28 22:09:13 +00001039 const NonLValue& R1 = cast<NonLValue>(V1);
1040 const NonLValue& R2 = cast<NonLValue>(V2);
1041 Nodify(Dst, B, N2, SetValue(St, B, R1.Div(ValMgr, R2)));
Ted Kremenek5ee4ff82008-01-25 22:55:56 +00001042 break;
1043 }
1044
Ted Kremenekcce207d2008-01-28 22:26:15 +00001045 case BinaryOperator::Rem: {
1046 const NonLValue& R1 = cast<NonLValue>(V1);
1047 const NonLValue& R2 = cast<NonLValue>(V2);
1048 Nodify(Dst, B, N2, SetValue(St, B, R1.Rem(ValMgr, R2)));
1049 break;
1050 }
1051
Ted Kremenekab2b8c52008-01-23 19:59:44 +00001052 case BinaryOperator::Assign: {
1053 const LValue& L1 = cast<LValue>(V1);
Ted Kremenekbd03f1d2008-01-28 22:09:13 +00001054 const NonLValue& R2 = cast<NonLValue>(V2);
Ted Kremenekab2b8c52008-01-23 19:59:44 +00001055 Nodify(Dst, B, N2, SetValue(SetValue(St, B, R2), L1, R2));
1056 break;
1057 }
Ted Kremenekb4ae33f2008-01-23 23:38:00 +00001058
1059 case BinaryOperator::AddAssign: {
1060 const LValue& L1 = cast<LValue>(V1);
Ted Kremenekbd03f1d2008-01-28 22:09:13 +00001061 NonLValue R1 = cast<NonLValue>(GetValue(N1->getState(), L1));
1062 NonLValue Result = R1.Add(ValMgr, cast<NonLValue>(V2));
Ted Kremenekb4ae33f2008-01-23 23:38:00 +00001063 Nodify(Dst, B, N2, SetValue(SetValue(St, B, Result), L1, Result));
1064 break;
1065 }
1066
1067 case BinaryOperator::SubAssign: {
1068 const LValue& L1 = cast<LValue>(V1);
Ted Kremenekbd03f1d2008-01-28 22:09:13 +00001069 NonLValue R1 = cast<NonLValue>(GetValue(N1->getState(), L1));
1070 NonLValue Result = R1.Sub(ValMgr, cast<NonLValue>(V2));
Ted Kremenekb4ae33f2008-01-23 23:38:00 +00001071 Nodify(Dst, B, N2, SetValue(SetValue(St, B, Result), L1, Result));
1072 break;
1073 }
Ted Kremenek2eafd0e2008-01-23 23:42:27 +00001074
1075 case BinaryOperator::MulAssign: {
1076 const LValue& L1 = cast<LValue>(V1);
Ted Kremenekbd03f1d2008-01-28 22:09:13 +00001077 NonLValue R1 = cast<NonLValue>(GetValue(N1->getState(), L1));
1078 NonLValue Result = R1.Mul(ValMgr, cast<NonLValue>(V2));
Ted Kremenek2eafd0e2008-01-23 23:42:27 +00001079 Nodify(Dst, B, N2, SetValue(SetValue(St, B, Result), L1, Result));
1080 break;
1081 }
Ted Kremenek5c1e2622008-01-25 23:45:34 +00001082
1083 case BinaryOperator::DivAssign: {
1084 const LValue& L1 = cast<LValue>(V1);
Ted Kremenekbd03f1d2008-01-28 22:09:13 +00001085 NonLValue R1 = cast<NonLValue>(GetValue(N1->getState(), L1));
1086 NonLValue Result = R1.Div(ValMgr, cast<NonLValue>(V2));
Ted Kremenek5c1e2622008-01-25 23:45:34 +00001087 Nodify(Dst, B, N2, SetValue(SetValue(St, B, Result), L1, Result));
1088 break;
1089 }
Ted Kremenek10099a62008-01-28 22:28:54 +00001090
1091 case BinaryOperator::RemAssign: {
1092 const LValue& L1 = cast<LValue>(V1);
1093 NonLValue R1 = cast<NonLValue>(GetValue(N1->getState(), L1));
1094 NonLValue Result = R1.Rem(ValMgr, cast<NonLValue>(V2));
1095 Nodify(Dst, B, N2, SetValue(SetValue(St, B, Result), L1, Result));
1096 break;
1097 }
Ted Kremenekab2b8c52008-01-23 19:59:44 +00001098
1099 default:
1100 Dst.Add(N2);
1101 break;
1102 }
Ted Kremenekcb448ca2008-01-16 00:53:15 +00001103 }
Ted Kremenekd27f8162008-01-15 23:55:06 +00001104 }
Ted Kremenekd27f8162008-01-15 23:55:06 +00001105}
Ted Kremenekee985462008-01-16 18:18:48 +00001106
Ted Kremenek1ccd31c2008-01-16 19:42:59 +00001107
Ted Kremenekab2b8c52008-01-23 19:59:44 +00001108void GRConstants::Visit(Stmt* S, GRConstants::NodeTy* Pred,
1109 GRConstants::NodeSet& Dst) {
1110
1111 // FIXME: add metadata to the CFG so that we can disable
1112 // this check when we KNOW that there is no block-level subexpression.
1113 // The motivation is that this check requires a hashtable lookup.
1114
1115 if (S != CurrentStmt && getCFG().isBlkExpr(S)) {
1116 Dst.Add(Pred);
1117 return;
1118 }
1119
1120 switch (S->getStmtClass()) {
1121 case Stmt::BinaryOperatorClass:
Ted Kremenekb4ae33f2008-01-23 23:38:00 +00001122 case Stmt::CompoundAssignOperatorClass:
Ted Kremenekab2b8c52008-01-23 19:59:44 +00001123 VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Dst);
1124 break;
1125
Ted Kremenek7b8009a2008-01-24 02:28:56 +00001126 case Stmt::UnaryOperatorClass:
1127 VisitUnaryOperator(cast<UnaryOperator>(S), Pred, Dst);
1128 break;
1129
Ted Kremenekab2b8c52008-01-23 19:59:44 +00001130 case Stmt::ParenExprClass:
1131 Visit(cast<ParenExpr>(S)->getSubExpr(), Pred, Dst);
1132 break;
1133
Ted Kremenek874d63f2008-01-24 02:02:54 +00001134 case Stmt::ImplicitCastExprClass: {
1135 ImplicitCastExpr* C = cast<ImplicitCastExpr>(S);
1136 VisitCast(C, C->getSubExpr(), Pred, Dst);
1137 break;
1138 }
1139
1140 case Stmt::CastExprClass: {
1141 CastExpr* C = cast<CastExpr>(S);
1142 VisitCast(C, C->getSubExpr(), Pred, Dst);
1143 break;
1144 }
1145
Ted Kremenek9de04c42008-01-24 20:55:43 +00001146 case Stmt::DeclStmtClass:
1147 VisitDeclStmt(cast<DeclStmt>(S), Pred, Dst);
1148 break;
1149
Ted Kremenekab2b8c52008-01-23 19:59:44 +00001150 default:
1151 Dst.Add(Pred); // No-op. Simply propagate the current state unchanged.
1152 break;
Ted Kremenek79649df2008-01-17 18:25:22 +00001153 }
Ted Kremenek1ccd31c2008-01-16 19:42:59 +00001154}
1155
Ted Kremenekee985462008-01-16 18:18:48 +00001156//===----------------------------------------------------------------------===//
1157// Driver.
1158//===----------------------------------------------------------------------===//
1159
Ted Kremenekaa66a322008-01-16 21:46:15 +00001160#ifndef NDEBUG
1161namespace llvm {
1162template<>
1163struct VISIBILITY_HIDDEN DOTGraphTraits<GRConstants::NodeTy*> :
1164 public DefaultDOTGraphTraits {
Ted Kremenek9ff731d2008-01-24 22:27:20 +00001165
1166 static void PrintKindLabel(std::ostream& Out, ValueKey::Kind kind) {
Ted Kremenek803c9ed2008-01-23 22:30:44 +00001167 switch (kind) {
Ted Kremenek565256e2008-01-24 22:44:24 +00001168 case ValueKey::IsSubExpr: Out << "Sub-Expressions:\\l"; break;
Ted Kremenek803c9ed2008-01-23 22:30:44 +00001169 case ValueKey::IsDecl: Out << "Variables:\\l"; break;
1170 case ValueKey::IsBlkExpr: Out << "Block-level Expressions:\\l"; break;
1171 default: assert (false && "Unknown ValueKey type.");
1172 }
1173 }
1174
Ted Kremenek9ff731d2008-01-24 22:27:20 +00001175 static void PrintKind(std::ostream& Out, GRConstants::StateTy M,
1176 ValueKey::Kind kind, bool isFirstGroup = false) {
1177 bool isFirst = true;
1178
1179 for (GRConstants::StateTy::iterator I=M.begin(), E=M.end();I!=E;++I) {
1180 if (I.getKey().getKind() != kind)
1181 continue;
1182
1183 if (isFirst) {
1184 if (!isFirstGroup) Out << "\\l\\l";
1185 PrintKindLabel(Out, kind);
1186 isFirst = false;
1187 }
1188 else
1189 Out << "\\l";
1190
1191 Out << ' ';
1192
1193 if (ValueDecl* V = dyn_cast<ValueDecl>(I.getKey()))
1194 Out << V->getName();
1195 else {
1196 Stmt* E = cast<Stmt>(I.getKey());
1197 Out << " (" << (void*) E << ") ";
1198 E->printPretty(Out);
1199 }
1200
1201 Out << " : ";
1202 I.getData().print(Out);
1203 }
1204 }
1205
Ted Kremenekaa66a322008-01-16 21:46:15 +00001206 static std::string getNodeLabel(const GRConstants::NodeTy* N, void*) {
1207 std::ostringstream Out;
Ted Kremenek803c9ed2008-01-23 22:30:44 +00001208
1209 // Program Location.
Ted Kremenekaa66a322008-01-16 21:46:15 +00001210 ProgramPoint Loc = N->getLocation();
1211
1212 switch (Loc.getKind()) {
1213 case ProgramPoint::BlockEntranceKind:
1214 Out << "Block Entrance: B"
1215 << cast<BlockEntrance>(Loc).getBlock()->getBlockID();
1216 break;
1217
1218 case ProgramPoint::BlockExitKind:
1219 assert (false);
1220 break;
1221
1222 case ProgramPoint::PostStmtKind: {
1223 const PostStmt& L = cast<PostStmt>(Loc);
Ted Kremenek9ff731d2008-01-24 22:27:20 +00001224 Out << L.getStmt()->getStmtClassName() << ':'
1225 << (void*) L.getStmt() << ' ';
1226
Ted Kremenekaa66a322008-01-16 21:46:15 +00001227 L.getStmt()->printPretty(Out);
1228 break;
1229 }
1230
1231 default: {
1232 const BlockEdge& E = cast<BlockEdge>(Loc);
1233 Out << "Edge: (B" << E.getSrc()->getBlockID() << ", B"
1234 << E.getDst()->getBlockID() << ')';
1235 }
1236 }
1237
Ted Kremenek803c9ed2008-01-23 22:30:44 +00001238 Out << "\\|";
Ted Kremenekaa66a322008-01-16 21:46:15 +00001239
Ted Kremenek9ff731d2008-01-24 22:27:20 +00001240 PrintKind(Out, N->getState(), ValueKey::IsDecl, true);
1241 PrintKind(Out, N->getState(), ValueKey::IsBlkExpr);
Ted Kremenek565256e2008-01-24 22:44:24 +00001242 PrintKind(Out, N->getState(), ValueKey::IsSubExpr);
Ted Kremenek803c9ed2008-01-23 22:30:44 +00001243
Ted Kremenek803c9ed2008-01-23 22:30:44 +00001244 Out << "\\l";
Ted Kremenekaa66a322008-01-16 21:46:15 +00001245 return Out.str();
1246 }
1247};
1248} // end llvm namespace
1249#endif
1250
Ted Kremenekee985462008-01-16 18:18:48 +00001251namespace clang {
Ted Kremenekcb48b9c2008-01-29 00:33:40 +00001252void RunGRConstants(CFG& cfg, FunctionDecl& FD, ASTContext& Ctx) {
1253 GREngine<GRConstants> Engine(cfg, FD, Ctx);
Ted Kremenekee985462008-01-16 18:18:48 +00001254 Engine.ExecuteWorkList();
Ted Kremenekaa66a322008-01-16 21:46:15 +00001255#ifndef NDEBUG
1256 llvm::ViewGraph(*Engine.getGraph().roots_begin(),"GRConstants");
1257#endif
Ted Kremenekee985462008-01-16 18:18:48 +00001258}
Ted Kremenekab2b8c52008-01-23 19:59:44 +00001259} // end clang namespace