Move EVER MORE stuff over to LLVMContext.
[oota-llvm.git] / unittests / Support / ValueHandleTest.cpp
1 //===- llvm/unittest/Support/ValueHandleTest.cpp - ValueHandle tests --------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "llvm/Support/ValueHandle.h"
11
12 #include "llvm/Constants.h"
13 #include "llvm/Instructions.h"
14
15 #include "gtest/gtest.h"
16
17 #include <memory>
18
19 using namespace llvm;
20
21 namespace {
22
23 class ValueHandle : public testing::Test {
24 protected:
25   Constant *ConstantV;
26   std::auto_ptr<BitCastInst> BitcastV;
27
28   ValueHandle() :
29     ConstantV(getGlobalContext().getConstantInt(Type::Int32Ty, 0)),
30     BitcastV(new BitCastInst(ConstantV, Type::Int32Ty)) {
31   }
32 };
33
34 class ConcreteCallbackVH : public CallbackVH {
35 public:
36   ConcreteCallbackVH() : CallbackVH() {}
37   ConcreteCallbackVH(Value *V) : CallbackVH(V) {}
38 };
39
40 TEST_F(ValueHandle, WeakVH_BasicOperation) {
41   WeakVH WVH(BitcastV.get());
42   EXPECT_EQ(BitcastV.get(), WVH);
43   WVH = ConstantV;
44   EXPECT_EQ(ConstantV, WVH);
45
46   // Make sure I can call a method on the underlying Value.  It
47   // doesn't matter which method.
48   EXPECT_EQ(Type::Int32Ty, WVH->getType());
49   EXPECT_EQ(Type::Int32Ty, (*WVH).getType());
50 }
51
52 TEST_F(ValueHandle, WeakVH_Comparisons) {
53   WeakVH BitcastWVH(BitcastV.get());
54   WeakVH ConstantWVH(ConstantV);
55
56   EXPECT_TRUE(BitcastWVH == BitcastWVH);
57   EXPECT_TRUE(BitcastV.get() == BitcastWVH);
58   EXPECT_TRUE(BitcastWVH == BitcastV.get());
59   EXPECT_FALSE(BitcastWVH == ConstantWVH);
60
61   EXPECT_TRUE(BitcastWVH != ConstantWVH);
62   EXPECT_TRUE(BitcastV.get() != ConstantWVH);
63   EXPECT_TRUE(BitcastWVH != ConstantV);
64   EXPECT_FALSE(BitcastWVH != BitcastWVH);
65
66   // Cast to Value* so comparisons work.
67   Value *BV = BitcastV.get();
68   Value *CV = ConstantV;
69   EXPECT_EQ(BV < CV, BitcastWVH < ConstantWVH);
70   EXPECT_EQ(BV <= CV, BitcastWVH <= ConstantWVH);
71   EXPECT_EQ(BV > CV, BitcastWVH > ConstantWVH);
72   EXPECT_EQ(BV >= CV, BitcastWVH >= ConstantWVH);
73
74   EXPECT_EQ(BV < CV, BitcastV.get() < ConstantWVH);
75   EXPECT_EQ(BV <= CV, BitcastV.get() <= ConstantWVH);
76   EXPECT_EQ(BV > CV, BitcastV.get() > ConstantWVH);
77   EXPECT_EQ(BV >= CV, BitcastV.get() >= ConstantWVH);
78
79   EXPECT_EQ(BV < CV, BitcastWVH < ConstantV);
80   EXPECT_EQ(BV <= CV, BitcastWVH <= ConstantV);
81   EXPECT_EQ(BV > CV, BitcastWVH > ConstantV);
82   EXPECT_EQ(BV >= CV, BitcastWVH >= ConstantV);
83 }
84
85 TEST_F(ValueHandle, WeakVH_FollowsRAUW) {
86   WeakVH WVH(BitcastV.get());
87   WeakVH WVH_Copy(WVH);
88   WeakVH WVH_Recreated(BitcastV.get());
89   BitcastV->replaceAllUsesWith(ConstantV);
90   EXPECT_EQ(ConstantV, WVH);
91   EXPECT_EQ(ConstantV, WVH_Copy);
92   EXPECT_EQ(ConstantV, WVH_Recreated);
93 }
94
95 TEST_F(ValueHandle, WeakVH_NullOnDeletion) {
96   WeakVH WVH(BitcastV.get());
97   WeakVH WVH_Copy(WVH);
98   WeakVH WVH_Recreated(BitcastV.get());
99   BitcastV.reset();
100   Value *null_value = NULL;
101   EXPECT_EQ(null_value, WVH);
102   EXPECT_EQ(null_value, WVH_Copy);
103   EXPECT_EQ(null_value, WVH_Recreated);
104 }
105
106
107 TEST_F(ValueHandle, AssertingVH_BasicOperation) {
108   AssertingVH<CastInst> AVH(BitcastV.get());
109   CastInst *implicit_to_exact_type = AVH;
110   implicit_to_exact_type = implicit_to_exact_type;  // Avoid warning.
111
112   AssertingVH<Value> GenericAVH(BitcastV.get());
113   EXPECT_EQ(BitcastV.get(), GenericAVH);
114   GenericAVH = ConstantV;
115   EXPECT_EQ(ConstantV, GenericAVH);
116
117   // Make sure I can call a method on the underlying CastInst.  It
118   // doesn't matter which method.
119   EXPECT_FALSE(AVH->mayWriteToMemory());
120   EXPECT_FALSE((*AVH).mayWriteToMemory());
121 }
122
123 TEST_F(ValueHandle, AssertingVH_Comparisons) {
124   AssertingVH<Value> BitcastAVH(BitcastV.get());
125   AssertingVH<Value> ConstantAVH(ConstantV);
126
127   EXPECT_TRUE(BitcastAVH == BitcastAVH);
128   EXPECT_TRUE(BitcastV.get() == BitcastAVH);
129   EXPECT_TRUE(BitcastAVH == BitcastV.get());
130   EXPECT_FALSE(BitcastAVH == ConstantAVH);
131
132   EXPECT_TRUE(BitcastAVH != ConstantAVH);
133   EXPECT_TRUE(BitcastV.get() != ConstantAVH);
134   EXPECT_TRUE(BitcastAVH != ConstantV);
135   EXPECT_FALSE(BitcastAVH != BitcastAVH);
136
137   // Cast to Value* so comparisons work.
138   Value *BV = BitcastV.get();
139   Value *CV = ConstantV;
140   EXPECT_EQ(BV < CV, BitcastAVH < ConstantAVH);
141   EXPECT_EQ(BV <= CV, BitcastAVH <= ConstantAVH);
142   EXPECT_EQ(BV > CV, BitcastAVH > ConstantAVH);
143   EXPECT_EQ(BV >= CV, BitcastAVH >= ConstantAVH);
144
145   EXPECT_EQ(BV < CV, BitcastV.get() < ConstantAVH);
146   EXPECT_EQ(BV <= CV, BitcastV.get() <= ConstantAVH);
147   EXPECT_EQ(BV > CV, BitcastV.get() > ConstantAVH);
148   EXPECT_EQ(BV >= CV, BitcastV.get() >= ConstantAVH);
149
150   EXPECT_EQ(BV < CV, BitcastAVH < ConstantV);
151   EXPECT_EQ(BV <= CV, BitcastAVH <= ConstantV);
152   EXPECT_EQ(BV > CV, BitcastAVH > ConstantV);
153   EXPECT_EQ(BV >= CV, BitcastAVH >= ConstantV);
154 }
155
156 TEST_F(ValueHandle, AssertingVH_DoesNotFollowRAUW) {
157   AssertingVH<Value> AVH(BitcastV.get());
158   BitcastV->replaceAllUsesWith(ConstantV);
159   EXPECT_EQ(BitcastV.get(), AVH);
160 }
161
162 #ifdef NDEBUG
163
164 TEST_F(ValueHandle, AssertingVH_ReducesToPointer) {
165   EXPECT_EQ(sizeof(CastInst *), sizeof(AssertingVH<CastInst>));
166 }
167
168 #else  // !NDEBUG
169
170 #ifdef GTEST_HAS_DEATH_TEST
171
172 TEST_F(ValueHandle, AssertingVH_Asserts) {
173   AssertingVH<Value> AVH(BitcastV.get());
174   EXPECT_DEATH({BitcastV.reset();},
175                "An asserting value handle still pointed to this value!");
176   AssertingVH<Value> Copy(AVH);
177   AVH = NULL;
178   EXPECT_DEATH({BitcastV.reset();},
179                "An asserting value handle still pointed to this value!");
180   Copy = NULL;
181   BitcastV.reset();
182 }
183
184 #endif  // GTEST_HAS_DEATH_TEST
185
186 #endif  // NDEBUG
187
188 TEST_F(ValueHandle, CallbackVH_BasicOperation) {
189   ConcreteCallbackVH CVH(BitcastV.get());
190   EXPECT_EQ(BitcastV.get(), CVH);
191   CVH = ConstantV;
192   EXPECT_EQ(ConstantV, CVH);
193
194   // Make sure I can call a method on the underlying Value.  It
195   // doesn't matter which method.
196   EXPECT_EQ(Type::Int32Ty, CVH->getType());
197   EXPECT_EQ(Type::Int32Ty, (*CVH).getType());
198 }
199
200 TEST_F(ValueHandle, CallbackVH_Comparisons) {
201   ConcreteCallbackVH BitcastCVH(BitcastV.get());
202   ConcreteCallbackVH ConstantCVH(ConstantV);
203
204   EXPECT_TRUE(BitcastCVH == BitcastCVH);
205   EXPECT_TRUE(BitcastV.get() == BitcastCVH);
206   EXPECT_TRUE(BitcastCVH == BitcastV.get());
207   EXPECT_FALSE(BitcastCVH == ConstantCVH);
208
209   EXPECT_TRUE(BitcastCVH != ConstantCVH);
210   EXPECT_TRUE(BitcastV.get() != ConstantCVH);
211   EXPECT_TRUE(BitcastCVH != ConstantV);
212   EXPECT_FALSE(BitcastCVH != BitcastCVH);
213
214   // Cast to Value* so comparisons work.
215   Value *BV = BitcastV.get();
216   Value *CV = ConstantV;
217   EXPECT_EQ(BV < CV, BitcastCVH < ConstantCVH);
218   EXPECT_EQ(BV <= CV, BitcastCVH <= ConstantCVH);
219   EXPECT_EQ(BV > CV, BitcastCVH > ConstantCVH);
220   EXPECT_EQ(BV >= CV, BitcastCVH >= ConstantCVH);
221
222   EXPECT_EQ(BV < CV, BitcastV.get() < ConstantCVH);
223   EXPECT_EQ(BV <= CV, BitcastV.get() <= ConstantCVH);
224   EXPECT_EQ(BV > CV, BitcastV.get() > ConstantCVH);
225   EXPECT_EQ(BV >= CV, BitcastV.get() >= ConstantCVH);
226
227   EXPECT_EQ(BV < CV, BitcastCVH < ConstantV);
228   EXPECT_EQ(BV <= CV, BitcastCVH <= ConstantV);
229   EXPECT_EQ(BV > CV, BitcastCVH > ConstantV);
230   EXPECT_EQ(BV >= CV, BitcastCVH >= ConstantV);
231 }
232
233 TEST_F(ValueHandle, CallbackVH_CallbackOnDeletion) {
234   class RecordingVH : public CallbackVH {
235   public:
236     int DeletedCalls;
237     int AURWCalls;
238
239     RecordingVH() : DeletedCalls(0), AURWCalls(0) {}
240     RecordingVH(Value *V) : CallbackVH(V), DeletedCalls(0), AURWCalls(0) {}
241
242   private:
243     virtual void deleted() { DeletedCalls++; CallbackVH::deleted(); }
244     virtual void allUsesReplacedWith(Value *) { AURWCalls++; }
245   };
246
247   RecordingVH RVH;
248   RVH = BitcastV.get();
249   EXPECT_EQ(0, RVH.DeletedCalls);
250   EXPECT_EQ(0, RVH.AURWCalls);
251   BitcastV.reset();
252   EXPECT_EQ(1, RVH.DeletedCalls);
253   EXPECT_EQ(0, RVH.AURWCalls);
254 }
255
256 TEST_F(ValueHandle, CallbackVH_CallbackOnRAUW) {
257   class RecordingVH : public CallbackVH {
258   public:
259     int DeletedCalls;
260     Value *AURWArgument;
261
262     RecordingVH() : DeletedCalls(0), AURWArgument(NULL) {}
263     RecordingVH(Value *V)
264       : CallbackVH(V), DeletedCalls(0), AURWArgument(NULL) {}
265
266   private:
267     virtual void deleted() { DeletedCalls++; CallbackVH::deleted(); }
268     virtual void allUsesReplacedWith(Value *new_value) {
269       EXPECT_EQ(NULL, AURWArgument);
270       AURWArgument = new_value;
271     }
272   };
273
274   RecordingVH RVH;
275   RVH = BitcastV.get();
276   EXPECT_EQ(0, RVH.DeletedCalls);
277   EXPECT_EQ(NULL, RVH.AURWArgument);
278   BitcastV->replaceAllUsesWith(ConstantV);
279   EXPECT_EQ(0, RVH.DeletedCalls);
280   EXPECT_EQ(ConstantV, RVH.AURWArgument);
281 }
282
283 TEST_F(ValueHandle, CallbackVH_DeletionCanRAUW) {
284   class RecoveringVH : public CallbackVH {
285   public:
286     int DeletedCalls;
287     Value *AURWArgument;
288     LLVMContext *Context;
289
290     RecoveringVH() : DeletedCalls(0), AURWArgument(NULL), 
291                      Context(&getGlobalContext()) {}
292     RecoveringVH(Value *V)
293       : CallbackVH(V), DeletedCalls(0), AURWArgument(NULL), 
294         Context(&getGlobalContext()) {}
295
296   private:
297     virtual void deleted() {
298       getValPtr()->replaceAllUsesWith(Context->getNullValue(Type::Int32Ty));
299       setValPtr(NULL);
300     }
301     virtual void allUsesReplacedWith(Value *new_value) {
302       ASSERT_TRUE(NULL != getValPtr());
303       EXPECT_EQ(1U, getValPtr()->getNumUses());
304       EXPECT_EQ(NULL, AURWArgument);
305       AURWArgument = new_value;
306     }
307   };
308
309   // Normally, if a value has uses, deleting it will crash.  However, we can use
310   // a CallbackVH to remove the uses before the check for no uses.
311   RecoveringVH RVH;
312   RVH = BitcastV.get();
313   std::auto_ptr<BinaryOperator> BitcastUser(
314     BinaryOperator::CreateAdd(RVH, 
315                               getGlobalContext().getNullValue(Type::Int32Ty)));
316   EXPECT_EQ(BitcastV.get(), BitcastUser->getOperand(0));
317   BitcastV.reset();  // Would crash without the ValueHandler.
318   EXPECT_EQ(getGlobalContext().getNullValue(Type::Int32Ty), RVH.AURWArgument);
319   EXPECT_EQ(getGlobalContext().getNullValue(Type::Int32Ty),
320             BitcastUser->getOperand(0));
321 }
322
323 }