brintos

brintos / llvm-project-archived public Read only

0
0
Text · 17.8 KiB · 0d4d0e2 Raw
579 lines · cpp
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-exception6//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 16using namespace llvm;17 18namespace {19 20class ValueHandle : public testing::Test {21protected:22  LLVMContext Context;23  Constant *ConstantV;24  std::unique_ptr<BitCastInst> BitcastV;25 26  ValueHandle()27      : ConstantV(ConstantInt::get(Type::getInt32Ty(Context), 0)),28        BitcastV(new BitCastInst(ConstantV, Type::getInt32Ty(Context))) {}29};30 31class ConcreteCallbackVH final : public CallbackVH {32public:33  ConcreteCallbackVH(Value *V) : CallbackVH(V) {}34};35 36TEST_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.  It43  // 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 54TEST_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.  It61  // doesn't matter which method.62  EXPECT_EQ(Type::getInt32Ty(Context), WVH->getType());63  EXPECT_EQ(Type::getInt32Ty(Context), (*WVH).getType());64}65 66TEST_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 99TEST_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 109TEST_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 121TEST_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.  It132  // doesn't matter which method.133  EXPECT_FALSE(AVH->mayWriteToMemory());134  EXPECT_FALSE((*AVH).mayWriteToMemory());135}136 137TEST_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 144TEST_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 177TEST_F(ValueHandle, AssertingVH_DoesNotFollowRAUW) {178  AssertingVH<Value> AVH(BitcastV.get());179  BitcastV->replaceAllUsesWith(ConstantV);180  EXPECT_EQ(BitcastV.get(), AVH);181}182 183#ifdef NDEBUG184 185TEST_F(ValueHandle, AssertingVH_ReducesToPointer) {186  EXPECT_EQ(sizeof(CastInst *), sizeof(AssertingVH<CastInst>));187}188 189#elif LLVM_ENABLE_ABI_BREAKING_CHECKS // && !NDEBUG190 191#ifdef GTEST_HAS_DEATH_TEST192 193TEST_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_TEST206 207#endif  // NDEBUG208 209TEST_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.  It216  // doesn't matter which method.217  EXPECT_EQ(Type::getInt32Ty(Context), CVH->getType());218  EXPECT_EQ(Type::getInt32Ty(Context), (*CVH).getType());219}220 221TEST_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 254TEST_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 280TEST_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 310TEST_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_TRUE(getValPtr()->hasOneUse());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 use339  // 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 352TEST_F(ValueHandle, DestroyingOtherVHOnSameValueDoesntBreakIteration) {353  // When a CallbackVH modifies other ValueHandles in its callbacks,354  // that shouldn't interfere with non-modified ValueHandles receiving355  // their appropriate callbacks.356  //357  // We create the active CallbackVH in the middle of a palindromic358  // arrangement of other VHs so that the bad behavior would be359  // 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 401TEST_F(ValueHandle, AssertingVHCheckedLast) {402  // If a CallbackVH exists to clear out a group of AssertingVHs on403  // Value deletion, the CallbackVH should get a chance to do so404  // 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 432TEST_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.  It443  // doesn't matter which method.444  EXPECT_FALSE(VH->mayWriteToMemory());445  EXPECT_FALSE((*VH).mayWriteToMemory());446}447 448TEST_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 455TEST_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 488TEST_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 494TEST_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.contains(BitcastV.get()));500  EXPECT_TRUE(Map.contains(ConstantV));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 506TEST_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.contains(BitcastV.get()));512  EXPECT_TRUE(Map.contains(ConstantV));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 NDEBUG519 520TEST_F(ValueHandle, PoisoningVH_ReducesToPointer) {521  EXPECT_EQ(sizeof(CastInst *), sizeof(PoisoningVH<CastInst>));522}523 524#else // !NDEBUG525 526TEST_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_TEST533#if LLVM_ENABLE_ABI_BREAKING_CHECKS534 535TEST_F(ValueHandle, PoisoningVH_Asserts) {536  PoisoningVH<Value> VH(BitcastV.get());537 538  // The poisoned handle shouldn't assert when the value is deleted.539  BitcastV.reset(new BitCastInst(ConstantV, Type::getInt32Ty(Context)));540  // But should when we access the handle.541  EXPECT_DEATH((void)*VH, "Accessed a poisoned value handle!");542 543  // Now check that poison catches RAUW.544  VH = BitcastV.get();545  // The replace doesn't trigger anything immediately.546  BitcastV->replaceAllUsesWith(ConstantV);547  // But a use does.548  EXPECT_DEATH((void)*VH, "Accessed a poisoned value handle!");549 550  // Don't clear anything out here as destroying the handles should be fine.551}552 553#endif // LLVM_ENABLE_ABI_BREAKING_CHECKS554 555TEST_F(ValueHandle, TrackingVH_Asserts) {556  {557    TrackingVH<Value> VH(BitcastV.get());558 559    // The tracking handle shouldn't assert when the value is deleted.560    BitcastV.reset(new BitCastInst(ConstantV, Type::getInt32Ty(Context)));561    // But should when we access the handle.562    EXPECT_DEATH((void)*VH,563                 "TrackingVH must be non-null and valid on dereference!");564  }565 566  {567    TrackingVH<Instruction> VH(BitcastV.get());568 569    BitcastV->replaceAllUsesWith(ConstantV);570    EXPECT_DEATH((void)*VH,571                 "Tracked Value was replaced by one with an invalid type!");572  }573}574 575#endif // GTEST_HAS_DEATH_TEST576 577#endif // NDEBUG578}579