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