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