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 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: 33 ConcreteCallbackVH(Value *V) : CallbackVH(V) {} 34 }; 35 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 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 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 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 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 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 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 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 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 185 TEST_F(ValueHandle, AssertingVH_ReducesToPointer) { 186 EXPECT_EQ(sizeof(CastInst *), sizeof(AssertingVH<CastInst>)); 187 } 188 189 #elif LLVM_ENABLE_ABI_BREAKING_CHECKS // && !NDEBUG 190 191 #ifdef GTEST_HAS_DEATH_TEST 192 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 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 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 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 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 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 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 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 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 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 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 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 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 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 520 TEST_F(ValueHandle, PoisoningVH_ReducesToPointer) { 521 EXPECT_EQ(sizeof(CastInst *), sizeof(PoisoningVH<CastInst>)); 522 } 523 524 #else // !NDEBUG 525 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 #if LLVM_ENABLE_ABI_BREAKING_CHECKS 534 535 TEST_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_CHECKS 554 555 TEST_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_TEST 576 577 #endif // NDEBUG 578 } 579