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