1 //===- ValueHandleTest.cpp - ValueHandle tests ----------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "llvm/IR/ValueHandle.h"
10 #include "llvm/IR/Constants.h"
11 #include "llvm/IR/Instructions.h"
12 #include "llvm/IR/LLVMContext.h"
13 #include "gtest/gtest.h"
14 #include <memory>
15 
16 using namespace llvm;
17 
18 namespace {
19 
20 class ValueHandle : public testing::Test {
21 protected:
22   LLVMContext Context;
23   Constant *ConstantV;
24   std::unique_ptr<BitCastInst> BitcastV;
25 
ValueHandle()26   ValueHandle()
27       : ConstantV(ConstantInt::get(Type::getInt32Ty(Context), 0)),
28         BitcastV(new BitCastInst(ConstantV, Type::getInt32Ty(Context))) {}
29 };
30 
31 class ConcreteCallbackVH final : public CallbackVH {
32 public:
ConcreteCallbackVH(Value * V)33   ConcreteCallbackVH(Value *V) : CallbackVH(V) {}
34 };
35 
TEST_F(ValueHandle,WeakVH_BasicOperation)36 TEST_F(ValueHandle, WeakVH_BasicOperation) {
37   WeakVH WVH(BitcastV.get());
38   EXPECT_EQ(BitcastV.get(), WVH);
39   WVH = ConstantV;
40   EXPECT_EQ(ConstantV, WVH);
41 
42   // Make sure I can call a method on the underlying Value.  It
43   // doesn't matter which method.
44   EXPECT_EQ(Type::getInt32Ty(Context), WVH->getType());
45   EXPECT_EQ(Type::getInt32Ty(Context), (*WVH).getType());
46 
47   WVH = BitcastV.get();
48   BitcastV->replaceAllUsesWith(ConstantV);
49   EXPECT_EQ(WVH, BitcastV.get());
50   BitcastV.reset();
51   EXPECT_EQ(WVH, nullptr);
52 }
53 
TEST_F(ValueHandle,WeakTrackingVH_BasicOperation)54 TEST_F(ValueHandle, WeakTrackingVH_BasicOperation) {
55   WeakTrackingVH WVH(BitcastV.get());
56   EXPECT_EQ(BitcastV.get(), WVH);
57   WVH = ConstantV;
58   EXPECT_EQ(ConstantV, WVH);
59 
60   // Make sure I can call a method on the underlying Value.  It
61   // doesn't matter which method.
62   EXPECT_EQ(Type::getInt32Ty(Context), WVH->getType());
63   EXPECT_EQ(Type::getInt32Ty(Context), (*WVH).getType());
64 }
65 
TEST_F(ValueHandle,WeakTrackingVH_Comparisons)66 TEST_F(ValueHandle, WeakTrackingVH_Comparisons) {
67   WeakTrackingVH BitcastWVH(BitcastV.get());
68   WeakTrackingVH ConstantWVH(ConstantV);
69 
70   EXPECT_TRUE(BitcastWVH == BitcastWVH);
71   EXPECT_TRUE(BitcastV.get() == BitcastWVH);
72   EXPECT_TRUE(BitcastWVH == BitcastV.get());
73   EXPECT_FALSE(BitcastWVH == ConstantWVH);
74 
75   EXPECT_TRUE(BitcastWVH != ConstantWVH);
76   EXPECT_TRUE(BitcastV.get() != ConstantWVH);
77   EXPECT_TRUE(BitcastWVH != ConstantV);
78   EXPECT_FALSE(BitcastWVH != BitcastWVH);
79 
80   // Cast to Value* so comparisons work.
81   Value *BV = BitcastV.get();
82   Value *CV = ConstantV;
83   EXPECT_EQ(BV < CV, BitcastWVH < ConstantWVH);
84   EXPECT_EQ(BV <= CV, BitcastWVH <= ConstantWVH);
85   EXPECT_EQ(BV > CV, BitcastWVH > ConstantWVH);
86   EXPECT_EQ(BV >= CV, BitcastWVH >= ConstantWVH);
87 
88   EXPECT_EQ(BV < CV, BitcastV.get() < ConstantWVH);
89   EXPECT_EQ(BV <= CV, BitcastV.get() <= ConstantWVH);
90   EXPECT_EQ(BV > CV, BitcastV.get() > ConstantWVH);
91   EXPECT_EQ(BV >= CV, BitcastV.get() >= ConstantWVH);
92 
93   EXPECT_EQ(BV < CV, BitcastWVH < ConstantV);
94   EXPECT_EQ(BV <= CV, BitcastWVH <= ConstantV);
95   EXPECT_EQ(BV > CV, BitcastWVH > ConstantV);
96   EXPECT_EQ(BV >= CV, BitcastWVH >= ConstantV);
97 }
98 
TEST_F(ValueHandle,WeakTrackingVH_FollowsRAUW)99 TEST_F(ValueHandle, WeakTrackingVH_FollowsRAUW) {
100   WeakTrackingVH WVH(BitcastV.get());
101   WeakTrackingVH WVH_Copy(WVH);
102   WeakTrackingVH WVH_Recreated(BitcastV.get());
103   BitcastV->replaceAllUsesWith(ConstantV);
104   EXPECT_EQ(ConstantV, WVH);
105   EXPECT_EQ(ConstantV, WVH_Copy);
106   EXPECT_EQ(ConstantV, WVH_Recreated);
107 }
108 
TEST_F(ValueHandle,WeakTrackingVH_NullOnDeletion)109 TEST_F(ValueHandle, WeakTrackingVH_NullOnDeletion) {
110   WeakTrackingVH WVH(BitcastV.get());
111   WeakTrackingVH WVH_Copy(WVH);
112   WeakTrackingVH WVH_Recreated(BitcastV.get());
113   BitcastV.reset();
114   Value *null_value = nullptr;
115   EXPECT_EQ(null_value, WVH);
116   EXPECT_EQ(null_value, WVH_Copy);
117   EXPECT_EQ(null_value, WVH_Recreated);
118 }
119 
120 
TEST_F(ValueHandle,AssertingVH_BasicOperation)121 TEST_F(ValueHandle, AssertingVH_BasicOperation) {
122   AssertingVH<CastInst> AVH(BitcastV.get());
123   CastInst *implicit_to_exact_type = AVH;
124   (void)implicit_to_exact_type;  // Avoid warning.
125 
126   AssertingVH<Value> GenericAVH(BitcastV.get());
127   EXPECT_EQ(BitcastV.get(), GenericAVH);
128   GenericAVH = ConstantV;
129   EXPECT_EQ(ConstantV, GenericAVH);
130 
131   // Make sure I can call a method on the underlying CastInst.  It
132   // doesn't matter which method.
133   EXPECT_FALSE(AVH->mayWriteToMemory());
134   EXPECT_FALSE((*AVH).mayWriteToMemory());
135 }
136 
TEST_F(ValueHandle,AssertingVH_Const)137 TEST_F(ValueHandle, AssertingVH_Const) {
138   const CastInst *ConstBitcast = BitcastV.get();
139   AssertingVH<const CastInst> AVH(ConstBitcast);
140   const CastInst *implicit_to_exact_type = AVH;
141   (void)implicit_to_exact_type;  // Avoid warning.
142 }
143 
TEST_F(ValueHandle,AssertingVH_Comparisons)144 TEST_F(ValueHandle, AssertingVH_Comparisons) {
145   AssertingVH<Value> BitcastAVH(BitcastV.get());
146   AssertingVH<Value> ConstantAVH(ConstantV);
147 
148   EXPECT_TRUE(BitcastAVH == BitcastAVH);
149   EXPECT_TRUE(BitcastV.get() == BitcastAVH);
150   EXPECT_TRUE(BitcastAVH == BitcastV.get());
151   EXPECT_FALSE(BitcastAVH == ConstantAVH);
152 
153   EXPECT_TRUE(BitcastAVH != ConstantAVH);
154   EXPECT_TRUE(BitcastV.get() != ConstantAVH);
155   EXPECT_TRUE(BitcastAVH != ConstantV);
156   EXPECT_FALSE(BitcastAVH != BitcastAVH);
157 
158   // Cast to Value* so comparisons work.
159   Value *BV = BitcastV.get();
160   Value *CV = ConstantV;
161   EXPECT_EQ(BV < CV, BitcastAVH < ConstantAVH);
162   EXPECT_EQ(BV <= CV, BitcastAVH <= ConstantAVH);
163   EXPECT_EQ(BV > CV, BitcastAVH > ConstantAVH);
164   EXPECT_EQ(BV >= CV, BitcastAVH >= ConstantAVH);
165 
166   EXPECT_EQ(BV < CV, BitcastV.get() < ConstantAVH);
167   EXPECT_EQ(BV <= CV, BitcastV.get() <= ConstantAVH);
168   EXPECT_EQ(BV > CV, BitcastV.get() > ConstantAVH);
169   EXPECT_EQ(BV >= CV, BitcastV.get() >= ConstantAVH);
170 
171   EXPECT_EQ(BV < CV, BitcastAVH < ConstantV);
172   EXPECT_EQ(BV <= CV, BitcastAVH <= ConstantV);
173   EXPECT_EQ(BV > CV, BitcastAVH > ConstantV);
174   EXPECT_EQ(BV >= CV, BitcastAVH >= ConstantV);
175 }
176 
TEST_F(ValueHandle,AssertingVH_DoesNotFollowRAUW)177 TEST_F(ValueHandle, AssertingVH_DoesNotFollowRAUW) {
178   AssertingVH<Value> AVH(BitcastV.get());
179   BitcastV->replaceAllUsesWith(ConstantV);
180   EXPECT_EQ(BitcastV.get(), AVH);
181 }
182 
183 #ifdef NDEBUG
184 
TEST_F(ValueHandle,AssertingVH_ReducesToPointer)185 TEST_F(ValueHandle, AssertingVH_ReducesToPointer) {
186   EXPECT_EQ(sizeof(CastInst *), sizeof(AssertingVH<CastInst>));
187 }
188 
189 #else  // !NDEBUG
190 
191 #ifdef GTEST_HAS_DEATH_TEST
192 
TEST_F(ValueHandle,AssertingVH_Asserts)193 TEST_F(ValueHandle, AssertingVH_Asserts) {
194   AssertingVH<Value> AVH(BitcastV.get());
195   EXPECT_DEATH({BitcastV.reset();},
196                "An asserting value handle still pointed to this value!");
197   AssertingVH<Value> Copy(AVH);
198   AVH = nullptr;
199   EXPECT_DEATH({BitcastV.reset();},
200                "An asserting value handle still pointed to this value!");
201   Copy = nullptr;
202   BitcastV.reset();
203 }
204 
205 #endif  // GTEST_HAS_DEATH_TEST
206 
207 #endif  // NDEBUG
208 
TEST_F(ValueHandle,CallbackVH_BasicOperation)209 TEST_F(ValueHandle, CallbackVH_BasicOperation) {
210   ConcreteCallbackVH CVH(BitcastV.get());
211   EXPECT_EQ(BitcastV.get(), CVH);
212   CVH = ConstantV;
213   EXPECT_EQ(ConstantV, CVH);
214 
215   // Make sure I can call a method on the underlying Value.  It
216   // doesn't matter which method.
217   EXPECT_EQ(Type::getInt32Ty(Context), CVH->getType());
218   EXPECT_EQ(Type::getInt32Ty(Context), (*CVH).getType());
219 }
220 
TEST_F(ValueHandle,CallbackVH_Comparisons)221 TEST_F(ValueHandle, CallbackVH_Comparisons) {
222   ConcreteCallbackVH BitcastCVH(BitcastV.get());
223   ConcreteCallbackVH ConstantCVH(ConstantV);
224 
225   EXPECT_TRUE(BitcastCVH == BitcastCVH);
226   EXPECT_TRUE(BitcastV.get() == BitcastCVH);
227   EXPECT_TRUE(BitcastCVH == BitcastV.get());
228   EXPECT_FALSE(BitcastCVH == ConstantCVH);
229 
230   EXPECT_TRUE(BitcastCVH != ConstantCVH);
231   EXPECT_TRUE(BitcastV.get() != ConstantCVH);
232   EXPECT_TRUE(BitcastCVH != ConstantV);
233   EXPECT_FALSE(BitcastCVH != BitcastCVH);
234 
235   // Cast to Value* so comparisons work.
236   Value *BV = BitcastV.get();
237   Value *CV = ConstantV;
238   EXPECT_EQ(BV < CV, BitcastCVH < ConstantCVH);
239   EXPECT_EQ(BV <= CV, BitcastCVH <= ConstantCVH);
240   EXPECT_EQ(BV > CV, BitcastCVH > ConstantCVH);
241   EXPECT_EQ(BV >= CV, BitcastCVH >= ConstantCVH);
242 
243   EXPECT_EQ(BV < CV, BitcastV.get() < ConstantCVH);
244   EXPECT_EQ(BV <= CV, BitcastV.get() <= ConstantCVH);
245   EXPECT_EQ(BV > CV, BitcastV.get() > ConstantCVH);
246   EXPECT_EQ(BV >= CV, BitcastV.get() >= ConstantCVH);
247 
248   EXPECT_EQ(BV < CV, BitcastCVH < ConstantV);
249   EXPECT_EQ(BV <= CV, BitcastCVH <= ConstantV);
250   EXPECT_EQ(BV > CV, BitcastCVH > ConstantV);
251   EXPECT_EQ(BV >= CV, BitcastCVH >= ConstantV);
252 }
253 
TEST_F(ValueHandle,CallbackVH_CallbackOnDeletion)254 TEST_F(ValueHandle, CallbackVH_CallbackOnDeletion) {
255   class RecordingVH final : public CallbackVH {
256   public:
257     int DeletedCalls;
258     int AURWCalls;
259 
260     RecordingVH() : DeletedCalls(0), AURWCalls(0) {}
261     RecordingVH(Value *V) : CallbackVH(V), DeletedCalls(0), AURWCalls(0) {}
262 
263   private:
264     void deleted() override {
265       DeletedCalls++;
266       CallbackVH::deleted();
267     }
268     void allUsesReplacedWith(Value *) override { AURWCalls++; }
269   };
270 
271   RecordingVH RVH;
272   RVH = BitcastV.get();
273   EXPECT_EQ(0, RVH.DeletedCalls);
274   EXPECT_EQ(0, RVH.AURWCalls);
275   BitcastV.reset();
276   EXPECT_EQ(1, RVH.DeletedCalls);
277   EXPECT_EQ(0, RVH.AURWCalls);
278 }
279 
TEST_F(ValueHandle,CallbackVH_CallbackOnRAUW)280 TEST_F(ValueHandle, CallbackVH_CallbackOnRAUW) {
281   class RecordingVH final : public CallbackVH {
282   public:
283     int DeletedCalls;
284     Value *AURWArgument;
285 
286     RecordingVH() : DeletedCalls(0), AURWArgument(nullptr) {}
287     RecordingVH(Value *V)
288       : CallbackVH(V), DeletedCalls(0), AURWArgument(nullptr) {}
289 
290   private:
291     void deleted() override {
292       DeletedCalls++;
293       CallbackVH::deleted();
294     }
295     void allUsesReplacedWith(Value *new_value) override {
296       EXPECT_EQ(nullptr, AURWArgument);
297       AURWArgument = new_value;
298     }
299   };
300 
301   RecordingVH RVH;
302   RVH = BitcastV.get();
303   EXPECT_EQ(0, RVH.DeletedCalls);
304   EXPECT_EQ(nullptr, RVH.AURWArgument);
305   BitcastV->replaceAllUsesWith(ConstantV);
306   EXPECT_EQ(0, RVH.DeletedCalls);
307   EXPECT_EQ(ConstantV, RVH.AURWArgument);
308 }
309 
TEST_F(ValueHandle,CallbackVH_DeletionCanRAUW)310 TEST_F(ValueHandle, CallbackVH_DeletionCanRAUW) {
311   class RecoveringVH final : public CallbackVH {
312   public:
313     int DeletedCalls;
314     Value *AURWArgument;
315     LLVMContext *Context;
316 
317     RecoveringVH(LLVMContext &TheContext)
318         : DeletedCalls(0), AURWArgument(nullptr), Context(&TheContext) {}
319 
320     RecoveringVH(LLVMContext &TheContext, Value *V)
321         : CallbackVH(V), DeletedCalls(0), AURWArgument(nullptr),
322           Context(&TheContext) {}
323 
324   private:
325     void deleted() override {
326       getValPtr()->replaceAllUsesWith(
327           Constant::getNullValue(Type::getInt32Ty(*Context)));
328       setValPtr(nullptr);
329     }
330     void allUsesReplacedWith(Value *new_value) override {
331       ASSERT_TRUE(nullptr != getValPtr());
332       EXPECT_EQ(1U, getValPtr()->getNumUses());
333       EXPECT_EQ(nullptr, AURWArgument);
334       AURWArgument = new_value;
335     }
336   };
337 
338   // Normally, if a value has uses, deleting it will crash.  However, we can use
339   // a CallbackVH to remove the uses before the check for no uses.
340   RecoveringVH RVH(Context);
341   RVH = RecoveringVH(Context, BitcastV.get());
342   std::unique_ptr<BinaryOperator> BitcastUser(BinaryOperator::CreateAdd(
343       RVH, Constant::getNullValue(Type::getInt32Ty(Context))));
344   EXPECT_EQ(BitcastV.get(), BitcastUser->getOperand(0));
345   BitcastV.reset();  // Would crash without the ValueHandler.
346   EXPECT_EQ(Constant::getNullValue(Type::getInt32Ty(Context)),
347             RVH.AURWArgument);
348   EXPECT_EQ(Constant::getNullValue(Type::getInt32Ty(Context)),
349             BitcastUser->getOperand(0));
350 }
351 
TEST_F(ValueHandle,DestroyingOtherVHOnSameValueDoesntBreakIteration)352 TEST_F(ValueHandle, DestroyingOtherVHOnSameValueDoesntBreakIteration) {
353   // When a CallbackVH modifies other ValueHandles in its callbacks,
354   // that shouldn't interfere with non-modified ValueHandles receiving
355   // their appropriate callbacks.
356   //
357   // We create the active CallbackVH in the middle of a palindromic
358   // arrangement of other VHs so that the bad behavior would be
359   // triggered in whichever order callbacks run.
360 
361   class DestroyingVH final : public CallbackVH {
362   public:
363     std::unique_ptr<WeakTrackingVH> ToClear[2];
364     DestroyingVH(Value *V) {
365       ToClear[0].reset(new WeakTrackingVH(V));
366       setValPtr(V);
367       ToClear[1].reset(new WeakTrackingVH(V));
368     }
369     void deleted() override {
370       ToClear[0].reset();
371       ToClear[1].reset();
372       CallbackVH::deleted();
373     }
374     void allUsesReplacedWith(Value *) override {
375       ToClear[0].reset();
376       ToClear[1].reset();
377     }
378   };
379 
380   {
381     WeakTrackingVH ShouldBeVisited1(BitcastV.get());
382     DestroyingVH C(BitcastV.get());
383     WeakTrackingVH ShouldBeVisited2(BitcastV.get());
384 
385     BitcastV->replaceAllUsesWith(ConstantV);
386     EXPECT_EQ(ConstantV, static_cast<Value*>(ShouldBeVisited1));
387     EXPECT_EQ(ConstantV, static_cast<Value*>(ShouldBeVisited2));
388   }
389 
390   {
391     WeakTrackingVH ShouldBeVisited1(BitcastV.get());
392     DestroyingVH C(BitcastV.get());
393     WeakTrackingVH ShouldBeVisited2(BitcastV.get());
394 
395     BitcastV.reset();
396     EXPECT_EQ(nullptr, static_cast<Value*>(ShouldBeVisited1));
397     EXPECT_EQ(nullptr, static_cast<Value*>(ShouldBeVisited2));
398   }
399 }
400 
TEST_F(ValueHandle,AssertingVHCheckedLast)401 TEST_F(ValueHandle, AssertingVHCheckedLast) {
402   // If a CallbackVH exists to clear out a group of AssertingVHs on
403   // Value deletion, the CallbackVH should get a chance to do so
404   // before the AssertingVHs assert.
405 
406   class ClearingVH final : public CallbackVH {
407   public:
408     AssertingVH<Value> *ToClear[2];
409     ClearingVH(Value *V,
410                AssertingVH<Value> &A0, AssertingVH<Value> &A1)
411       : CallbackVH(V) {
412       ToClear[0] = &A0;
413       ToClear[1] = &A1;
414     }
415 
416     void deleted() override {
417       *ToClear[0] = nullptr;
418       *ToClear[1] = nullptr;
419       CallbackVH::deleted();
420     }
421   };
422 
423   AssertingVH<Value> A1, A2;
424   A1 = BitcastV.get();
425   ClearingVH C(BitcastV.get(), A1, A2);
426   A2 = BitcastV.get();
427   // C.deleted() should run first, clearing the two AssertingVHs,
428   // which should prevent them from asserting.
429   BitcastV.reset();
430 }
431 
TEST_F(ValueHandle,PoisoningVH_BasicOperation)432 TEST_F(ValueHandle, PoisoningVH_BasicOperation) {
433   PoisoningVH<CastInst> VH(BitcastV.get());
434   CastInst *implicit_to_exact_type = VH;
435   (void)implicit_to_exact_type; // Avoid warning.
436 
437   PoisoningVH<Value> GenericVH(BitcastV.get());
438   EXPECT_EQ(BitcastV.get(), GenericVH);
439   GenericVH = ConstantV;
440   EXPECT_EQ(ConstantV, GenericVH);
441 
442   // Make sure I can call a method on the underlying CastInst.  It
443   // doesn't matter which method.
444   EXPECT_FALSE(VH->mayWriteToMemory());
445   EXPECT_FALSE((*VH).mayWriteToMemory());
446 }
447 
TEST_F(ValueHandle,PoisoningVH_Const)448 TEST_F(ValueHandle, PoisoningVH_Const) {
449   const CastInst *ConstBitcast = BitcastV.get();
450   PoisoningVH<const CastInst> VH(ConstBitcast);
451   const CastInst *implicit_to_exact_type = VH;
452   (void)implicit_to_exact_type; // Avoid warning.
453 }
454 
TEST_F(ValueHandle,PoisoningVH_Comparisons)455 TEST_F(ValueHandle, PoisoningVH_Comparisons) {
456   PoisoningVH<Value> BitcastVH(BitcastV.get());
457   PoisoningVH<Value> ConstantVH(ConstantV);
458 
459   EXPECT_TRUE(BitcastVH == BitcastVH);
460   EXPECT_TRUE(BitcastV.get() == BitcastVH);
461   EXPECT_TRUE(BitcastVH == BitcastV.get());
462   EXPECT_FALSE(BitcastVH == ConstantVH);
463 
464   EXPECT_TRUE(BitcastVH != ConstantVH);
465   EXPECT_TRUE(BitcastV.get() != ConstantVH);
466   EXPECT_TRUE(BitcastVH != ConstantV);
467   EXPECT_FALSE(BitcastVH != BitcastVH);
468 
469   // Cast to Value* so comparisons work.
470   Value *BV = BitcastV.get();
471   Value *CV = ConstantV;
472   EXPECT_EQ(BV < CV, BitcastVH < ConstantVH);
473   EXPECT_EQ(BV <= CV, BitcastVH <= ConstantVH);
474   EXPECT_EQ(BV > CV, BitcastVH > ConstantVH);
475   EXPECT_EQ(BV >= CV, BitcastVH >= ConstantVH);
476 
477   EXPECT_EQ(BV < CV, BitcastV.get() < ConstantVH);
478   EXPECT_EQ(BV <= CV, BitcastV.get() <= ConstantVH);
479   EXPECT_EQ(BV > CV, BitcastV.get() > ConstantVH);
480   EXPECT_EQ(BV >= CV, BitcastV.get() >= ConstantVH);
481 
482   EXPECT_EQ(BV < CV, BitcastVH < ConstantV);
483   EXPECT_EQ(BV <= CV, BitcastVH <= ConstantV);
484   EXPECT_EQ(BV > CV, BitcastVH > ConstantV);
485   EXPECT_EQ(BV >= CV, BitcastVH >= ConstantV);
486 }
487 
TEST_F(ValueHandle,PoisoningVH_DoesNotFollowRAUW)488 TEST_F(ValueHandle, PoisoningVH_DoesNotFollowRAUW) {
489   PoisoningVH<Value> VH(BitcastV.get());
490   BitcastV->replaceAllUsesWith(ConstantV);
491   EXPECT_TRUE(DenseMapInfo<PoisoningVH<Value>>::isEqual(VH, BitcastV.get()));
492 }
493 
TEST_F(ValueHandle,AssertingVH_DenseMap)494 TEST_F(ValueHandle, AssertingVH_DenseMap) {
495   DenseMap<AssertingVH<Value>, int> Map;
496   Map.insert({BitcastV.get(), 1});
497   Map.insert({ConstantV, 2});
498   // These will create a temporary AssertingVH during lookup.
499   EXPECT_TRUE(Map.find(BitcastV.get()) != Map.end());
500   EXPECT_TRUE(Map.find(ConstantV) != Map.end());
501   // These will not create a temporary AssertingVH.
502   EXPECT_TRUE(Map.find_as(BitcastV.get()) != Map.end());
503   EXPECT_TRUE(Map.find_as(ConstantV) != Map.end());
504 }
505 
TEST_F(ValueHandle,PoisoningVH_DenseMap)506 TEST_F(ValueHandle, PoisoningVH_DenseMap) {
507   DenseMap<PoisoningVH<Value>, int> Map;
508   Map.insert({BitcastV.get(), 1});
509   Map.insert({ConstantV, 2});
510   // These will create a temporary PoisoningVH during lookup.
511   EXPECT_TRUE(Map.find(BitcastV.get()) != Map.end());
512   EXPECT_TRUE(Map.find(ConstantV) != Map.end());
513   // These will not create a temporary PoisoningVH.
514   EXPECT_TRUE(Map.find_as(BitcastV.get()) != Map.end());
515   EXPECT_TRUE(Map.find_as(ConstantV) != Map.end());
516 }
517 
518 #ifdef NDEBUG
519 
TEST_F(ValueHandle,PoisoningVH_ReducesToPointer)520 TEST_F(ValueHandle, PoisoningVH_ReducesToPointer) {
521   EXPECT_EQ(sizeof(CastInst *), sizeof(PoisoningVH<CastInst>));
522 }
523 
524 #else // !NDEBUG
525 
TEST_F(ValueHandle,TrackingVH_Tracks)526 TEST_F(ValueHandle, TrackingVH_Tracks) {
527   TrackingVH<Value> VH(BitcastV.get());
528   BitcastV->replaceAllUsesWith(ConstantV);
529   EXPECT_EQ(VH, ConstantV);
530 }
531 
532 #ifdef GTEST_HAS_DEATH_TEST
533 
TEST_F(ValueHandle,PoisoningVH_Asserts)534 TEST_F(ValueHandle, PoisoningVH_Asserts) {
535   PoisoningVH<Value> VH(BitcastV.get());
536 
537   // The poisoned handle shouldn't assert when the value is deleted.
538   BitcastV.reset(new BitCastInst(ConstantV, Type::getInt32Ty(Context)));
539   // But should when we access the handle.
540   EXPECT_DEATH((void)*VH, "Accessed a poisoned value handle!");
541 
542   // Now check that poison catches RAUW.
543   VH = BitcastV.get();
544   // The replace doesn't trigger anything immediately.
545   BitcastV->replaceAllUsesWith(ConstantV);
546   // But a use does.
547   EXPECT_DEATH((void)*VH, "Accessed a poisoned value handle!");
548 
549   // Don't clear anything out here as destroying the handles should be fine.
550 }
551 
TEST_F(ValueHandle,TrackingVH_Asserts)552 TEST_F(ValueHandle, TrackingVH_Asserts) {
553   {
554     TrackingVH<Value> VH(BitcastV.get());
555 
556     // The tracking handle shouldn't assert when the value is deleted.
557     BitcastV.reset(new BitCastInst(ConstantV, Type::getInt32Ty(Context)));
558     // But should when we access the handle.
559     EXPECT_DEATH((void)*VH,
560                  "TrackingVH must be non-null and valid on dereference!");
561   }
562 
563   {
564     TrackingVH<Instruction> VH(BitcastV.get());
565 
566     BitcastV->replaceAllUsesWith(ConstantV);
567     EXPECT_DEATH((void)*VH,
568                  "Tracked Value was replaced by one with an invalid type!");
569   }
570 }
571 
572 #endif // GTEST_HAS_DEATH_TEST
573 
574 #endif // NDEBUG
575 }
576