[C++11] Use 'nullptr'.
[oota-llvm.git] / unittests / IR / ValueHandleTest.cpp
1 //===- 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/IR/ValueHandle.h"
11 #include "llvm/IR/Constants.h"
12 #include "llvm/IR/Instructions.h"
13 #include "llvm/IR/LLVMContext.h"
14 #include "gtest/gtest.h"
15 #include <memory>
16
17 using namespace llvm;
18
19 namespace {
20
21 class ValueHandle : public testing::Test {
22 protected:
23   Constant *ConstantV;
24   std::auto_ptr<BitCastInst> BitcastV;
25
26   ValueHandle() :
27     ConstantV(ConstantInt::get(Type::getInt32Ty(getGlobalContext()), 0)),
28     BitcastV(new BitCastInst(ConstantV, Type::getInt32Ty(getGlobalContext()))) {
29   }
30 };
31
32 class ConcreteCallbackVH : public CallbackVH {
33 public:
34   ConcreteCallbackVH(Value *V) : CallbackVH(V) {}
35 };
36
37 TEST_F(ValueHandle, WeakVH_BasicOperation) {
38   WeakVH WVH(BitcastV.get());
39   EXPECT_EQ(BitcastV.get(), WVH);
40   WVH = ConstantV;
41   EXPECT_EQ(ConstantV, WVH);
42
43   // Make sure I can call a method on the underlying Value.  It
44   // doesn't matter which method.
45   EXPECT_EQ(Type::getInt32Ty(getGlobalContext()), WVH->getType());
46   EXPECT_EQ(Type::getInt32Ty(getGlobalContext()), (*WVH).getType());
47 }
48
49 TEST_F(ValueHandle, WeakVH_Comparisons) {
50   WeakVH BitcastWVH(BitcastV.get());
51   WeakVH ConstantWVH(ConstantV);
52
53   EXPECT_TRUE(BitcastWVH == BitcastWVH);
54   EXPECT_TRUE(BitcastV.get() == BitcastWVH);
55   EXPECT_TRUE(BitcastWVH == BitcastV.get());
56   EXPECT_FALSE(BitcastWVH == ConstantWVH);
57
58   EXPECT_TRUE(BitcastWVH != ConstantWVH);
59   EXPECT_TRUE(BitcastV.get() != ConstantWVH);
60   EXPECT_TRUE(BitcastWVH != ConstantV);
61   EXPECT_FALSE(BitcastWVH != BitcastWVH);
62
63   // Cast to Value* so comparisons work.
64   Value *BV = BitcastV.get();
65   Value *CV = ConstantV;
66   EXPECT_EQ(BV < CV, BitcastWVH < ConstantWVH);
67   EXPECT_EQ(BV <= CV, BitcastWVH <= ConstantWVH);
68   EXPECT_EQ(BV > CV, BitcastWVH > ConstantWVH);
69   EXPECT_EQ(BV >= CV, BitcastWVH >= ConstantWVH);
70
71   EXPECT_EQ(BV < CV, BitcastV.get() < ConstantWVH);
72   EXPECT_EQ(BV <= CV, BitcastV.get() <= ConstantWVH);
73   EXPECT_EQ(BV > CV, BitcastV.get() > ConstantWVH);
74   EXPECT_EQ(BV >= CV, BitcastV.get() >= ConstantWVH);
75
76   EXPECT_EQ(BV < CV, BitcastWVH < ConstantV);
77   EXPECT_EQ(BV <= CV, BitcastWVH <= ConstantV);
78   EXPECT_EQ(BV > CV, BitcastWVH > ConstantV);
79   EXPECT_EQ(BV >= CV, BitcastWVH >= ConstantV);
80 }
81
82 TEST_F(ValueHandle, WeakVH_FollowsRAUW) {
83   WeakVH WVH(BitcastV.get());
84   WeakVH WVH_Copy(WVH);
85   WeakVH WVH_Recreated(BitcastV.get());
86   BitcastV->replaceAllUsesWith(ConstantV);
87   EXPECT_EQ(ConstantV, WVH);
88   EXPECT_EQ(ConstantV, WVH_Copy);
89   EXPECT_EQ(ConstantV, WVH_Recreated);
90 }
91
92 TEST_F(ValueHandle, WeakVH_NullOnDeletion) {
93   WeakVH WVH(BitcastV.get());
94   WeakVH WVH_Copy(WVH);
95   WeakVH WVH_Recreated(BitcastV.get());
96   BitcastV.reset();
97   Value *null_value = nullptr;
98   EXPECT_EQ(null_value, WVH);
99   EXPECT_EQ(null_value, WVH_Copy);
100   EXPECT_EQ(null_value, WVH_Recreated);
101 }
102
103
104 TEST_F(ValueHandle, AssertingVH_BasicOperation) {
105   AssertingVH<CastInst> AVH(BitcastV.get());
106   CastInst *implicit_to_exact_type = AVH;
107   (void)implicit_to_exact_type;  // Avoid warning.
108
109   AssertingVH<Value> GenericAVH(BitcastV.get());
110   EXPECT_EQ(BitcastV.get(), GenericAVH);
111   GenericAVH = ConstantV;
112   EXPECT_EQ(ConstantV, GenericAVH);
113
114   // Make sure I can call a method on the underlying CastInst.  It
115   // doesn't matter which method.
116   EXPECT_FALSE(AVH->mayWriteToMemory());
117   EXPECT_FALSE((*AVH).mayWriteToMemory());
118 }
119
120 TEST_F(ValueHandle, AssertingVH_Const) {
121   const CastInst *ConstBitcast = BitcastV.get();
122   AssertingVH<const CastInst> AVH(ConstBitcast);
123   const CastInst *implicit_to_exact_type = AVH;
124   (void)implicit_to_exact_type;  // Avoid warning.
125 }
126
127 TEST_F(ValueHandle, AssertingVH_Comparisons) {
128   AssertingVH<Value> BitcastAVH(BitcastV.get());
129   AssertingVH<Value> ConstantAVH(ConstantV);
130
131   EXPECT_TRUE(BitcastAVH == BitcastAVH);
132   EXPECT_TRUE(BitcastV.get() == BitcastAVH);
133   EXPECT_TRUE(BitcastAVH == BitcastV.get());
134   EXPECT_FALSE(BitcastAVH == ConstantAVH);
135
136   EXPECT_TRUE(BitcastAVH != ConstantAVH);
137   EXPECT_TRUE(BitcastV.get() != ConstantAVH);
138   EXPECT_TRUE(BitcastAVH != ConstantV);
139   EXPECT_FALSE(BitcastAVH != BitcastAVH);
140
141   // Cast to Value* so comparisons work.
142   Value *BV = BitcastV.get();
143   Value *CV = ConstantV;
144   EXPECT_EQ(BV < CV, BitcastAVH < ConstantAVH);
145   EXPECT_EQ(BV <= CV, BitcastAVH <= ConstantAVH);
146   EXPECT_EQ(BV > CV, BitcastAVH > ConstantAVH);
147   EXPECT_EQ(BV >= CV, BitcastAVH >= ConstantAVH);
148
149   EXPECT_EQ(BV < CV, BitcastV.get() < ConstantAVH);
150   EXPECT_EQ(BV <= CV, BitcastV.get() <= ConstantAVH);
151   EXPECT_EQ(BV > CV, BitcastV.get() > ConstantAVH);
152   EXPECT_EQ(BV >= CV, BitcastV.get() >= ConstantAVH);
153
154   EXPECT_EQ(BV < CV, BitcastAVH < ConstantV);
155   EXPECT_EQ(BV <= CV, BitcastAVH <= ConstantV);
156   EXPECT_EQ(BV > CV, BitcastAVH > ConstantV);
157   EXPECT_EQ(BV >= CV, BitcastAVH >= ConstantV);
158 }
159
160 TEST_F(ValueHandle, AssertingVH_DoesNotFollowRAUW) {
161   AssertingVH<Value> AVH(BitcastV.get());
162   BitcastV->replaceAllUsesWith(ConstantV);
163   EXPECT_EQ(BitcastV.get(), AVH);
164 }
165
166 #ifdef NDEBUG
167
168 TEST_F(ValueHandle, AssertingVH_ReducesToPointer) {
169   EXPECT_EQ(sizeof(CastInst *), sizeof(AssertingVH<CastInst>));
170 }
171
172 #else  // !NDEBUG
173
174 #ifdef GTEST_HAS_DEATH_TEST
175
176 TEST_F(ValueHandle, AssertingVH_Asserts) {
177   AssertingVH<Value> AVH(BitcastV.get());
178   EXPECT_DEATH({BitcastV.reset();},
179                "An asserting value handle still pointed to this value!");
180   AssertingVH<Value> Copy(AVH);
181   AVH = nullptr;
182   EXPECT_DEATH({BitcastV.reset();},
183                "An asserting value handle still pointed to this value!");
184   Copy = nullptr;
185   BitcastV.reset();
186 }
187
188 #endif  // GTEST_HAS_DEATH_TEST
189
190 #endif  // NDEBUG
191
192 TEST_F(ValueHandle, CallbackVH_BasicOperation) {
193   ConcreteCallbackVH CVH(BitcastV.get());
194   EXPECT_EQ(BitcastV.get(), CVH);
195   CVH = ConstantV;
196   EXPECT_EQ(ConstantV, CVH);
197
198   // Make sure I can call a method on the underlying Value.  It
199   // doesn't matter which method.
200   EXPECT_EQ(Type::getInt32Ty(getGlobalContext()), CVH->getType());
201   EXPECT_EQ(Type::getInt32Ty(getGlobalContext()), (*CVH).getType());
202 }
203
204 TEST_F(ValueHandle, CallbackVH_Comparisons) {
205   ConcreteCallbackVH BitcastCVH(BitcastV.get());
206   ConcreteCallbackVH ConstantCVH(ConstantV);
207
208   EXPECT_TRUE(BitcastCVH == BitcastCVH);
209   EXPECT_TRUE(BitcastV.get() == BitcastCVH);
210   EXPECT_TRUE(BitcastCVH == BitcastV.get());
211   EXPECT_FALSE(BitcastCVH == ConstantCVH);
212
213   EXPECT_TRUE(BitcastCVH != ConstantCVH);
214   EXPECT_TRUE(BitcastV.get() != ConstantCVH);
215   EXPECT_TRUE(BitcastCVH != ConstantV);
216   EXPECT_FALSE(BitcastCVH != BitcastCVH);
217
218   // Cast to Value* so comparisons work.
219   Value *BV = BitcastV.get();
220   Value *CV = ConstantV;
221   EXPECT_EQ(BV < CV, BitcastCVH < ConstantCVH);
222   EXPECT_EQ(BV <= CV, BitcastCVH <= ConstantCVH);
223   EXPECT_EQ(BV > CV, BitcastCVH > ConstantCVH);
224   EXPECT_EQ(BV >= CV, BitcastCVH >= ConstantCVH);
225
226   EXPECT_EQ(BV < CV, BitcastV.get() < ConstantCVH);
227   EXPECT_EQ(BV <= CV, BitcastV.get() <= ConstantCVH);
228   EXPECT_EQ(BV > CV, BitcastV.get() > ConstantCVH);
229   EXPECT_EQ(BV >= CV, BitcastV.get() >= ConstantCVH);
230
231   EXPECT_EQ(BV < CV, BitcastCVH < ConstantV);
232   EXPECT_EQ(BV <= CV, BitcastCVH <= ConstantV);
233   EXPECT_EQ(BV > CV, BitcastCVH > ConstantV);
234   EXPECT_EQ(BV >= CV, BitcastCVH >= ConstantV);
235 }
236
237 TEST_F(ValueHandle, CallbackVH_CallbackOnDeletion) {
238   class RecordingVH : public CallbackVH {
239   public:
240     int DeletedCalls;
241     int AURWCalls;
242
243     RecordingVH() : DeletedCalls(0), AURWCalls(0) {}
244     RecordingVH(Value *V) : CallbackVH(V), DeletedCalls(0), AURWCalls(0) {}
245
246   private:
247     virtual void deleted() { DeletedCalls++; CallbackVH::deleted(); }
248     virtual void allUsesReplacedWith(Value *) { AURWCalls++; }
249   };
250
251   RecordingVH RVH;
252   RVH = BitcastV.get();
253   EXPECT_EQ(0, RVH.DeletedCalls);
254   EXPECT_EQ(0, RVH.AURWCalls);
255   BitcastV.reset();
256   EXPECT_EQ(1, RVH.DeletedCalls);
257   EXPECT_EQ(0, RVH.AURWCalls);
258 }
259
260 TEST_F(ValueHandle, CallbackVH_CallbackOnRAUW) {
261   class RecordingVH : public CallbackVH {
262   public:
263     int DeletedCalls;
264     Value *AURWArgument;
265
266     RecordingVH() : DeletedCalls(0), AURWArgument(nullptr) {}
267     RecordingVH(Value *V)
268       : CallbackVH(V), DeletedCalls(0), AURWArgument(nullptr) {}
269
270   private:
271     virtual void deleted() { DeletedCalls++; CallbackVH::deleted(); }
272     virtual void allUsesReplacedWith(Value *new_value) {
273       EXPECT_EQ(nullptr, AURWArgument);
274       AURWArgument = new_value;
275     }
276   };
277
278   RecordingVH RVH;
279   RVH = BitcastV.get();
280   EXPECT_EQ(0, RVH.DeletedCalls);
281   EXPECT_EQ(nullptr, RVH.AURWArgument);
282   BitcastV->replaceAllUsesWith(ConstantV);
283   EXPECT_EQ(0, RVH.DeletedCalls);
284   EXPECT_EQ(ConstantV, RVH.AURWArgument);
285 }
286
287 TEST_F(ValueHandle, CallbackVH_DeletionCanRAUW) {
288   class RecoveringVH : public CallbackVH {
289   public:
290     int DeletedCalls;
291     Value *AURWArgument;
292     LLVMContext *Context;
293
294     RecoveringVH() : DeletedCalls(0), AURWArgument(nullptr), 
295                      Context(&getGlobalContext()) {}
296     RecoveringVH(Value *V)
297       : CallbackVH(V), DeletedCalls(0), AURWArgument(nullptr), 
298         Context(&getGlobalContext()) {}
299
300   private:
301     virtual void deleted() {
302       getValPtr()->replaceAllUsesWith(Constant::getNullValue(Type::getInt32Ty(getGlobalContext())));
303       setValPtr(nullptr);
304     }
305     virtual void allUsesReplacedWith(Value *new_value) {
306       ASSERT_TRUE(nullptr != getValPtr());
307       EXPECT_EQ(1U, getValPtr()->getNumUses());
308       EXPECT_EQ(nullptr, AURWArgument);
309       AURWArgument = new_value;
310     }
311   };
312
313   // Normally, if a value has uses, deleting it will crash.  However, we can use
314   // a CallbackVH to remove the uses before the check for no uses.
315   RecoveringVH RVH;
316   RVH = BitcastV.get();
317   std::auto_ptr<BinaryOperator> BitcastUser(
318     BinaryOperator::CreateAdd(RVH, 
319                               Constant::getNullValue(Type::getInt32Ty(getGlobalContext()))));
320   EXPECT_EQ(BitcastV.get(), BitcastUser->getOperand(0));
321   BitcastV.reset();  // Would crash without the ValueHandler.
322   EXPECT_EQ(Constant::getNullValue(Type::getInt32Ty(getGlobalContext())), RVH.AURWArgument);
323   EXPECT_EQ(Constant::getNullValue(Type::getInt32Ty(getGlobalContext())),
324             BitcastUser->getOperand(0));
325 }
326
327 TEST_F(ValueHandle, DestroyingOtherVHOnSameValueDoesntBreakIteration) {
328   // When a CallbackVH modifies other ValueHandles in its callbacks,
329   // that shouldn't interfere with non-modified ValueHandles receiving
330   // their appropriate callbacks.
331   //
332   // We create the active CallbackVH in the middle of a palindromic
333   // arrangement of other VHs so that the bad behavior would be
334   // triggered in whichever order callbacks run.
335
336   class DestroyingVH : public CallbackVH {
337   public:
338     std::unique_ptr<WeakVH> ToClear[2];
339     DestroyingVH(Value *V) {
340       ToClear[0].reset(new WeakVH(V));
341       setValPtr(V);
342       ToClear[1].reset(new WeakVH(V));
343     }
344     virtual void deleted() {
345       ToClear[0].reset();
346       ToClear[1].reset();
347       CallbackVH::deleted();
348     }
349     virtual void allUsesReplacedWith(Value *) {
350       ToClear[0].reset();
351       ToClear[1].reset();
352     }
353   };
354
355   {
356     WeakVH ShouldBeVisited1(BitcastV.get());
357     DestroyingVH C(BitcastV.get());
358     WeakVH ShouldBeVisited2(BitcastV.get());
359
360     BitcastV->replaceAllUsesWith(ConstantV);
361     EXPECT_EQ(ConstantV, static_cast<Value*>(ShouldBeVisited1));
362     EXPECT_EQ(ConstantV, static_cast<Value*>(ShouldBeVisited2));
363   }
364
365   {
366     WeakVH ShouldBeVisited1(BitcastV.get());
367     DestroyingVH C(BitcastV.get());
368     WeakVH ShouldBeVisited2(BitcastV.get());
369
370     BitcastV.reset();
371     EXPECT_EQ(nullptr, static_cast<Value*>(ShouldBeVisited1));
372     EXPECT_EQ(nullptr, static_cast<Value*>(ShouldBeVisited2));
373   }
374 }
375
376 TEST_F(ValueHandle, AssertingVHCheckedLast) {
377   // If a CallbackVH exists to clear out a group of AssertingVHs on
378   // Value deletion, the CallbackVH should get a chance to do so
379   // before the AssertingVHs assert.
380
381   class ClearingVH : public CallbackVH {
382   public:
383     AssertingVH<Value> *ToClear[2];
384     ClearingVH(Value *V,
385                AssertingVH<Value> &A0, AssertingVH<Value> &A1)
386       : CallbackVH(V) {
387       ToClear[0] = &A0;
388       ToClear[1] = &A1;
389     }
390
391     virtual void deleted() {
392       *ToClear[0] = nullptr;
393       *ToClear[1] = nullptr;
394       CallbackVH::deleted();
395     }
396   };
397
398   AssertingVH<Value> A1, A2;
399   A1 = BitcastV.get();
400   ClearingVH C(BitcastV.get(), A1, A2);
401   A2 = BitcastV.get();
402   // C.deleted() should run first, clearing the two AssertingVHs,
403   // which should prevent them from asserting.
404   BitcastV.reset();
405 }
406
407 }