To catch bugs like the one fixed in
[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(ConstantInt::get(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_Const) {
124   const CastInst *ConstBitcast = BitcastV.get();
125   AssertingVH<const CastInst> AVH(ConstBitcast);
126   const CastInst *implicit_to_exact_type = AVH;
127   implicit_to_exact_type = implicit_to_exact_type;  // Avoid warning.
128 }
129
130 TEST_F(ValueHandle, AssertingVH_Comparisons) {
131   AssertingVH<Value> BitcastAVH(BitcastV.get());
132   AssertingVH<Value> ConstantAVH(ConstantV);
133
134   EXPECT_TRUE(BitcastAVH == BitcastAVH);
135   EXPECT_TRUE(BitcastV.get() == BitcastAVH);
136   EXPECT_TRUE(BitcastAVH == BitcastV.get());
137   EXPECT_FALSE(BitcastAVH == ConstantAVH);
138
139   EXPECT_TRUE(BitcastAVH != ConstantAVH);
140   EXPECT_TRUE(BitcastV.get() != ConstantAVH);
141   EXPECT_TRUE(BitcastAVH != ConstantV);
142   EXPECT_FALSE(BitcastAVH != BitcastAVH);
143
144   // Cast to Value* so comparisons work.
145   Value *BV = BitcastV.get();
146   Value *CV = ConstantV;
147   EXPECT_EQ(BV < CV, BitcastAVH < ConstantAVH);
148   EXPECT_EQ(BV <= CV, BitcastAVH <= ConstantAVH);
149   EXPECT_EQ(BV > CV, BitcastAVH > ConstantAVH);
150   EXPECT_EQ(BV >= CV, BitcastAVH >= ConstantAVH);
151
152   EXPECT_EQ(BV < CV, BitcastV.get() < ConstantAVH);
153   EXPECT_EQ(BV <= CV, BitcastV.get() <= ConstantAVH);
154   EXPECT_EQ(BV > CV, BitcastV.get() > ConstantAVH);
155   EXPECT_EQ(BV >= CV, BitcastV.get() >= ConstantAVH);
156
157   EXPECT_EQ(BV < CV, BitcastAVH < ConstantV);
158   EXPECT_EQ(BV <= CV, BitcastAVH <= ConstantV);
159   EXPECT_EQ(BV > CV, BitcastAVH > ConstantV);
160   EXPECT_EQ(BV >= CV, BitcastAVH >= ConstantV);
161 }
162
163 TEST_F(ValueHandle, AssertingVH_DoesNotFollowRAUW) {
164   AssertingVH<Value> AVH(BitcastV.get());
165   BitcastV->replaceAllUsesWith(ConstantV);
166   EXPECT_EQ(BitcastV.get(), AVH);
167 }
168
169 #ifdef NDEBUG
170
171 TEST_F(ValueHandle, AssertingVH_ReducesToPointer) {
172   EXPECT_EQ(sizeof(CastInst *), sizeof(AssertingVH<CastInst>));
173 }
174
175 #else  // !NDEBUG
176
177 #ifdef GTEST_HAS_DEATH_TEST
178
179 TEST_F(ValueHandle, AssertingVH_Asserts) {
180   AssertingVH<Value> AVH(BitcastV.get());
181   EXPECT_DEATH({BitcastV.reset();},
182                "An asserting value handle still pointed to this value!");
183   AssertingVH<Value> Copy(AVH);
184   AVH = NULL;
185   EXPECT_DEATH({BitcastV.reset();},
186                "An asserting value handle still pointed to this value!");
187   Copy = NULL;
188   BitcastV.reset();
189 }
190
191 #endif  // GTEST_HAS_DEATH_TEST
192
193 #endif  // NDEBUG
194
195 TEST_F(ValueHandle, CallbackVH_BasicOperation) {
196   ConcreteCallbackVH CVH(BitcastV.get());
197   EXPECT_EQ(BitcastV.get(), CVH);
198   CVH = ConstantV;
199   EXPECT_EQ(ConstantV, CVH);
200
201   // Make sure I can call a method on the underlying Value.  It
202   // doesn't matter which method.
203   EXPECT_EQ(Type::Int32Ty, CVH->getType());
204   EXPECT_EQ(Type::Int32Ty, (*CVH).getType());
205 }
206
207 TEST_F(ValueHandle, CallbackVH_Comparisons) {
208   ConcreteCallbackVH BitcastCVH(BitcastV.get());
209   ConcreteCallbackVH ConstantCVH(ConstantV);
210
211   EXPECT_TRUE(BitcastCVH == BitcastCVH);
212   EXPECT_TRUE(BitcastV.get() == BitcastCVH);
213   EXPECT_TRUE(BitcastCVH == BitcastV.get());
214   EXPECT_FALSE(BitcastCVH == ConstantCVH);
215
216   EXPECT_TRUE(BitcastCVH != ConstantCVH);
217   EXPECT_TRUE(BitcastV.get() != ConstantCVH);
218   EXPECT_TRUE(BitcastCVH != ConstantV);
219   EXPECT_FALSE(BitcastCVH != BitcastCVH);
220
221   // Cast to Value* so comparisons work.
222   Value *BV = BitcastV.get();
223   Value *CV = ConstantV;
224   EXPECT_EQ(BV < CV, BitcastCVH < ConstantCVH);
225   EXPECT_EQ(BV <= CV, BitcastCVH <= ConstantCVH);
226   EXPECT_EQ(BV > CV, BitcastCVH > ConstantCVH);
227   EXPECT_EQ(BV >= CV, BitcastCVH >= ConstantCVH);
228
229   EXPECT_EQ(BV < CV, BitcastV.get() < ConstantCVH);
230   EXPECT_EQ(BV <= CV, BitcastV.get() <= ConstantCVH);
231   EXPECT_EQ(BV > CV, BitcastV.get() > ConstantCVH);
232   EXPECT_EQ(BV >= CV, BitcastV.get() >= ConstantCVH);
233
234   EXPECT_EQ(BV < CV, BitcastCVH < ConstantV);
235   EXPECT_EQ(BV <= CV, BitcastCVH <= ConstantV);
236   EXPECT_EQ(BV > CV, BitcastCVH > ConstantV);
237   EXPECT_EQ(BV >= CV, BitcastCVH >= ConstantV);
238 }
239
240 TEST_F(ValueHandle, CallbackVH_CallbackOnDeletion) {
241   class RecordingVH : public CallbackVH {
242   public:
243     int DeletedCalls;
244     int AURWCalls;
245
246     RecordingVH() : DeletedCalls(0), AURWCalls(0) {}
247     RecordingVH(Value *V) : CallbackVH(V), DeletedCalls(0), AURWCalls(0) {}
248
249   private:
250     virtual void deleted() { DeletedCalls++; CallbackVH::deleted(); }
251     virtual void allUsesReplacedWith(Value *) { AURWCalls++; }
252   };
253
254   RecordingVH RVH;
255   RVH = BitcastV.get();
256   EXPECT_EQ(0, RVH.DeletedCalls);
257   EXPECT_EQ(0, RVH.AURWCalls);
258   BitcastV.reset();
259   EXPECT_EQ(1, RVH.DeletedCalls);
260   EXPECT_EQ(0, RVH.AURWCalls);
261 }
262
263 TEST_F(ValueHandle, CallbackVH_CallbackOnRAUW) {
264   class RecordingVH : public CallbackVH {
265   public:
266     int DeletedCalls;
267     Value *AURWArgument;
268
269     RecordingVH() : DeletedCalls(0), AURWArgument(NULL) {}
270     RecordingVH(Value *V)
271       : CallbackVH(V), DeletedCalls(0), AURWArgument(NULL) {}
272
273   private:
274     virtual void deleted() { DeletedCalls++; CallbackVH::deleted(); }
275     virtual void allUsesReplacedWith(Value *new_value) {
276       EXPECT_EQ(NULL, AURWArgument);
277       AURWArgument = new_value;
278     }
279   };
280
281   RecordingVH RVH;
282   RVH = BitcastV.get();
283   EXPECT_EQ(0, RVH.DeletedCalls);
284   EXPECT_EQ(NULL, RVH.AURWArgument);
285   BitcastV->replaceAllUsesWith(ConstantV);
286   EXPECT_EQ(0, RVH.DeletedCalls);
287   EXPECT_EQ(ConstantV, RVH.AURWArgument);
288 }
289
290 TEST_F(ValueHandle, CallbackVH_DeletionCanRAUW) {
291   class RecoveringVH : public CallbackVH {
292   public:
293     int DeletedCalls;
294     Value *AURWArgument;
295     LLVMContext *Context;
296
297     RecoveringVH() : DeletedCalls(0), AURWArgument(NULL), 
298                      Context(&getGlobalContext()) {}
299     RecoveringVH(Value *V)
300       : CallbackVH(V), DeletedCalls(0), AURWArgument(NULL), 
301         Context(&getGlobalContext()) {}
302
303   private:
304     virtual void deleted() {
305       getValPtr()->replaceAllUsesWith(Constant::getNullValue(Type::Int32Ty));
306       setValPtr(NULL);
307     }
308     virtual void allUsesReplacedWith(Value *new_value) {
309       ASSERT_TRUE(NULL != getValPtr());
310       EXPECT_EQ(1U, getValPtr()->getNumUses());
311       EXPECT_EQ(NULL, AURWArgument);
312       AURWArgument = new_value;
313     }
314   };
315
316   // Normally, if a value has uses, deleting it will crash.  However, we can use
317   // a CallbackVH to remove the uses before the check for no uses.
318   RecoveringVH RVH;
319   RVH = BitcastV.get();
320   std::auto_ptr<BinaryOperator> BitcastUser(
321     BinaryOperator::CreateAdd(RVH, 
322                               Constant::getNullValue(Type::Int32Ty)));
323   EXPECT_EQ(BitcastV.get(), BitcastUser->getOperand(0));
324   BitcastV.reset();  // Would crash without the ValueHandler.
325   EXPECT_EQ(Constant::getNullValue(Type::Int32Ty), RVH.AURWArgument);
326   EXPECT_EQ(Constant::getNullValue(Type::Int32Ty),
327             BitcastUser->getOperand(0));
328 }
329
330 }