blob: f2676a0e6eecc3c3d7a803d629f6201d27ee0e6a [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 Kremenek68fd2572008-01-29 17:27:31 +000051class SymbolID {
52 unsigned Data;
53public:
54 SymbolID() : Data(~0) {}
55 SymbolID(unsigned x) : Data(x) {}
Ted Kremenekab2b8c52008-01-23 19:59:44 +000056
Ted Kremenek68fd2572008-01-29 17:27:31 +000057 bool isInitialized() const { return Data != (unsigned) ~0; }
58 operator unsigned() const { assert (isInitialized()); return Data; }
59};
60
Ted Kremenekab2b8c52008-01-23 19:59:44 +000061class VISIBILITY_HIDDEN ValueKey {
Ted Kremenekbd03f1d2008-01-28 22:09:13 +000062 uintptr_t Raw;
Ted Kremenekcc1c3652008-01-25 23:43:12 +000063 void operator=(const ValueKey& RHS); // Do not implement.
Ted Kremenekbd03f1d2008-01-28 22:09:13 +000064
Ted Kremenekd27f8162008-01-15 23:55:06 +000065public:
Ted Kremenekbd03f1d2008-01-28 22:09:13 +000066 enum Kind { IsSubExpr=0x0, IsBlkExpr=0x1, IsDecl=0x2, // L-Value Bindings.
67 IsSymbol=0x3, // Symbol Bindings.
68 Flags=0x3 };
69
70 inline Kind getKind() const {
71 return (Kind) (Raw & Flags);
72 }
73
74 inline void* getPtr() const {
75 assert (getKind() != IsSymbol);
76 return reinterpret_cast<void*>(Raw & ~Flags);
77 }
78
79 inline SymbolID getSymbolID() const {
80 assert (getKind() == IsSymbol);
Ted Kremenek68fd2572008-01-29 17:27:31 +000081 return Raw >> 2;
Ted Kremenekbd03f1d2008-01-28 22:09:13 +000082 }
Ted Kremenekd27f8162008-01-15 23:55:06 +000083
Ted Kremenekab2b8c52008-01-23 19:59:44 +000084 ValueKey(const ValueDecl* VD)
Ted Kremenekbd03f1d2008-01-28 22:09:13 +000085 : Raw(reinterpret_cast<uintptr_t>(VD) | IsDecl) {
86 assert(VD && "ValueDecl cannot be NULL.");
87 }
Ted Kremenekab2b8c52008-01-23 19:59:44 +000088
Ted Kremenek5c1b9962008-01-24 19:43:37 +000089 ValueKey(Stmt* S, bool isBlkExpr = false)
Ted Kremenekcc1c3652008-01-25 23:43:12 +000090 : Raw(reinterpret_cast<uintptr_t>(S) | (isBlkExpr ? IsBlkExpr : IsSubExpr)){
Ted Kremenekbd03f1d2008-01-28 22:09:13 +000091 assert(S && "Tracked statement cannot be NULL.");
Ted Kremenekcc1c3652008-01-25 23:43:12 +000092 }
Ted Kremenekd27f8162008-01-15 23:55:06 +000093
Ted Kremenekbd03f1d2008-01-28 22:09:13 +000094 ValueKey(SymbolID V)
95 : Raw((V << 2) | IsSymbol) {}
96
97 bool isSymbol() const { return getKind() == IsSymbol; }
Ted Kremenek565256e2008-01-24 22:44:24 +000098 bool isSubExpr() const { return getKind() == IsSubExpr; }
Ted Kremenek65cac132008-01-29 05:25:31 +000099 bool isBlkExpr() const { return getKind() == IsBlkExpr; }
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000100 bool isDecl() const { return getKind() == IsDecl; }
Ted Kremenek65cac132008-01-29 05:25:31 +0000101 bool isStmt() const { return getKind() <= IsBlkExpr; }
Ted Kremenekd27f8162008-01-15 23:55:06 +0000102
103 inline void Profile(llvm::FoldingSetNodeID& ID) const {
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000104 ID.AddInteger(isSymbol() ? 1 : 0);
105
106 if (isSymbol())
Ted Kremenekf2645622008-01-28 22:25:21 +0000107 ID.AddInteger(getSymbolID());
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000108 else
109 ID.AddPointer(getPtr());
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000110 }
111
112 inline bool operator==(const ValueKey& X) const {
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000113 return isSymbol() ? getSymbolID() == X.getSymbolID()
114 : getPtr() == X.getPtr();
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000115 }
116
117 inline bool operator!=(const ValueKey& X) const {
118 return !operator==(X);
119 }
120
121 inline bool operator<(const ValueKey& X) const {
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000122 if (isSymbol())
123 return X.isSymbol() ? getSymbolID() < X.getSymbolID() : false;
Ted Kremenek5c1b9962008-01-24 19:43:37 +0000124
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000125 return getPtr() < X.getPtr();
Ted Kremenekb3d2dca2008-01-16 23:33:44 +0000126 }
Ted Kremenekd27f8162008-01-15 23:55:06 +0000127};
128} // end anonymous namespace
129
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000130// Machinery to get cast<> and dyn_cast<> working with ValueKey.
Ted Kremenekd27f8162008-01-15 23:55:06 +0000131namespace llvm {
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000132 template<> inline bool isa<ValueDecl,ValueKey>(const ValueKey& V) {
133 return V.getKind() == ValueKey::IsDecl;
Ted Kremenekd27f8162008-01-15 23:55:06 +0000134 }
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000135 template<> inline bool isa<Stmt,ValueKey>(const ValueKey& V) {
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000136 return ((unsigned) V.getKind()) < ValueKey::IsDecl;
Ted Kremenekd27f8162008-01-15 23:55:06 +0000137 }
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000138 template<> struct VISIBILITY_HIDDEN cast_retty_impl<ValueDecl,ValueKey> {
Ted Kremenekaa66a322008-01-16 21:46:15 +0000139 typedef const ValueDecl* ret_type;
Ted Kremenekd27f8162008-01-15 23:55:06 +0000140 };
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000141 template<> struct VISIBILITY_HIDDEN cast_retty_impl<Stmt,ValueKey> {
Ted Kremenekd27f8162008-01-15 23:55:06 +0000142 typedef const Stmt* ret_type;
143 };
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000144 template<> struct VISIBILITY_HIDDEN simplify_type<ValueKey> {
Ted Kremenekd27f8162008-01-15 23:55:06 +0000145 typedef void* SimpleType;
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000146 static inline SimpleType getSimplifiedValue(const ValueKey &V) {
Ted Kremenekd27f8162008-01-15 23:55:06 +0000147 return V.getPtr();
148 }
149 };
150} // end llvm namespace
151
Ted Kremenek68fd2572008-01-29 17:27:31 +0000152
153//===----------------------------------------------------------------------===//
154// SymbolManager.
155//===----------------------------------------------------------------------===//
156
157namespace {
158class VISIBILITY_HIDDEN SymbolData {
159 uintptr_t Data;
160public:
161 enum Kind { ParmKind = 0x0, Mask = 0x3 };
162
163 SymbolData(ParmVarDecl* D)
164 : Data(reinterpret_cast<uintptr_t>(D) | ParmKind) {}
165
166 inline Kind getKind() const { return (Kind) (Data & Mask); }
167 inline void* getPtr() const { return reinterpret_cast<void*>(Data & ~Mask); }
168 inline bool operator==(const SymbolData& R) const { return Data == R.Data; }
169};
170}
171
172// Machinery to get cast<> and dyn_cast<> working with SymbolData.
173namespace llvm {
174 template<> inline bool isa<ParmVarDecl,SymbolData>(const SymbolData& V) {
175 return V.getKind() == SymbolData::ParmKind;
176 }
177 template<> struct VISIBILITY_HIDDEN cast_retty_impl<ParmVarDecl,SymbolData> {
178 typedef const ParmVarDecl* ret_type;
179 };
180 template<> struct VISIBILITY_HIDDEN simplify_type<SymbolData> {
181 typedef void* SimpleType;
182 static inline SimpleType getSimplifiedValue(const SymbolData &V) {
183 return V.getPtr();
184 }
185 };
186} // end llvm namespace
187
188namespace {
189class VISIBILITY_HIDDEN SymbolManager {
190 std::vector<SymbolData> SymbolToData;
191
192 typedef llvm::DenseMap<void*,SymbolID> MapTy;
193 MapTy DataToSymbol;
194
195public:
196 SymbolData getSymbolData(SymbolID id) const {
197 assert (id < SymbolToData.size());
198 return SymbolToData[id];
199 }
200
201 SymbolID getSymbol(ParmVarDecl* D);
202};
203} // end anonymous namespace
204
205SymbolID SymbolManager::getSymbol(ParmVarDecl* D) {
206 SymbolID& X = DataToSymbol[D];
207
208 if (!X.isInitialized()) {
209 X = SymbolToData.size();
210 SymbolToData.push_back(D);
211 }
212
213 return X;
214}
215
Ted Kremenekd27f8162008-01-15 23:55:06 +0000216//===----------------------------------------------------------------------===//
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000217// ValueManager.
Ted Kremenekd27f8162008-01-15 23:55:06 +0000218//===----------------------------------------------------------------------===//
219
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000220namespace {
221
Ted Kremenek5ee4ff82008-01-25 22:55:56 +0000222typedef llvm::ImmutableSet<APSInt > APSIntSetTy;
223
224
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000225class VISIBILITY_HIDDEN ValueManager {
Ted Kremenekcb48b9c2008-01-29 00:33:40 +0000226 ASTContext& Ctx;
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000227
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000228 typedef llvm::FoldingSet<llvm::FoldingSetNodeWrapper<APSInt> > APSIntSetTy;
229 APSIntSetTy APSIntSet;
230
231 llvm::BumpPtrAllocator BPAlloc;
232
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000233public:
Ted Kremenekcb48b9c2008-01-29 00:33:40 +0000234 ValueManager(ASTContext& ctx) : Ctx(ctx) {}
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000235 ~ValueManager();
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000236
Ted Kremenekcb48b9c2008-01-29 00:33:40 +0000237 ASTContext& getContext() const { return Ctx; }
Ted Kremenek687af802008-01-29 19:43:15 +0000238 APSInt& getValue(const APSInt& X);
239 APSInt& getValue(uint64_t X, unsigned BitWidth, bool isUnsigned);
240 APSInt& getValue(uint64_t X, QualType T,
241 SourceLocation Loc = SourceLocation());
Ted Kremenekd27f8162008-01-15 23:55:06 +0000242};
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000243} // end anonymous namespace
244
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000245ValueManager::~ValueManager() {
246 // Note that the dstor for the contents of APSIntSet will never be called,
247 // so we iterate over the set and invoke the dstor for each APSInt. This
248 // frees an aux. memory allocated to represent very large constants.
249 for (APSIntSetTy::iterator I=APSIntSet.begin(), E=APSIntSet.end(); I!=E; ++I)
250 I->getValue().~APSInt();
251}
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000252
253APSInt& ValueManager::getValue(const APSInt& X) {
254 llvm::FoldingSetNodeID ID;
255 void* InsertPos;
256 typedef llvm::FoldingSetNodeWrapper<APSInt> FoldNodeTy;
Ted Kremenekcc1c3652008-01-25 23:43:12 +0000257
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000258 X.Profile(ID);
259 FoldNodeTy* P = APSIntSet.FindNodeOrInsertPos(ID, InsertPos);
Ted Kremenek5ee4ff82008-01-25 22:55:56 +0000260
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000261 if (!P) {
262 P = (FoldNodeTy*) BPAlloc.Allocate<FoldNodeTy>();
263 new (P) FoldNodeTy(X);
264 APSIntSet.InsertNode(P, InsertPos);
265 }
266
267 return *P;
Ted Kremenek5ee4ff82008-01-25 22:55:56 +0000268}
269
Ted Kremenek687af802008-01-29 19:43:15 +0000270APSInt& ValueManager::getValue(uint64_t X, unsigned BitWidth, bool isUnsigned) {
271 APSInt V(BitWidth, isUnsigned);
272 V = X;
273 return getValue(V);
274}
275
276APSInt& ValueManager::getValue(uint64_t X, QualType T, SourceLocation Loc) {
277 unsigned bits = Ctx.getTypeSize(T, Loc);
278 APSInt V(bits, T->isUnsignedIntegerType());
279 V = X;
280 return getValue(V);
281}
282
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000283//===----------------------------------------------------------------------===//
284// Expression Values.
285//===----------------------------------------------------------------------===//
Ted Kremenekf13794e2008-01-24 23:19:54 +0000286
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000287namespace {
288
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000289class VISIBILITY_HIDDEN RValue {
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000290public:
Ted Kremenek403c1812008-01-28 22:51:57 +0000291 enum BaseKind { LValueKind=0x0, NonLValueKind=0x1,
Ted Kremenek6753fe32008-01-30 18:54:06 +0000292 UninitializedKind=0x2, InvalidKind=0x3 };
293
294 enum { BaseBits = 2, BaseMask = 0x3 };
Ted Kremenekf13794e2008-01-24 23:19:54 +0000295
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000296private:
Ted Kremenekf2645622008-01-28 22:25:21 +0000297 void* Data;
Ted Kremenekf13794e2008-01-24 23:19:54 +0000298 unsigned Kind;
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000299
300protected:
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000301 RValue(const void* d, bool isLValue, unsigned ValKind)
Ted Kremenekf2645622008-01-28 22:25:21 +0000302 : Data(const_cast<void*>(d)),
Ted Kremenek6753fe32008-01-30 18:54:06 +0000303 Kind((isLValue ? LValueKind : NonLValueKind) | (ValKind << BaseBits)) {}
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000304
Ted Kremenek403c1812008-01-28 22:51:57 +0000305 explicit RValue(BaseKind k)
306 : Data(0), Kind(k) {}
Ted Kremenekf2645622008-01-28 22:25:21 +0000307
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000308 void* getRawPtr() const {
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000309 return reinterpret_cast<void*>(Data);
310 }
311
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000312public:
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000313 ~RValue() {};
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000314
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000315 RValue Cast(ValueManager& ValMgr, Expr* CastExpr) const;
Ted Kremenek874d63f2008-01-24 02:02:54 +0000316
Ted Kremenekf13794e2008-01-24 23:19:54 +0000317 unsigned getRawKind() const { return Kind; }
Ted Kremenek6753fe32008-01-30 18:54:06 +0000318 BaseKind getBaseKind() const { return (BaseKind) (Kind & BaseMask); }
319 unsigned getSubKind() const { return (Kind & ~BaseMask) >> BaseBits; }
Ted Kremenekf13794e2008-01-24 23:19:54 +0000320
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000321 void Profile(llvm::FoldingSetNodeID& ID) const {
Ted Kremenekf13794e2008-01-24 23:19:54 +0000322 ID.AddInteger((unsigned) getRawKind());
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000323 ID.AddPointer(reinterpret_cast<void*>(Data));
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000324 }
325
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000326 bool operator==(const RValue& RHS) const {
Ted Kremenekf13794e2008-01-24 23:19:54 +0000327 return getRawKind() == RHS.getRawKind() && Data == RHS.Data;
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000328 }
329
Ted Kremenekf13794e2008-01-24 23:19:54 +0000330 inline bool isValid() const { return getRawKind() != InvalidKind; }
331 inline bool isInvalid() const { return getRawKind() == InvalidKind; }
332
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000333 void print(std::ostream& OS) const;
334 void print() const { print(*llvm::cerr.stream()); }
335
336 // Implement isa<T> support.
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000337 static inline bool classof(const RValue*) { return true; }
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000338};
339
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000340class VISIBILITY_HIDDEN InvalidValue : public RValue {
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000341public:
Ted Kremenek403c1812008-01-28 22:51:57 +0000342 InvalidValue() : RValue(InvalidKind) {}
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000343
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000344 static inline bool classof(const RValue* V) {
Ted Kremenekf13794e2008-01-24 23:19:54 +0000345 return V->getBaseKind() == InvalidKind;
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000346 }
347};
Ted Kremenek403c1812008-01-28 22:51:57 +0000348
349class VISIBILITY_HIDDEN UninitializedValue : public RValue {
350public:
351 UninitializedValue() : RValue(UninitializedKind) {}
352
353 static inline bool classof(const RValue* V) {
354 return V->getBaseKind() == UninitializedKind;
355 }
356};
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000357
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000358class VISIBILITY_HIDDEN NonLValue : public RValue {
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000359protected:
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000360 NonLValue(unsigned SubKind, const void* d) : RValue(d, false, SubKind) {}
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000361
362public:
Ted Kremenekf13794e2008-01-24 23:19:54 +0000363 void print(std::ostream& Out) const;
364
Ted Kremenek687af802008-01-29 19:43:15 +0000365 // Arithmetic operators.
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000366 NonLValue Add(ValueManager& ValMgr, const NonLValue& RHS) const;
367 NonLValue Sub(ValueManager& ValMgr, const NonLValue& RHS) const;
368 NonLValue Mul(ValueManager& ValMgr, const NonLValue& RHS) const;
369 NonLValue Div(ValueManager& ValMgr, const NonLValue& RHS) const;
370 NonLValue Rem(ValueManager& ValMgr, const NonLValue& RHS) const;
371 NonLValue UnaryMinus(ValueManager& ValMgr, UnaryOperator* U) const;
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000372
Ted Kremenek687af802008-01-29 19:43:15 +0000373 // Equality operators.
374 NonLValue EQ(ValueManager& ValMgr, const NonLValue& RHS) const;
375 NonLValue NE(ValueManager& ValMgr, const NonLValue& RHS) const;
Ted Kremenek68fd2572008-01-29 17:27:31 +0000376
Ted Kremenek687af802008-01-29 19:43:15 +0000377 // Utility methods to create NonLValues.
378 static NonLValue GetValue(ValueManager& ValMgr, uint64_t X, QualType T,
379 SourceLocation Loc = SourceLocation());
380
381 static NonLValue GetValue(ValueManager& ValMgr, IntegerLiteral* I);
Ted Kremenek68fd2572008-01-29 17:27:31 +0000382 static NonLValue GetSymbolValue(SymbolManager& SymMgr, ParmVarDecl *D);
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000383
Ted Kremenek687af802008-01-29 19:43:15 +0000384 static inline NonLValue GetIntTruthValue(ValueManager& ValMgr, bool X) {
385 return GetValue(ValMgr, X ? 1U : 0U, ValMgr.getContext().IntTy);
386 }
387
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000388 // Implement isa<T> support.
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000389 static inline bool classof(const RValue* V) {
Ted Kremenek403c1812008-01-28 22:51:57 +0000390 return V->getBaseKind() >= NonLValueKind;
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000391 }
392};
Ted Kremenek687af802008-01-29 19:43:15 +0000393
394class VISIBILITY_HIDDEN LValue : public RValue {
395protected:
396 LValue(unsigned SubKind, void* D) : RValue(D, true, SubKind) {}
397
398public:
399
400 // Equality operators.
401 NonLValue EQ(ValueManager& ValMgr, const LValue& RHS) const;
402 NonLValue NE(ValueManager& ValMgr, const LValue& RHS) const;
403
404 // Implement isa<T> support.
405 static inline bool classof(const RValue* V) {
406 return V->getBaseKind() == LValueKind;
407 }
408};
Ted Kremenekf13794e2008-01-24 23:19:54 +0000409
410} // end anonymous namespace
411
412//===----------------------------------------------------------------------===//
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000413// LValues.
Ted Kremenekf13794e2008-01-24 23:19:54 +0000414//===----------------------------------------------------------------------===//
415
416namespace {
417
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000418enum { LValueDeclKind, NumLValueKind };
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000419
420class VISIBILITY_HIDDEN LValueDecl : public LValue {
421public:
Ted Kremenek9de04c42008-01-24 20:55:43 +0000422 LValueDecl(const ValueDecl* vd)
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000423 : LValue(LValueDeclKind,const_cast<ValueDecl*>(vd)) {}
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000424
425 ValueDecl* getDecl() const {
426 return static_cast<ValueDecl*>(getRawPtr());
427 }
428
Ted Kremenek687af802008-01-29 19:43:15 +0000429 inline bool operator==(const LValueDecl& R) const {
430 return getDecl() == R.getDecl();
431 }
432
433 inline bool operator!=(const LValueDecl& R) const {
434 return getDecl() != R.getDecl();
435 }
436
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000437 // Implement isa<T> support.
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000438 static inline bool classof(const RValue* V) {
Ted Kremenekf13794e2008-01-24 23:19:54 +0000439 return V->getSubKind() == LValueDeclKind;
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000440 }
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000441};
442
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000443} // end anonymous namespace
444
445//===----------------------------------------------------------------------===//
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000446// Non-LValues.
447//===----------------------------------------------------------------------===//
448
449namespace {
450
Ted Kremenekf2645622008-01-28 22:25:21 +0000451enum { SymbolicNonLValueKind, ConcreteIntKind, ConstrainedIntegerKind,
452 NumNonLValueKind };
453
454class VISIBILITY_HIDDEN SymbolicNonLValue : public NonLValue {
455public:
456 SymbolicNonLValue(unsigned SymID)
457 : NonLValue(SymbolicNonLValueKind,
458 reinterpret_cast<void*>((uintptr_t) SymID)) {}
459
460 SymbolID getSymbolID() const {
461 return (SymbolID) reinterpret_cast<uintptr_t>(getRawPtr());
462 }
463
464 static inline bool classof(const RValue* V) {
465 return V->getSubKind() == SymbolicNonLValueKind;
466 }
467};
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000468
469class VISIBILITY_HIDDEN ConcreteInt : public NonLValue {
470public:
471 ConcreteInt(const APSInt& V) : NonLValue(ConcreteIntKind, &V) {}
472
473 const APSInt& getValue() const {
474 return *static_cast<APSInt*>(getRawPtr());
475 }
476
Ted Kremenek687af802008-01-29 19:43:15 +0000477 // Arithmetic operators.
478
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000479 ConcreteInt Add(ValueManager& ValMgr, const ConcreteInt& V) const {
480 return ValMgr.getValue(getValue() + V.getValue());
481 }
Ted Kremenek687af802008-01-29 19:43:15 +0000482
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000483 ConcreteInt Sub(ValueManager& ValMgr, const ConcreteInt& V) const {
484 return ValMgr.getValue(getValue() - V.getValue());
485 }
486
487 ConcreteInt Mul(ValueManager& ValMgr, const ConcreteInt& V) const {
488 return ValMgr.getValue(getValue() * V.getValue());
489 }
490
491 ConcreteInt Div(ValueManager& ValMgr, const ConcreteInt& V) const {
492 return ValMgr.getValue(getValue() / V.getValue());
493 }
494
495 ConcreteInt Rem(ValueManager& ValMgr, const ConcreteInt& V) const {
496 return ValMgr.getValue(getValue() % V.getValue());
497 }
498
Ted Kremenek687af802008-01-29 19:43:15 +0000499 ConcreteInt UnaryMinus(ValueManager& ValMgr, UnaryOperator* U) const {
500 assert (U->getType() == U->getSubExpr()->getType());
501 assert (U->getType()->isIntegerType());
502 return ValMgr.getValue(-getValue());
503 }
504
505 // Casting.
506
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000507 ConcreteInt Cast(ValueManager& ValMgr, Expr* CastExpr) const {
508 assert (CastExpr->getType()->isIntegerType());
509
510 APSInt X(getValue());
Ted Kremenekcb48b9c2008-01-29 00:33:40 +0000511 X.extOrTrunc(ValMgr.getContext().getTypeSize(CastExpr->getType(),
512 CastExpr->getLocStart()));
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000513 return ValMgr.getValue(X);
514 }
515
Ted Kremenek687af802008-01-29 19:43:15 +0000516 // Equality operators.
517
518 ConcreteInt EQ(ValueManager& ValMgr, const ConcreteInt& V) const {
519 const APSInt& Val = getValue();
520 return ValMgr.getValue(Val == V.getValue() ? 1U : 0U,
521 Val.getBitWidth(), Val.isUnsigned());
522 }
523
524 ConcreteInt NE(ValueManager& ValMgr, const ConcreteInt& V) const {
525 const APSInt& Val = getValue();
526 return ValMgr.getValue(Val != V.getValue() ? 1U : 0U,
527 Val.getBitWidth(), Val.isUnsigned());
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000528 }
529
530 // Implement isa<T> support.
531 static inline bool classof(const RValue* V) {
532 return V->getSubKind() == ConcreteIntKind;
533 }
534};
535
536} // end anonymous namespace
537
538//===----------------------------------------------------------------------===//
Ted Kremenek687af802008-01-29 19:43:15 +0000539// Transfer function dispatch for Non-LValues.
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000540//===----------------------------------------------------------------------===//
541
542RValue RValue::Cast(ValueManager& ValMgr, Expr* CastExpr) const {
543 switch (getSubKind()) {
544 case ConcreteIntKind:
545 return cast<ConcreteInt>(this)->Cast(ValMgr, CastExpr);
546 default:
547 return InvalidValue();
548 }
549}
550
551NonLValue NonLValue::UnaryMinus(ValueManager& ValMgr, UnaryOperator* U) const {
552 switch (getSubKind()) {
553 case ConcreteIntKind:
554 return cast<ConcreteInt>(this)->UnaryMinus(ValMgr, U);
555 default:
556 return cast<NonLValue>(InvalidValue());
557 }
558}
559
Ted Kremenek687af802008-01-29 19:43:15 +0000560#define NONLVALUE_DISPATCH_CASE(k1,k2,Op)\
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000561case (k1##Kind*NumNonLValueKind+k2##Kind):\
562 return cast<k1>(*this).Op(ValMgr,cast<k2>(RHS));
563
Ted Kremenek687af802008-01-29 19:43:15 +0000564#define NONLVALUE_DISPATCH(Op)\
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000565switch (getSubKind()*NumNonLValueKind+RHS.getSubKind()){\
Ted Kremenek687af802008-01-29 19:43:15 +0000566 NONLVALUE_DISPATCH_CASE(ConcreteInt,ConcreteInt,Op)\
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000567 default:\
Ted Kremenek403c1812008-01-28 22:51:57 +0000568 if (getBaseKind() == UninitializedKind ||\
569 RHS.getBaseKind() == UninitializedKind)\
570 return cast<NonLValue>(UninitializedValue());\
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000571 assert (!isValid() || !RHS.isValid() && "Missing case.");\
572 break;\
573}\
574return cast<NonLValue>(InvalidValue());
575
576NonLValue NonLValue::Add(ValueManager& ValMgr, const NonLValue& RHS) const {
Ted Kremenek687af802008-01-29 19:43:15 +0000577 NONLVALUE_DISPATCH(Add)
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000578}
579
580NonLValue NonLValue::Sub(ValueManager& ValMgr, const NonLValue& RHS) const {
Ted Kremenek687af802008-01-29 19:43:15 +0000581 NONLVALUE_DISPATCH(Sub)
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000582}
583
584NonLValue NonLValue::Mul(ValueManager& ValMgr, const NonLValue& RHS) const {
Ted Kremenek687af802008-01-29 19:43:15 +0000585 NONLVALUE_DISPATCH(Mul)
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000586}
587
588NonLValue NonLValue::Div(ValueManager& ValMgr, const NonLValue& RHS) const {
Ted Kremenek687af802008-01-29 19:43:15 +0000589 NONLVALUE_DISPATCH(Div)
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000590}
591
592NonLValue NonLValue::Rem(ValueManager& ValMgr, const NonLValue& RHS) const {
Ted Kremenek687af802008-01-29 19:43:15 +0000593 NONLVALUE_DISPATCH(Rem)
594}
595
596NonLValue NonLValue::EQ(ValueManager& ValMgr, const NonLValue& RHS) const {
597 NONLVALUE_DISPATCH(EQ)
598}
599
600NonLValue NonLValue::NE(ValueManager& ValMgr, const NonLValue& RHS) const {
601 NONLVALUE_DISPATCH(NE)
602}
603
604#undef NONLVALUE_DISPATCH_CASE
605#undef NONLVALUE_DISPATCH
606
607//===----------------------------------------------------------------------===//
608// Transfer function dispatch for LValues.
609//===----------------------------------------------------------------------===//
610
611
612NonLValue LValue::EQ(ValueManager& ValMgr, const LValue& RHS) const {
613 if (getSubKind() != RHS.getSubKind())
614 return NonLValue::GetIntTruthValue(ValMgr, false);
615
616 switch (getSubKind()) {
617 default:
618 assert(false && "EQ not implemented for this LValue.");
619 return cast<NonLValue>(InvalidValue());
620
621 case LValueDeclKind: {
622 bool b = cast<LValueDecl>(*this) == cast<LValueDecl>(RHS);
623 return NonLValue::GetIntTruthValue(ValMgr, b);
624 }
625 }
626}
627
628NonLValue LValue::NE(ValueManager& ValMgr, const LValue& RHS) const {
629 if (getSubKind() != RHS.getSubKind())
Ted Kremenek03701672008-01-29 21:27:49 +0000630 return NonLValue::GetIntTruthValue(ValMgr, true);
Ted Kremenek687af802008-01-29 19:43:15 +0000631
632 switch (getSubKind()) {
633 default:
634 assert(false && "EQ not implemented for this LValue.");
635 return cast<NonLValue>(InvalidValue());
636
637 case LValueDeclKind: {
638 bool b = cast<LValueDecl>(*this) != cast<LValueDecl>(RHS);
639 return NonLValue::GetIntTruthValue(ValMgr, b);
640 }
641 }
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000642}
643
644
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000645//===----------------------------------------------------------------------===//
Ted Kremenek687af802008-01-29 19:43:15 +0000646// Utility methods for constructing Non-LValues.
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000647//===----------------------------------------------------------------------===//
648
Ted Kremenek687af802008-01-29 19:43:15 +0000649NonLValue NonLValue::GetValue(ValueManager& ValMgr, uint64_t X, QualType T,
650 SourceLocation Loc) {
651
652 return ConcreteInt(ValMgr.getValue(X, T, Loc));
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000653}
654
655NonLValue NonLValue::GetValue(ValueManager& ValMgr, IntegerLiteral* I) {
656 return ConcreteInt(ValMgr.getValue(APSInt(I->getValue(),
657 I->getType()->isUnsignedIntegerType())));
658}
659
Ted Kremenek68fd2572008-01-29 17:27:31 +0000660NonLValue NonLValue::GetSymbolValue(SymbolManager& SymMgr, ParmVarDecl* D) {
661 return SymbolicNonLValue(SymMgr.getSymbol(D));
662}
663
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000664//===----------------------------------------------------------------------===//
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000665// Pretty-Printing.
666//===----------------------------------------------------------------------===//
667
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000668void RValue::print(std::ostream& Out) const {
Ted Kremenekf13794e2008-01-24 23:19:54 +0000669 switch (getBaseKind()) {
670 case InvalidKind:
671 Out << "Invalid";
672 break;
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000673
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000674 case NonLValueKind:
675 cast<NonLValue>(this)->print(Out);
Ted Kremenekf13794e2008-01-24 23:19:54 +0000676 break;
Ted Kremenek68fd2572008-01-29 17:27:31 +0000677
Ted Kremenekf13794e2008-01-24 23:19:54 +0000678 case LValueKind:
679 assert (false && "FIXME: LValue printing not implemented.");
680 break;
681
Ted Kremenek403c1812008-01-28 22:51:57 +0000682 case UninitializedKind:
683 Out << "Uninitialized";
684 break;
685
Ted Kremenekf13794e2008-01-24 23:19:54 +0000686 default:
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000687 assert (false && "Invalid RValue.");
Ted Kremenekf13794e2008-01-24 23:19:54 +0000688 }
689}
690
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000691void NonLValue::print(std::ostream& Out) const {
Ted Kremenekf13794e2008-01-24 23:19:54 +0000692 switch (getSubKind()) {
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000693 case ConcreteIntKind:
694 Out << cast<ConcreteInt>(this)->getValue().toString();
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000695 break;
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000696
Ted Kremenek68fd2572008-01-29 17:27:31 +0000697 case SymbolicNonLValueKind:
Ted Kremenek6753fe32008-01-30 18:54:06 +0000698 Out << '$' << cast<SymbolicNonLValue>(this)->getSymbolID();
Ted Kremenek68fd2572008-01-29 17:27:31 +0000699 break;
700
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000701 default:
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000702 assert (false && "Pretty-printed not implemented for this NonLValue.");
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000703 break;
704 }
705}
706
707//===----------------------------------------------------------------------===//
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000708// ValueMapTy - A ImmutableMap type Stmt*/Decl*/Symbols to RValues.
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000709//===----------------------------------------------------------------------===//
710
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000711typedef llvm::ImmutableMap<ValueKey,RValue> ValueMapTy;
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000712
713namespace clang {
714 template<>
715 struct VISIBILITY_HIDDEN GRTrait<ValueMapTy> {
716 static inline void* toPtr(ValueMapTy M) {
717 return reinterpret_cast<void*>(M.getRoot());
718 }
719 static inline ValueMapTy toState(void* P) {
720 return ValueMapTy(static_cast<ValueMapTy::TreeTy*>(P));
721 }
722 };
Ted Kremenekd27f8162008-01-15 23:55:06 +0000723}
724
725//===----------------------------------------------------------------------===//
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000726// The Checker.
Ted Kremenekd27f8162008-01-15 23:55:06 +0000727//===----------------------------------------------------------------------===//
728
729namespace {
Ted Kremenekd27f8162008-01-15 23:55:06 +0000730
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000731class VISIBILITY_HIDDEN GRConstants {
Ted Kremenekd27f8162008-01-15 23:55:06 +0000732
733public:
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000734 typedef ValueMapTy StateTy;
Ted Kremenek7d7fe6d2008-01-29 22:56:11 +0000735 typedef GRStmtNodeBuilder<GRConstants> StmtNodeBuilder;
736 typedef GRBranchNodeBuilder<GRConstants> BranchNodeBuilder;
Ted Kremenekcb48b9c2008-01-29 00:33:40 +0000737 typedef ExplodedGraph<GRConstants> GraphTy;
738 typedef GraphTy::NodeTy NodeTy;
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000739
740 class NodeSet {
741 typedef llvm::SmallVector<NodeTy*,3> ImplTy;
742 ImplTy Impl;
743 public:
744
745 NodeSet() {}
746 NodeSet(NodeTy* N) { assert (N && !N->isInfeasible()); Impl.push_back(N); }
747
748 void Add(NodeTy* N) { if (N && !N->isInfeasible()) Impl.push_back(N); }
749
750 typedef ImplTy::iterator iterator;
751 typedef ImplTy::const_iterator const_iterator;
752
753 unsigned size() const { return Impl.size(); }
Ted Kremenek9de04c42008-01-24 20:55:43 +0000754 bool empty() const { return Impl.empty(); }
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000755
756 iterator begin() { return Impl.begin(); }
757 iterator end() { return Impl.end(); }
758
759 const_iterator begin() const { return Impl.begin(); }
760 const_iterator end() const { return Impl.end(); }
761 };
Ted Kremenekd27f8162008-01-15 23:55:06 +0000762
763protected:
Ted Kremenekcb48b9c2008-01-29 00:33:40 +0000764 /// G - the simulation graph.
765 GraphTy& G;
766
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000767 /// Liveness - live-variables information the ValueDecl* and block-level
768 /// Expr* in the CFG. Used to prune out dead state.
Ted Kremenekbffaa832008-01-29 05:13:23 +0000769 LiveVariables Liveness;
Ted Kremenekd27f8162008-01-15 23:55:06 +0000770
Ted Kremenekf4b7a692008-01-29 22:11:49 +0000771 /// Builder - The current GRStmtNodeBuilder which is used when building the nodes
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000772 /// for a given statement.
Ted Kremenek7d7fe6d2008-01-29 22:56:11 +0000773 StmtNodeBuilder* Builder;
774
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000775 /// StateMgr - Object that manages the data for all created states.
776 ValueMapTy::Factory StateMgr;
Ted Kremenekd27f8162008-01-15 23:55:06 +0000777
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000778 /// ValueMgr - Object that manages the data for all created RValues.
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000779 ValueManager ValMgr;
780
Ted Kremenek68fd2572008-01-29 17:27:31 +0000781 /// SymMgr - Object that manages the symbol information.
782 SymbolManager SymMgr;
783
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000784 /// StmtEntryNode - The immediate predecessor node.
785 NodeTy* StmtEntryNode;
786
787 /// CurrentStmt - The current block-level statement.
788 Stmt* CurrentStmt;
789
790 bool StateCleaned;
Ted Kremenekd27f8162008-01-15 23:55:06 +0000791
Ted Kremenekcb48b9c2008-01-29 00:33:40 +0000792 ASTContext& getContext() const { return G.getContext(); }
Ted Kremenek7b8009a2008-01-24 02:28:56 +0000793
Ted Kremenekd27f8162008-01-15 23:55:06 +0000794public:
Ted Kremenekbffaa832008-01-29 05:13:23 +0000795 GRConstants(GraphTy& g) : G(g), Liveness(G.getCFG(), G.getFunctionDecl()),
796 Builder(NULL), ValMgr(G.getContext()), StmtEntryNode(NULL),
797 CurrentStmt(NULL) {
Ted Kremenekd27f8162008-01-15 23:55:06 +0000798
Ted Kremenekcb48b9c2008-01-29 00:33:40 +0000799 // Compute liveness information.
Ted Kremenekbffaa832008-01-29 05:13:23 +0000800 Liveness.runOnCFG(G.getCFG());
801 Liveness.runOnAllBlocks(G.getCFG(), NULL, true);
Ted Kremenekd27f8162008-01-15 23:55:06 +0000802 }
Ted Kremenekcb48b9c2008-01-29 00:33:40 +0000803
804 /// getCFG - Returns the CFG associated with this analysis.
805 CFG& getCFG() { return G.getCFG(); }
Ted Kremenekd27f8162008-01-15 23:55:06 +0000806
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000807 /// getInitialState - Return the initial state used for the root vertex
808 /// in the ExplodedGraph.
Ted Kremenekd27f8162008-01-15 23:55:06 +0000809 StateTy getInitialState() {
Ted Kremenekcb48b9c2008-01-29 00:33:40 +0000810 StateTy St = StateMgr.GetEmptyMap();
Ted Kremenekff6e3c52008-01-29 00:43:03 +0000811
812 // Iterate the parameters.
813 FunctionDecl& F = G.getFunctionDecl();
814
815 for (FunctionDecl::param_iterator I=F.param_begin(), E=F.param_end();
816 I!=E; ++I) {
817
818 // For now we only support symbolic values for non-pointer types.
819 if ((*I)->getType()->isPointerType() ||
820 (*I)->getType()->isReferenceType())
821 continue;
822
823 // FIXME: Set these values to a symbol, not Uninitialized.
Ted Kremenek68fd2572008-01-29 17:27:31 +0000824 St = SetValue(St, LValueDecl(*I), NonLValue::GetSymbolValue(SymMgr, *I));
Ted Kremenekff6e3c52008-01-29 00:43:03 +0000825 }
826
Ted Kremenekcb48b9c2008-01-29 00:33:40 +0000827 return St;
Ted Kremenekd27f8162008-01-15 23:55:06 +0000828 }
Ted Kremenekd27f8162008-01-15 23:55:06 +0000829
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000830 /// ProcessStmt - Called by GREngine. Used to generate new successor
831 /// nodes by processing the 'effects' of a block-level statement.
Ted Kremenek7d7fe6d2008-01-29 22:56:11 +0000832 void ProcessStmt(Stmt* S, StmtNodeBuilder& builder);
833
834 /// ProcessBranch - Called by GREngine. Used to generate successor
835 /// nodes by processing the 'effects' of a branch condition.
Ted Kremenek71c29bd2008-01-29 23:32:35 +0000836 void ProcessBranch(Stmt* Condition, Stmt* Term, BranchNodeBuilder& builder);
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000837
838 /// RemoveDeadBindings - Return a new state that is the same as 'M' except
839 /// that all subexpression mappings are removed and that any
840 /// block-level expressions that are not live at 'S' also have their
841 /// mappings removed.
842 StateTy RemoveDeadBindings(Stmt* S, StateTy M);
843
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000844 StateTy SetValue(StateTy St, Stmt* S, const RValue& V);
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000845
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000846 StateTy SetValue(StateTy St, const Stmt* S, const RValue& V) {
Ted Kremenek9de04c42008-01-24 20:55:43 +0000847 return SetValue(St, const_cast<Stmt*>(S), V);
848 }
849
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000850 StateTy SetValue(StateTy St, const LValue& LV, const RValue& V);
Ted Kremenek1ccd31c2008-01-16 19:42:59 +0000851
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000852 RValue GetValue(const StateTy& St, Stmt* S);
853 inline RValue GetValue(const StateTy& St, const Stmt* S) {
Ted Kremenek9de04c42008-01-24 20:55:43 +0000854 return GetValue(St, const_cast<Stmt*>(S));
855 }
856
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000857 RValue GetValue(const StateTy& St, const LValue& LV);
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000858 LValue GetLValue(const StateTy& St, Stmt* S);
Ted Kremenekd27f8162008-01-15 23:55:06 +0000859
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000860 void Nodify(NodeSet& Dst, Stmt* S, NodeTy* Pred, StateTy St);
Ted Kremenekd27f8162008-01-15 23:55:06 +0000861
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000862 /// Visit - Transfer function logic for all statements. Dispatches to
863 /// other functions that handle specific kinds of statements.
864 void Visit(Stmt* S, NodeTy* Pred, NodeSet& Dst);
Ted Kremenek874d63f2008-01-24 02:02:54 +0000865
866 /// VisitCast - Transfer function logic for all casts (implicit and explicit).
867 void VisitCast(Expr* CastE, Expr* E, NodeTy* Pred, NodeSet& Dst);
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000868
Ted Kremenek7b8009a2008-01-24 02:28:56 +0000869 /// VisitUnaryOperator - Transfer function logic for unary operators.
870 void VisitUnaryOperator(UnaryOperator* B, NodeTy* Pred, NodeSet& Dst);
871
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000872 /// VisitBinaryOperator - Transfer function logic for binary operators.
Ted Kremenek9de04c42008-01-24 20:55:43 +0000873 void VisitBinaryOperator(BinaryOperator* B, NodeTy* Pred, NodeSet& Dst);
874
875 /// VisitDeclStmt - Transfer function logic for DeclStmts.
876 void VisitDeclStmt(DeclStmt* DS, NodeTy* Pred, NodeSet& Dst);
Ted Kremenekd27f8162008-01-15 23:55:06 +0000877};
878} // end anonymous namespace
879
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000880
Ted Kremenek71c29bd2008-01-29 23:32:35 +0000881void GRConstants::ProcessBranch(Stmt* Condition, Stmt* Term,
882 BranchNodeBuilder& builder) {
883
884
885}
886
Ted Kremenek7d7fe6d2008-01-29 22:56:11 +0000887void GRConstants::ProcessStmt(Stmt* S, StmtNodeBuilder& builder) {
Ted Kremenekd27f8162008-01-15 23:55:06 +0000888 Builder = &builder;
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000889
890 StmtEntryNode = builder.getLastNode();
891 CurrentStmt = S;
892 NodeSet Dst;
893 StateCleaned = false;
894
895 Visit(S, StmtEntryNode, Dst);
896
897 // If no nodes were generated, generate a new node that has all the
898 // dead mappings removed.
899 if (Dst.size() == 1 && *Dst.begin() == StmtEntryNode) {
900 StateTy St = RemoveDeadBindings(S, StmtEntryNode->getState());
901 builder.generateNode(S, St, StmtEntryNode);
902 }
Ted Kremenekf84469b2008-01-18 00:41:32 +0000903
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000904 CurrentStmt = NULL;
905 StmtEntryNode = NULL;
906 Builder = NULL;
Ted Kremenekd27f8162008-01-15 23:55:06 +0000907}
908
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000909
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000910RValue GRConstants::GetValue(const StateTy& St, const LValue& LV) {
Ted Kremenekf13794e2008-01-24 23:19:54 +0000911 switch (LV.getSubKind()) {
912 case LValueDeclKind: {
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000913 StateTy::TreeTy* T = St.SlimFind(cast<LValueDecl>(LV).getDecl());
914 return T ? T->getValue().second : InvalidValue();
915 }
916 default:
917 assert (false && "Invalid LValue.");
Ted Kremenekca3e8572008-01-16 22:28:08 +0000918 break;
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000919 }
920
921 return InvalidValue();
922}
923
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000924RValue GRConstants::GetValue(const StateTy& St, Stmt* S) {
Ted Kremenek671c9e82008-01-24 00:50:08 +0000925 for (;;) {
926 switch (S->getStmtClass()) {
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000927
928 // ParenExprs are no-ops.
929
Ted Kremenek671c9e82008-01-24 00:50:08 +0000930 case Stmt::ParenExprClass:
931 S = cast<ParenExpr>(S)->getSubExpr();
932 continue;
933
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000934 // DeclRefExprs can either evaluate to an LValue or a Non-LValue
935 // (assuming an implicit "load") depending on the context. In this
936 // context we assume that we are retrieving the value contained
937 // within the referenced variables.
938
Ted Kremenek671c9e82008-01-24 00:50:08 +0000939 case Stmt::DeclRefExprClass:
940 return GetValue(St, LValueDecl(cast<DeclRefExpr>(S)->getDecl()));
Ted Kremenekca3e8572008-01-16 22:28:08 +0000941
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000942 // Integer literals evaluate to an RValue. Simply retrieve the
943 // RValue for the literal.
944
Ted Kremenek671c9e82008-01-24 00:50:08 +0000945 case Stmt::IntegerLiteralClass:
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000946 return NonLValue::GetValue(ValMgr, cast<IntegerLiteral>(S));
947
948 // Casts where the source and target type are the same
949 // are no-ops. We blast through these to get the descendant
950 // subexpression that has a value.
951
Ted Kremenek874d63f2008-01-24 02:02:54 +0000952 case Stmt::ImplicitCastExprClass: {
953 ImplicitCastExpr* C = cast<ImplicitCastExpr>(S);
954 if (C->getType() == C->getSubExpr()->getType()) {
955 S = C->getSubExpr();
956 continue;
957 }
958 break;
959 }
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000960
Ted Kremenek874d63f2008-01-24 02:02:54 +0000961 case Stmt::CastExprClass: {
962 CastExpr* C = cast<CastExpr>(S);
963 if (C->getType() == C->getSubExpr()->getType()) {
964 S = C->getSubExpr();
965 continue;
966 }
967 break;
968 }
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000969
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000970 // Handle all other Stmt* using a lookup.
971
Ted Kremenek671c9e82008-01-24 00:50:08 +0000972 default:
973 break;
974 };
975
976 break;
977 }
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000978
Ted Kremenek5c1b9962008-01-24 19:43:37 +0000979 StateTy::TreeTy* T = St.SlimFind(S);
Ted Kremenek874d63f2008-01-24 02:02:54 +0000980
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000981 return T ? T->getValue().second : InvalidValue();
982}
983
984LValue GRConstants::GetLValue(const StateTy& St, Stmt* S) {
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000985 while (ParenExpr* P = dyn_cast<ParenExpr>(S))
986 S = P->getSubExpr();
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000987
988 if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(S))
989 return LValueDecl(DR->getDecl());
990
991 return cast<LValue>(GetValue(St, S));
992}
993
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000994
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000995GRConstants::StateTy GRConstants::SetValue(StateTy St, Stmt* S,
Ted Kremenekbd03f1d2008-01-28 22:09:13 +0000996 const RValue& V) {
Ted Kremenekcc1c3652008-01-25 23:43:12 +0000997 assert (S);
Ted Kremenekab2b8c52008-01-23 19:59:44 +0000998
999 if (!StateCleaned) {
1000 St = RemoveDeadBindings(CurrentStmt, St);
1001 StateCleaned = true;
1002 }
1003
Ted Kremenek9ff731d2008-01-24 22:27:20 +00001004 bool isBlkExpr = false;
1005
1006 if (S == CurrentStmt) {
1007 isBlkExpr = getCFG().isBlkExpr(S);
1008
1009 if (!isBlkExpr)
1010 return St;
1011 }
Ted Kremenekdaadf452008-01-24 19:28:01 +00001012
Ted Kremenekab2b8c52008-01-23 19:59:44 +00001013 return V.isValid() ? StateMgr.Add(St, ValueKey(S,isBlkExpr), V)
1014 : St;
1015}
1016
1017GRConstants::StateTy GRConstants::SetValue(StateTy St, const LValue& LV,
Ted Kremenekbd03f1d2008-01-28 22:09:13 +00001018 const RValue& V) {
Ted Kremenekab2b8c52008-01-23 19:59:44 +00001019 if (!LV.isValid())
1020 return St;
1021
1022 if (!StateCleaned) {
1023 St = RemoveDeadBindings(CurrentStmt, St);
1024 StateCleaned = true;
Ted Kremenekca3e8572008-01-16 22:28:08 +00001025 }
Ted Kremenek0525a4f2008-01-16 19:47:19 +00001026
Ted Kremenekf13794e2008-01-24 23:19:54 +00001027 switch (LV.getSubKind()) {
1028 case LValueDeclKind:
Ted Kremenekab2b8c52008-01-23 19:59:44 +00001029 return V.isValid() ? StateMgr.Add(St, cast<LValueDecl>(LV).getDecl(), V)
1030 : StateMgr.Remove(St, cast<LValueDecl>(LV).getDecl());
1031
1032 default:
1033 assert ("SetValue for given LValue type not yet implemented.");
1034 return St;
1035 }
Ted Kremenekd27f8162008-01-15 23:55:06 +00001036}
1037
Ted Kremenekab2b8c52008-01-23 19:59:44 +00001038GRConstants::StateTy GRConstants::RemoveDeadBindings(Stmt* Loc, StateTy M) {
Ted Kremenekf84469b2008-01-18 00:41:32 +00001039 // Note: in the code below, we can assign a new map to M since the
1040 // iterators are iterating over the tree of the *original* map.
Ted Kremenekf84469b2008-01-18 00:41:32 +00001041 StateTy::iterator I = M.begin(), E = M.end();
1042
Ted Kremenekf84469b2008-01-18 00:41:32 +00001043
Ted Kremenek65cac132008-01-29 05:25:31 +00001044 for (; I!=E && !I.getKey().isSymbol(); ++I) {
1045 // Remove old bindings for subexpressions and "dead"
1046 // block-level expressions.
1047 if (I.getKey().isSubExpr() ||
1048 I.getKey().isBlkExpr() && !Liveness.isLive(Loc,cast<Stmt>(I.getKey()))){
1049 M = StateMgr.Remove(M, I.getKey());
1050 }
1051 else if (I.getKey().isDecl()) { // Remove bindings for "dead" decls.
1052 if (VarDecl* V = dyn_cast<VarDecl>(cast<ValueDecl>(I.getKey())))
1053 if (!Liveness.isLive(Loc, V))
1054 M = StateMgr.Remove(M, I.getKey());
1055 }
1056 }
Ted Kremenek565256e2008-01-24 22:44:24 +00001057
Ted Kremeneke00fe3f2008-01-17 00:52:48 +00001058 return M;
Ted Kremeneke00fe3f2008-01-17 00:52:48 +00001059}
1060
Ted Kremenekab2b8c52008-01-23 19:59:44 +00001061void GRConstants::Nodify(NodeSet& Dst, Stmt* S, GRConstants::NodeTy* Pred,
1062 GRConstants::StateTy St) {
1063
1064 // If the state hasn't changed, don't generate a new node.
1065 if (St == Pred->getState())
1066 return;
Ted Kremenekcb448ca2008-01-16 00:53:15 +00001067
Ted Kremenekab2b8c52008-01-23 19:59:44 +00001068 Dst.Add(Builder->generateNode(S, St, Pred));
Ted Kremenekcb448ca2008-01-16 00:53:15 +00001069}
Ted Kremenekd27f8162008-01-15 23:55:06 +00001070
Ted Kremenek874d63f2008-01-24 02:02:54 +00001071void GRConstants::VisitCast(Expr* CastE, Expr* E, GRConstants::NodeTy* Pred,
1072 GRConstants::NodeSet& Dst) {
1073
1074 QualType T = CastE->getType();
1075
1076 // Check for redundant casts.
1077 if (E->getType() == T) {
1078 Dst.Add(Pred);
1079 return;
1080 }
1081
1082 NodeSet S1;
1083 Visit(E, Pred, S1);
1084
1085 for (NodeSet::iterator I1=S1.begin(), E1=S1.end(); I1 != E1; ++I1) {
1086 NodeTy* N = *I1;
1087 StateTy St = N->getState();
Ted Kremenekbd03f1d2008-01-28 22:09:13 +00001088 const RValue& V = GetValue(St, E);
1089 Nodify(Dst, CastE, N, SetValue(St, CastE, V.Cast(ValMgr, CastE)));
Ted Kremenek874d63f2008-01-24 02:02:54 +00001090 }
Ted Kremenek9de04c42008-01-24 20:55:43 +00001091}
1092
1093void GRConstants::VisitDeclStmt(DeclStmt* DS, GRConstants::NodeTy* Pred,
1094 GRConstants::NodeSet& Dst) {
1095
1096 StateTy St = Pred->getState();
1097
1098 for (const ScopedDecl* D = DS->getDecl(); D; D = D->getNextDeclarator())
Ted Kremenek403c1812008-01-28 22:51:57 +00001099 if (const VarDecl* VD = dyn_cast<VarDecl>(D)) {
1100 const Expr* E = VD->getInit();
1101 St = SetValue(St, LValueDecl(VD),
1102 E ? GetValue(St, E) : UninitializedValue());
1103 }
Ted Kremenek9de04c42008-01-24 20:55:43 +00001104
1105 Nodify(Dst, DS, Pred, St);
1106
1107 if (Dst.empty())
1108 Dst.Add(Pred);
1109}
Ted Kremenek874d63f2008-01-24 02:02:54 +00001110
Ted Kremenek7b8009a2008-01-24 02:28:56 +00001111void GRConstants::VisitUnaryOperator(UnaryOperator* U,
1112 GRConstants::NodeTy* Pred,
1113 GRConstants::NodeSet& Dst) {
1114 NodeSet S1;
1115 Visit(U->getSubExpr(), Pred, S1);
1116
1117 for (NodeSet::iterator I1=S1.begin(), E1=S1.end(); I1 != E1; ++I1) {
1118 NodeTy* N1 = *I1;
1119 StateTy St = N1->getState();
1120
1121 switch (U->getOpcode()) {
1122 case UnaryOperator::PostInc: {
1123 const LValue& L1 = GetLValue(St, U->getSubExpr());
Ted Kremenekbd03f1d2008-01-28 22:09:13 +00001124 NonLValue R1 = cast<NonLValue>(GetValue(St, L1));
Ted Kremenek687af802008-01-29 19:43:15 +00001125 NonLValue R2 = NonLValue::GetValue(ValMgr, 1U, U->getType(),
1126 U->getLocStart());
Ted Kremeneke0cf9c82008-01-24 19:00:57 +00001127
Ted Kremenekbd03f1d2008-01-28 22:09:13 +00001128 NonLValue Result = R1.Add(ValMgr, R2);
Ted Kremenek7b8009a2008-01-24 02:28:56 +00001129 Nodify(Dst, U, N1, SetValue(SetValue(St, U, R1), L1, Result));
1130 break;
1131 }
1132
1133 case UnaryOperator::PostDec: {
1134 const LValue& L1 = GetLValue(St, U->getSubExpr());
Ted Kremenekbd03f1d2008-01-28 22:09:13 +00001135 NonLValue R1 = cast<NonLValue>(GetValue(St, L1));
Ted Kremenek687af802008-01-29 19:43:15 +00001136 NonLValue R2 = NonLValue::GetValue(ValMgr, 1U, U->getType(),
1137 U->getLocStart());
Ted Kremenek7b8009a2008-01-24 02:28:56 +00001138
Ted Kremenekbd03f1d2008-01-28 22:09:13 +00001139 NonLValue Result = R1.Sub(ValMgr, R2);
Ted Kremenek7b8009a2008-01-24 02:28:56 +00001140 Nodify(Dst, U, N1, SetValue(SetValue(St, U, R1), L1, Result));
1141 break;
1142 }
1143
1144 case UnaryOperator::PreInc: {
1145 const LValue& L1 = GetLValue(St, U->getSubExpr());
Ted Kremenekbd03f1d2008-01-28 22:09:13 +00001146 NonLValue R1 = cast<NonLValue>(GetValue(St, L1));
Ted Kremenek687af802008-01-29 19:43:15 +00001147 NonLValue R2 = NonLValue::GetValue(ValMgr, 1U, U->getType(),
1148 U->getLocStart());
Ted Kremenek7b8009a2008-01-24 02:28:56 +00001149
Ted Kremenekbd03f1d2008-01-28 22:09:13 +00001150 NonLValue Result = R1.Add(ValMgr, R2);
Ted Kremenek7b8009a2008-01-24 02:28:56 +00001151 Nodify(Dst, U, N1, SetValue(SetValue(St, U, Result), L1, Result));
1152 break;
1153 }
1154
1155 case UnaryOperator::PreDec: {
1156 const LValue& L1 = GetLValue(St, U->getSubExpr());
Ted Kremenekbd03f1d2008-01-28 22:09:13 +00001157 NonLValue R1 = cast<NonLValue>(GetValue(St, L1));
Ted Kremenek687af802008-01-29 19:43:15 +00001158 NonLValue R2 = NonLValue::GetValue(ValMgr, 1U, U->getType(),
1159 U->getLocStart());
Ted Kremenek7b8009a2008-01-24 02:28:56 +00001160
Ted Kremenekbd03f1d2008-01-28 22:09:13 +00001161 NonLValue Result = R1.Sub(ValMgr, R2);
Ted Kremenek7b8009a2008-01-24 02:28:56 +00001162 Nodify(Dst, U, N1, SetValue(SetValue(St, U, Result), L1, Result));
1163 break;
1164 }
1165
Ted Kremenekdacbb4f2008-01-24 08:20:02 +00001166 case UnaryOperator::Minus: {
Ted Kremenekbd03f1d2008-01-28 22:09:13 +00001167 const NonLValue& R1 = cast<NonLValue>(GetValue(St, U->getSubExpr()));
1168 Nodify(Dst, U, N1, SetValue(St, U, R1.UnaryMinus(ValMgr, U)));
Ted Kremenekdacbb4f2008-01-24 08:20:02 +00001169 break;
1170 }
1171
Ted Kremenek7b8009a2008-01-24 02:28:56 +00001172 default: ;
1173 assert (false && "Not implemented.");
1174 }
1175 }
1176}
1177
Ted Kremenekab2b8c52008-01-23 19:59:44 +00001178void GRConstants::VisitBinaryOperator(BinaryOperator* B,
1179 GRConstants::NodeTy* Pred,
1180 GRConstants::NodeSet& Dst) {
1181 NodeSet S1;
1182 Visit(B->getLHS(), Pred, S1);
Ted Kremenekcb448ca2008-01-16 00:53:15 +00001183
Ted Kremenekab2b8c52008-01-23 19:59:44 +00001184 for (NodeSet::iterator I1=S1.begin(), E1=S1.end(); I1 != E1; ++I1) {
1185 NodeTy* N1 = *I1;
Ted Kremeneke00fe3f2008-01-17 00:52:48 +00001186
Ted Kremenekab2b8c52008-01-23 19:59:44 +00001187 // When getting the value for the LHS, check if we are in an assignment.
1188 // In such cases, we want to (initially) treat the LHS as an LValue,
1189 // so we use GetLValue instead of GetValue so that DeclRefExpr's are
Ted Kremenekbd03f1d2008-01-28 22:09:13 +00001190 // evaluated to LValueDecl's instead of to an NonLValue.
1191 const RValue& V1 =
Ted Kremenekab2b8c52008-01-23 19:59:44 +00001192 B->isAssignmentOp() ? GetLValue(N1->getState(), B->getLHS())
1193 : GetValue(N1->getState(), B->getLHS());
Ted Kremenekcb448ca2008-01-16 00:53:15 +00001194
Ted Kremenekab2b8c52008-01-23 19:59:44 +00001195 NodeSet S2;
1196 Visit(B->getRHS(), N1, S2);
1197
1198 for (NodeSet::iterator I2=S2.begin(), E2=S2.end(); I2 != E2; ++I2) {
1199 NodeTy* N2 = *I2;
1200 StateTy St = N2->getState();
Ted Kremenekbd03f1d2008-01-28 22:09:13 +00001201 const RValue& V2 = GetValue(St, B->getRHS());
Ted Kremenekab2b8c52008-01-23 19:59:44 +00001202
1203 switch (B->getOpcode()) {
Ted Kremenek687af802008-01-29 19:43:15 +00001204 default:
1205 Dst.Add(N2);
1206 break;
1207
1208 // Arithmetic opreators.
1209
Ted Kremenekab2b8c52008-01-23 19:59:44 +00001210 case BinaryOperator::Add: {
Ted Kremenekbd03f1d2008-01-28 22:09:13 +00001211 const NonLValue& R1 = cast<NonLValue>(V1);
1212 const NonLValue& R2 = cast<NonLValue>(V2);
Ted Kremenekab2b8c52008-01-23 19:59:44 +00001213
Ted Kremenekbd03f1d2008-01-28 22:09:13 +00001214 Nodify(Dst, B, N2, SetValue(St, B, R1.Add(ValMgr, R2)));
Ted Kremenekab2b8c52008-01-23 19:59:44 +00001215 break;
1216 }
1217
1218 case BinaryOperator::Sub: {
Ted Kremenekbd03f1d2008-01-28 22:09:13 +00001219 const NonLValue& R1 = cast<NonLValue>(V1);
1220 const NonLValue& R2 = cast<NonLValue>(V2);
1221 Nodify(Dst, B, N2, SetValue(St, B, R1.Sub(ValMgr, R2)));
Ted Kremenekab2b8c52008-01-23 19:59:44 +00001222 break;
1223 }
1224
Ted Kremenek2eafd0e2008-01-23 23:42:27 +00001225 case BinaryOperator::Mul: {
Ted Kremenekbd03f1d2008-01-28 22:09:13 +00001226 const NonLValue& R1 = cast<NonLValue>(V1);
1227 const NonLValue& R2 = cast<NonLValue>(V2);
1228 Nodify(Dst, B, N2, SetValue(St, B, R1.Mul(ValMgr, R2)));
Ted Kremenek2eafd0e2008-01-23 23:42:27 +00001229 break;
1230 }
1231
Ted Kremenek5ee4ff82008-01-25 22:55:56 +00001232 case BinaryOperator::Div: {
Ted Kremenekbd03f1d2008-01-28 22:09:13 +00001233 const NonLValue& R1 = cast<NonLValue>(V1);
1234 const NonLValue& R2 = cast<NonLValue>(V2);
1235 Nodify(Dst, B, N2, SetValue(St, B, R1.Div(ValMgr, R2)));
Ted Kremenek5ee4ff82008-01-25 22:55:56 +00001236 break;
1237 }
1238
Ted Kremenekcce207d2008-01-28 22:26:15 +00001239 case BinaryOperator::Rem: {
1240 const NonLValue& R1 = cast<NonLValue>(V1);
1241 const NonLValue& R2 = cast<NonLValue>(V2);
1242 Nodify(Dst, B, N2, SetValue(St, B, R1.Rem(ValMgr, R2)));
1243 break;
1244 }
1245
Ted Kremenek687af802008-01-29 19:43:15 +00001246 // Assignment operators.
1247
Ted Kremenekab2b8c52008-01-23 19:59:44 +00001248 case BinaryOperator::Assign: {
1249 const LValue& L1 = cast<LValue>(V1);
Ted Kremenekbd03f1d2008-01-28 22:09:13 +00001250 const NonLValue& R2 = cast<NonLValue>(V2);
Ted Kremenekab2b8c52008-01-23 19:59:44 +00001251 Nodify(Dst, B, N2, SetValue(SetValue(St, B, R2), L1, R2));
1252 break;
1253 }
Ted Kremenekb4ae33f2008-01-23 23:38:00 +00001254
1255 case BinaryOperator::AddAssign: {
1256 const LValue& L1 = cast<LValue>(V1);
Ted Kremenekbd03f1d2008-01-28 22:09:13 +00001257 NonLValue R1 = cast<NonLValue>(GetValue(N1->getState(), L1));
1258 NonLValue Result = R1.Add(ValMgr, cast<NonLValue>(V2));
Ted Kremenekb4ae33f2008-01-23 23:38:00 +00001259 Nodify(Dst, B, N2, SetValue(SetValue(St, B, Result), L1, Result));
1260 break;
1261 }
1262
1263 case BinaryOperator::SubAssign: {
1264 const LValue& L1 = cast<LValue>(V1);
Ted Kremenekbd03f1d2008-01-28 22:09:13 +00001265 NonLValue R1 = cast<NonLValue>(GetValue(N1->getState(), L1));
1266 NonLValue Result = R1.Sub(ValMgr, cast<NonLValue>(V2));
Ted Kremenekb4ae33f2008-01-23 23:38:00 +00001267 Nodify(Dst, B, N2, SetValue(SetValue(St, B, Result), L1, Result));
1268 break;
1269 }
Ted Kremenek2eafd0e2008-01-23 23:42:27 +00001270
1271 case BinaryOperator::MulAssign: {
1272 const LValue& L1 = cast<LValue>(V1);
Ted Kremenekbd03f1d2008-01-28 22:09:13 +00001273 NonLValue R1 = cast<NonLValue>(GetValue(N1->getState(), L1));
1274 NonLValue Result = R1.Mul(ValMgr, cast<NonLValue>(V2));
Ted Kremenek2eafd0e2008-01-23 23:42:27 +00001275 Nodify(Dst, B, N2, SetValue(SetValue(St, B, Result), L1, Result));
1276 break;
1277 }
Ted Kremenek5c1e2622008-01-25 23:45:34 +00001278
1279 case BinaryOperator::DivAssign: {
1280 const LValue& L1 = cast<LValue>(V1);
Ted Kremenekbd03f1d2008-01-28 22:09:13 +00001281 NonLValue R1 = cast<NonLValue>(GetValue(N1->getState(), L1));
1282 NonLValue Result = R1.Div(ValMgr, cast<NonLValue>(V2));
Ted Kremenek5c1e2622008-01-25 23:45:34 +00001283 Nodify(Dst, B, N2, SetValue(SetValue(St, B, Result), L1, Result));
1284 break;
1285 }
Ted Kremenek10099a62008-01-28 22:28:54 +00001286
1287 case BinaryOperator::RemAssign: {
1288 const LValue& L1 = cast<LValue>(V1);
1289 NonLValue R1 = cast<NonLValue>(GetValue(N1->getState(), L1));
1290 NonLValue Result = R1.Rem(ValMgr, cast<NonLValue>(V2));
1291 Nodify(Dst, B, N2, SetValue(SetValue(St, B, Result), L1, Result));
1292 break;
1293 }
Ted Kremenek687af802008-01-29 19:43:15 +00001294
1295 // Equality operators.
Ted Kremenekab2b8c52008-01-23 19:59:44 +00001296
Ted Kremenek687af802008-01-29 19:43:15 +00001297 case BinaryOperator::EQ:
1298 // FIXME: should we allow XX.EQ() to return a set of values,
1299 // allowing state bifurcation? In such cases, they will also
1300 // modify the state (meaning that a new state will be returned
1301 // as well).
1302 assert (B->getType() == getContext().IntTy);
1303
1304 if (isa<LValue>(V1)) {
1305 const LValue& L1 = cast<LValue>(V1);
1306 const LValue& L2 = cast<LValue>(V2);
1307 St = SetValue(St, B, L1.EQ(ValMgr, L2));
1308 }
1309 else {
1310 const NonLValue& R1 = cast<NonLValue>(V1);
1311 const NonLValue& R2 = cast<NonLValue>(V2);
1312 St = SetValue(St, B, R1.EQ(ValMgr, R2));
1313 }
1314
1315 Nodify(Dst, B, N2, St);
Ted Kremenekab2b8c52008-01-23 19:59:44 +00001316 break;
1317 }
Ted Kremenekcb448ca2008-01-16 00:53:15 +00001318 }
Ted Kremenekd27f8162008-01-15 23:55:06 +00001319 }
Ted Kremenekd27f8162008-01-15 23:55:06 +00001320}
Ted Kremenekee985462008-01-16 18:18:48 +00001321
Ted Kremenek1ccd31c2008-01-16 19:42:59 +00001322
Ted Kremenekab2b8c52008-01-23 19:59:44 +00001323void GRConstants::Visit(Stmt* S, GRConstants::NodeTy* Pred,
1324 GRConstants::NodeSet& Dst) {
1325
1326 // FIXME: add metadata to the CFG so that we can disable
1327 // this check when we KNOW that there is no block-level subexpression.
1328 // The motivation is that this check requires a hashtable lookup.
1329
1330 if (S != CurrentStmt && getCFG().isBlkExpr(S)) {
1331 Dst.Add(Pred);
1332 return;
1333 }
1334
1335 switch (S->getStmtClass()) {
1336 case Stmt::BinaryOperatorClass:
Ted Kremenekb4ae33f2008-01-23 23:38:00 +00001337 case Stmt::CompoundAssignOperatorClass:
Ted Kremenekab2b8c52008-01-23 19:59:44 +00001338 VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Dst);
1339 break;
1340
Ted Kremenek7b8009a2008-01-24 02:28:56 +00001341 case Stmt::UnaryOperatorClass:
1342 VisitUnaryOperator(cast<UnaryOperator>(S), Pred, Dst);
1343 break;
1344
Ted Kremenekab2b8c52008-01-23 19:59:44 +00001345 case Stmt::ParenExprClass:
1346 Visit(cast<ParenExpr>(S)->getSubExpr(), Pred, Dst);
1347 break;
1348
Ted Kremenek874d63f2008-01-24 02:02:54 +00001349 case Stmt::ImplicitCastExprClass: {
1350 ImplicitCastExpr* C = cast<ImplicitCastExpr>(S);
1351 VisitCast(C, C->getSubExpr(), Pred, Dst);
1352 break;
1353 }
1354
1355 case Stmt::CastExprClass: {
1356 CastExpr* C = cast<CastExpr>(S);
1357 VisitCast(C, C->getSubExpr(), Pred, Dst);
1358 break;
1359 }
1360
Ted Kremenek9de04c42008-01-24 20:55:43 +00001361 case Stmt::DeclStmtClass:
1362 VisitDeclStmt(cast<DeclStmt>(S), Pred, Dst);
1363 break;
1364
Ted Kremenekab2b8c52008-01-23 19:59:44 +00001365 default:
1366 Dst.Add(Pred); // No-op. Simply propagate the current state unchanged.
1367 break;
Ted Kremenek79649df2008-01-17 18:25:22 +00001368 }
Ted Kremenek1ccd31c2008-01-16 19:42:59 +00001369}
1370
Ted Kremenekee985462008-01-16 18:18:48 +00001371//===----------------------------------------------------------------------===//
1372// Driver.
1373//===----------------------------------------------------------------------===//
1374
Ted Kremenekaa66a322008-01-16 21:46:15 +00001375#ifndef NDEBUG
1376namespace llvm {
1377template<>
1378struct VISIBILITY_HIDDEN DOTGraphTraits<GRConstants::NodeTy*> :
1379 public DefaultDOTGraphTraits {
Ted Kremenek9ff731d2008-01-24 22:27:20 +00001380
1381 static void PrintKindLabel(std::ostream& Out, ValueKey::Kind kind) {
Ted Kremenek803c9ed2008-01-23 22:30:44 +00001382 switch (kind) {
Ted Kremenek565256e2008-01-24 22:44:24 +00001383 case ValueKey::IsSubExpr: Out << "Sub-Expressions:\\l"; break;
Ted Kremenek803c9ed2008-01-23 22:30:44 +00001384 case ValueKey::IsDecl: Out << "Variables:\\l"; break;
1385 case ValueKey::IsBlkExpr: Out << "Block-level Expressions:\\l"; break;
1386 default: assert (false && "Unknown ValueKey type.");
1387 }
1388 }
1389
Ted Kremenek9ff731d2008-01-24 22:27:20 +00001390 static void PrintKind(std::ostream& Out, GRConstants::StateTy M,
1391 ValueKey::Kind kind, bool isFirstGroup = false) {
1392 bool isFirst = true;
1393
1394 for (GRConstants::StateTy::iterator I=M.begin(), E=M.end();I!=E;++I) {
1395 if (I.getKey().getKind() != kind)
1396 continue;
1397
1398 if (isFirst) {
1399 if (!isFirstGroup) Out << "\\l\\l";
1400 PrintKindLabel(Out, kind);
1401 isFirst = false;
1402 }
1403 else
1404 Out << "\\l";
1405
1406 Out << ' ';
1407
1408 if (ValueDecl* V = dyn_cast<ValueDecl>(I.getKey()))
1409 Out << V->getName();
1410 else {
1411 Stmt* E = cast<Stmt>(I.getKey());
1412 Out << " (" << (void*) E << ") ";
1413 E->printPretty(Out);
1414 }
1415
1416 Out << " : ";
1417 I.getData().print(Out);
1418 }
1419 }
1420
Ted Kremenekaa66a322008-01-16 21:46:15 +00001421 static std::string getNodeLabel(const GRConstants::NodeTy* N, void*) {
1422 std::ostringstream Out;
Ted Kremenek803c9ed2008-01-23 22:30:44 +00001423
1424 // Program Location.
Ted Kremenekaa66a322008-01-16 21:46:15 +00001425 ProgramPoint Loc = N->getLocation();
1426
1427 switch (Loc.getKind()) {
1428 case ProgramPoint::BlockEntranceKind:
1429 Out << "Block Entrance: B"
1430 << cast<BlockEntrance>(Loc).getBlock()->getBlockID();
1431 break;
1432
1433 case ProgramPoint::BlockExitKind:
1434 assert (false);
1435 break;
1436
1437 case ProgramPoint::PostStmtKind: {
1438 const PostStmt& L = cast<PostStmt>(Loc);
Ted Kremenek9ff731d2008-01-24 22:27:20 +00001439 Out << L.getStmt()->getStmtClassName() << ':'
1440 << (void*) L.getStmt() << ' ';
1441
Ted Kremenekaa66a322008-01-16 21:46:15 +00001442 L.getStmt()->printPretty(Out);
1443 break;
1444 }
1445
1446 default: {
1447 const BlockEdge& E = cast<BlockEdge>(Loc);
1448 Out << "Edge: (B" << E.getSrc()->getBlockID() << ", B"
1449 << E.getDst()->getBlockID() << ')';
1450 }
1451 }
1452
Ted Kremenek803c9ed2008-01-23 22:30:44 +00001453 Out << "\\|";
Ted Kremenekaa66a322008-01-16 21:46:15 +00001454
Ted Kremenek9ff731d2008-01-24 22:27:20 +00001455 PrintKind(Out, N->getState(), ValueKey::IsDecl, true);
1456 PrintKind(Out, N->getState(), ValueKey::IsBlkExpr);
Ted Kremenek565256e2008-01-24 22:44:24 +00001457 PrintKind(Out, N->getState(), ValueKey::IsSubExpr);
Ted Kremenek803c9ed2008-01-23 22:30:44 +00001458
Ted Kremenek803c9ed2008-01-23 22:30:44 +00001459 Out << "\\l";
Ted Kremenekaa66a322008-01-16 21:46:15 +00001460 return Out.str();
1461 }
1462};
1463} // end llvm namespace
1464#endif
1465
Ted Kremenekee985462008-01-16 18:18:48 +00001466namespace clang {
Ted Kremenekcb48b9c2008-01-29 00:33:40 +00001467void RunGRConstants(CFG& cfg, FunctionDecl& FD, ASTContext& Ctx) {
1468 GREngine<GRConstants> Engine(cfg, FD, Ctx);
Ted Kremenekee985462008-01-16 18:18:48 +00001469 Engine.ExecuteWorkList();
Ted Kremenekaa66a322008-01-16 21:46:15 +00001470#ifndef NDEBUG
1471 llvm::ViewGraph(*Engine.getGraph().roots_begin(),"GRConstants");
1472#endif
Ted Kremenekee985462008-01-16 18:18:48 +00001473}
Ted Kremenekab2b8c52008-01-23 19:59:44 +00001474} // end clang namespace