136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//===- ValueHandleTest.cpp - ValueHandle tests ----------------------------===// 2487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin// 3487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin// The LLVM Compiler Infrastructure 4487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin// 5487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin// This file is distributed under the University of Illinois Open Source 6487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin// License. See LICENSE.TXT for details. 7487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin// 8487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin//===----------------------------------------------------------------------===// 9487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin 1036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/ValueHandle.h" 110b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Constants.h" 120b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Instructions.h" 130b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/LLVMContext.h" 14487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin#include "gtest/gtest.h" 15487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin#include <memory> 16487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin 17487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskinusing namespace llvm; 18487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin 19487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskinnamespace { 20487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin 21487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskinclass ValueHandle : public testing::Test { 22487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskinprotected: 23487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin Constant *ConstantV; 24487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin std::auto_ptr<BitCastInst> BitcastV; 25487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin 269adc0abad3c3ed40a268ccbcee0c74cb9e1359feOwen Anderson ValueHandle() : 271d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson ConstantV(ConstantInt::get(Type::getInt32Ty(getGlobalContext()), 0)), 281d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson BitcastV(new BitCastInst(ConstantV, Type::getInt32Ty(getGlobalContext()))) { 29487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin } 30487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin}; 31487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin 32c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohmanclass ConcreteCallbackVH : public CallbackVH { 33c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohmanpublic: 34c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman ConcreteCallbackVH(Value *V) : CallbackVH(V) {} 35c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman}; 36c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman 37487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey YasskinTEST_F(ValueHandle, WeakVH_BasicOperation) { 38487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin WeakVH WVH(BitcastV.get()); 39487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin EXPECT_EQ(BitcastV.get(), WVH); 40487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin WVH = ConstantV; 41487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin EXPECT_EQ(ConstantV, WVH); 42487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin 43487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin // Make sure I can call a method on the underlying Value. It 44487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin // doesn't matter which method. 451d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson EXPECT_EQ(Type::getInt32Ty(getGlobalContext()), WVH->getType()); 461d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson EXPECT_EQ(Type::getInt32Ty(getGlobalContext()), (*WVH).getType()); 47487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin} 48487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin 49487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey YasskinTEST_F(ValueHandle, WeakVH_Comparisons) { 50487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin WeakVH BitcastWVH(BitcastV.get()); 51487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin WeakVH ConstantWVH(ConstantV); 52487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin 53487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin EXPECT_TRUE(BitcastWVH == BitcastWVH); 54487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin EXPECT_TRUE(BitcastV.get() == BitcastWVH); 55487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin EXPECT_TRUE(BitcastWVH == BitcastV.get()); 56487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin EXPECT_FALSE(BitcastWVH == ConstantWVH); 57487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin 58487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin EXPECT_TRUE(BitcastWVH != ConstantWVH); 59487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin EXPECT_TRUE(BitcastV.get() != ConstantWVH); 60487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin EXPECT_TRUE(BitcastWVH != ConstantV); 61487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin EXPECT_FALSE(BitcastWVH != BitcastWVH); 62487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin 63487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin // Cast to Value* so comparisons work. 64487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin Value *BV = BitcastV.get(); 65487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin Value *CV = ConstantV; 66487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin EXPECT_EQ(BV < CV, BitcastWVH < ConstantWVH); 67487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin EXPECT_EQ(BV <= CV, BitcastWVH <= ConstantWVH); 68487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin EXPECT_EQ(BV > CV, BitcastWVH > ConstantWVH); 69487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin EXPECT_EQ(BV >= CV, BitcastWVH >= ConstantWVH); 70487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin 71487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin EXPECT_EQ(BV < CV, BitcastV.get() < ConstantWVH); 72487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin EXPECT_EQ(BV <= CV, BitcastV.get() <= ConstantWVH); 73487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin EXPECT_EQ(BV > CV, BitcastV.get() > ConstantWVH); 74487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin EXPECT_EQ(BV >= CV, BitcastV.get() >= ConstantWVH); 75487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin 76487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin EXPECT_EQ(BV < CV, BitcastWVH < ConstantV); 77487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin EXPECT_EQ(BV <= CV, BitcastWVH <= ConstantV); 78487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin EXPECT_EQ(BV > CV, BitcastWVH > ConstantV); 79487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin EXPECT_EQ(BV >= CV, BitcastWVH >= ConstantV); 80487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin} 81487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin 82487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey YasskinTEST_F(ValueHandle, WeakVH_FollowsRAUW) { 83487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin WeakVH WVH(BitcastV.get()); 84487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin WeakVH WVH_Copy(WVH); 85487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin WeakVH WVH_Recreated(BitcastV.get()); 86487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin BitcastV->replaceAllUsesWith(ConstantV); 87487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin EXPECT_EQ(ConstantV, WVH); 88487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin EXPECT_EQ(ConstantV, WVH_Copy); 89487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin EXPECT_EQ(ConstantV, WVH_Recreated); 90487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin} 91487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin 92487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey YasskinTEST_F(ValueHandle, WeakVH_NullOnDeletion) { 93487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin WeakVH WVH(BitcastV.get()); 94487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin WeakVH WVH_Copy(WVH); 95487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin WeakVH WVH_Recreated(BitcastV.get()); 96487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin BitcastV.reset(); 97cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Value *null_value = nullptr; 98487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin EXPECT_EQ(null_value, WVH); 99487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin EXPECT_EQ(null_value, WVH_Copy); 100487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin EXPECT_EQ(null_value, WVH_Recreated); 101487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin} 102487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin 103487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin 104487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey YasskinTEST_F(ValueHandle, AssertingVH_BasicOperation) { 105487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin AssertingVH<CastInst> AVH(BitcastV.get()); 106487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin CastInst *implicit_to_exact_type = AVH; 1078e68c3873549ca31533e2e3e40dda3a43cb79566Jeffrey Yasskin (void)implicit_to_exact_type; // Avoid warning. 108487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin 109487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin AssertingVH<Value> GenericAVH(BitcastV.get()); 110487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin EXPECT_EQ(BitcastV.get(), GenericAVH); 111487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin GenericAVH = ConstantV; 112487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin EXPECT_EQ(ConstantV, GenericAVH); 113487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin 114487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin // Make sure I can call a method on the underlying CastInst. It 115487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin // doesn't matter which method. 116487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin EXPECT_FALSE(AVH->mayWriteToMemory()); 117487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin EXPECT_FALSE((*AVH).mayWriteToMemory()); 118487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin} 119487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin 1200d5bd59553375dc85ac04c81ef48ef74c9e7193eJeffrey YasskinTEST_F(ValueHandle, AssertingVH_Const) { 1210d5bd59553375dc85ac04c81ef48ef74c9e7193eJeffrey Yasskin const CastInst *ConstBitcast = BitcastV.get(); 1220d5bd59553375dc85ac04c81ef48ef74c9e7193eJeffrey Yasskin AssertingVH<const CastInst> AVH(ConstBitcast); 1230d5bd59553375dc85ac04c81ef48ef74c9e7193eJeffrey Yasskin const CastInst *implicit_to_exact_type = AVH; 1248e68c3873549ca31533e2e3e40dda3a43cb79566Jeffrey Yasskin (void)implicit_to_exact_type; // Avoid warning. 1250d5bd59553375dc85ac04c81ef48ef74c9e7193eJeffrey Yasskin} 1260d5bd59553375dc85ac04c81ef48ef74c9e7193eJeffrey Yasskin 127487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey YasskinTEST_F(ValueHandle, AssertingVH_Comparisons) { 128487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin AssertingVH<Value> BitcastAVH(BitcastV.get()); 129487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin AssertingVH<Value> ConstantAVH(ConstantV); 130487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin 131487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin EXPECT_TRUE(BitcastAVH == BitcastAVH); 132487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin EXPECT_TRUE(BitcastV.get() == BitcastAVH); 133487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin EXPECT_TRUE(BitcastAVH == BitcastV.get()); 134487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin EXPECT_FALSE(BitcastAVH == ConstantAVH); 135487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin 136487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin EXPECT_TRUE(BitcastAVH != ConstantAVH); 137487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin EXPECT_TRUE(BitcastV.get() != ConstantAVH); 138487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin EXPECT_TRUE(BitcastAVH != ConstantV); 139487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin EXPECT_FALSE(BitcastAVH != BitcastAVH); 140487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin 141487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin // Cast to Value* so comparisons work. 142487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin Value *BV = BitcastV.get(); 143487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin Value *CV = ConstantV; 144487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin EXPECT_EQ(BV < CV, BitcastAVH < ConstantAVH); 145487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin EXPECT_EQ(BV <= CV, BitcastAVH <= ConstantAVH); 146487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin EXPECT_EQ(BV > CV, BitcastAVH > ConstantAVH); 147487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin EXPECT_EQ(BV >= CV, BitcastAVH >= ConstantAVH); 148487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin 149487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin EXPECT_EQ(BV < CV, BitcastV.get() < ConstantAVH); 150487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin EXPECT_EQ(BV <= CV, BitcastV.get() <= ConstantAVH); 151487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin EXPECT_EQ(BV > CV, BitcastV.get() > ConstantAVH); 152487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin EXPECT_EQ(BV >= CV, BitcastV.get() >= ConstantAVH); 153487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin 154487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin EXPECT_EQ(BV < CV, BitcastAVH < ConstantV); 155487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin EXPECT_EQ(BV <= CV, BitcastAVH <= ConstantV); 156487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin EXPECT_EQ(BV > CV, BitcastAVH > ConstantV); 157487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin EXPECT_EQ(BV >= CV, BitcastAVH >= ConstantV); 158487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin} 159487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin 160487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey YasskinTEST_F(ValueHandle, AssertingVH_DoesNotFollowRAUW) { 161487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin AssertingVH<Value> AVH(BitcastV.get()); 162487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin BitcastV->replaceAllUsesWith(ConstantV); 163487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin EXPECT_EQ(BitcastV.get(), AVH); 164487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin} 165487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin 166487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin#ifdef NDEBUG 167487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin 168487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey YasskinTEST_F(ValueHandle, AssertingVH_ReducesToPointer) { 169487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin EXPECT_EQ(sizeof(CastInst *), sizeof(AssertingVH<CastInst>)); 170487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin} 171487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin 172487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin#else // !NDEBUG 173487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin 174487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin#ifdef GTEST_HAS_DEATH_TEST 175487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin 176487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey YasskinTEST_F(ValueHandle, AssertingVH_Asserts) { 177487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin AssertingVH<Value> AVH(BitcastV.get()); 178487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin EXPECT_DEATH({BitcastV.reset();}, 179487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin "An asserting value handle still pointed to this value!"); 180487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin AssertingVH<Value> Copy(AVH); 181cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines AVH = nullptr; 182487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin EXPECT_DEATH({BitcastV.reset();}, 183487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin "An asserting value handle still pointed to this value!"); 184cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Copy = nullptr; 185487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin BitcastV.reset(); 186487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin} 187487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin 188487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin#endif // GTEST_HAS_DEATH_TEST 189487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin 190487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin#endif // NDEBUG 191487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin 192c09b12c62208f09de9d107b320f5420ae6e4fc38Dan GohmanTEST_F(ValueHandle, CallbackVH_BasicOperation) { 193c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman ConcreteCallbackVH CVH(BitcastV.get()); 194c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman EXPECT_EQ(BitcastV.get(), CVH); 195c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman CVH = ConstantV; 196c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman EXPECT_EQ(ConstantV, CVH); 197c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman 198c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman // Make sure I can call a method on the underlying Value. It 199c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman // doesn't matter which method. 2001d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson EXPECT_EQ(Type::getInt32Ty(getGlobalContext()), CVH->getType()); 2011d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson EXPECT_EQ(Type::getInt32Ty(getGlobalContext()), (*CVH).getType()); 202c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman} 203c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman 204c09b12c62208f09de9d107b320f5420ae6e4fc38Dan GohmanTEST_F(ValueHandle, CallbackVH_Comparisons) { 205c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman ConcreteCallbackVH BitcastCVH(BitcastV.get()); 206c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman ConcreteCallbackVH ConstantCVH(ConstantV); 207c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman 208c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman EXPECT_TRUE(BitcastCVH == BitcastCVH); 209c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman EXPECT_TRUE(BitcastV.get() == BitcastCVH); 210c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman EXPECT_TRUE(BitcastCVH == BitcastV.get()); 211c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman EXPECT_FALSE(BitcastCVH == ConstantCVH); 212c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman 213c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman EXPECT_TRUE(BitcastCVH != ConstantCVH); 214c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman EXPECT_TRUE(BitcastV.get() != ConstantCVH); 215c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman EXPECT_TRUE(BitcastCVH != ConstantV); 216c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman EXPECT_FALSE(BitcastCVH != BitcastCVH); 217c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman 218c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman // Cast to Value* so comparisons work. 219c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman Value *BV = BitcastV.get(); 220c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman Value *CV = ConstantV; 221c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman EXPECT_EQ(BV < CV, BitcastCVH < ConstantCVH); 222c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman EXPECT_EQ(BV <= CV, BitcastCVH <= ConstantCVH); 223c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman EXPECT_EQ(BV > CV, BitcastCVH > ConstantCVH); 224c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman EXPECT_EQ(BV >= CV, BitcastCVH >= ConstantCVH); 225c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman 226c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman EXPECT_EQ(BV < CV, BitcastV.get() < ConstantCVH); 227c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman EXPECT_EQ(BV <= CV, BitcastV.get() <= ConstantCVH); 228c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman EXPECT_EQ(BV > CV, BitcastV.get() > ConstantCVH); 229c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman EXPECT_EQ(BV >= CV, BitcastV.get() >= ConstantCVH); 230c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman 231c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman EXPECT_EQ(BV < CV, BitcastCVH < ConstantV); 232c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman EXPECT_EQ(BV <= CV, BitcastCVH <= ConstantV); 233c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman EXPECT_EQ(BV > CV, BitcastCVH > ConstantV); 234c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman EXPECT_EQ(BV >= CV, BitcastCVH >= ConstantV); 235c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman} 236c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman 237c09b12c62208f09de9d107b320f5420ae6e4fc38Dan GohmanTEST_F(ValueHandle, CallbackVH_CallbackOnDeletion) { 238c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman class RecordingVH : public CallbackVH { 239c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman public: 240c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman int DeletedCalls; 241c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman int AURWCalls; 242c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman 243c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman RecordingVH() : DeletedCalls(0), AURWCalls(0) {} 244c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman RecordingVH(Value *V) : CallbackVH(V), DeletedCalls(0), AURWCalls(0) {} 245c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman 246c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman private: 247c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman virtual void deleted() { DeletedCalls++; CallbackVH::deleted(); } 248c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman virtual void allUsesReplacedWith(Value *) { AURWCalls++; } 249c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman }; 250c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman 251c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman RecordingVH RVH; 252c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman RVH = BitcastV.get(); 253c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman EXPECT_EQ(0, RVH.DeletedCalls); 254c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman EXPECT_EQ(0, RVH.AURWCalls); 255c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman BitcastV.reset(); 256c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman EXPECT_EQ(1, RVH.DeletedCalls); 257c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman EXPECT_EQ(0, RVH.AURWCalls); 258c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman} 259c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman 260c09b12c62208f09de9d107b320f5420ae6e4fc38Dan GohmanTEST_F(ValueHandle, CallbackVH_CallbackOnRAUW) { 261c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman class RecordingVH : public CallbackVH { 262c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman public: 263c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman int DeletedCalls; 264c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman Value *AURWArgument; 265c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman 266cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines RecordingVH() : DeletedCalls(0), AURWArgument(nullptr) {} 267c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman RecordingVH(Value *V) 268cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines : CallbackVH(V), DeletedCalls(0), AURWArgument(nullptr) {} 269c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman 270c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman private: 271c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman virtual void deleted() { DeletedCalls++; CallbackVH::deleted(); } 272c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman virtual void allUsesReplacedWith(Value *new_value) { 273cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines EXPECT_EQ(nullptr, AURWArgument); 274c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman AURWArgument = new_value; 275c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman } 276c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman }; 277c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman 278c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman RecordingVH RVH; 279c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman RVH = BitcastV.get(); 280c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman EXPECT_EQ(0, RVH.DeletedCalls); 281cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines EXPECT_EQ(nullptr, RVH.AURWArgument); 282c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman BitcastV->replaceAllUsesWith(ConstantV); 283c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman EXPECT_EQ(0, RVH.DeletedCalls); 284c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman EXPECT_EQ(ConstantV, RVH.AURWArgument); 285c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman} 286c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman 287c09b12c62208f09de9d107b320f5420ae6e4fc38Dan GohmanTEST_F(ValueHandle, CallbackVH_DeletionCanRAUW) { 288c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman class RecoveringVH : public CallbackVH { 289c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman public: 290c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman int DeletedCalls; 291c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman Value *AURWArgument; 2920a5372ed3e8cda10d724feda3c1a1c998db05ca0Owen Anderson LLVMContext *Context; 293c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman 294cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines RecoveringVH() : DeletedCalls(0), AURWArgument(nullptr), 2950a5372ed3e8cda10d724feda3c1a1c998db05ca0Owen Anderson Context(&getGlobalContext()) {} 296c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman RecoveringVH(Value *V) 297cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines : CallbackVH(V), DeletedCalls(0), AURWArgument(nullptr), 2980a5372ed3e8cda10d724feda3c1a1c998db05ca0Owen Anderson Context(&getGlobalContext()) {} 299c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman 300c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman private: 301c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman virtual void deleted() { 3021d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson getValPtr()->replaceAllUsesWith(Constant::getNullValue(Type::getInt32Ty(getGlobalContext()))); 303cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines setValPtr(nullptr); 304c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman } 305c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman virtual void allUsesReplacedWith(Value *new_value) { 306cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ASSERT_TRUE(nullptr != getValPtr()); 3077ce55362c7c9c16646973a1bfc16674b1de56729Daniel Dunbar EXPECT_EQ(1U, getValPtr()->getNumUses()); 308cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines EXPECT_EQ(nullptr, AURWArgument); 309c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman AURWArgument = new_value; 310c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman } 311c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman }; 312c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman 313c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman // Normally, if a value has uses, deleting it will crash. However, we can use 314c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman // a CallbackVH to remove the uses before the check for no uses. 315c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman RecoveringVH RVH; 316c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman RVH = BitcastV.get(); 317c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman std::auto_ptr<BinaryOperator> BitcastUser( 3180a5372ed3e8cda10d724feda3c1a1c998db05ca0Owen Anderson BinaryOperator::CreateAdd(RVH, 3191d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson Constant::getNullValue(Type::getInt32Ty(getGlobalContext())))); 320c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman EXPECT_EQ(BitcastV.get(), BitcastUser->getOperand(0)); 321c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman BitcastV.reset(); // Would crash without the ValueHandler. 3221d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson EXPECT_EQ(Constant::getNullValue(Type::getInt32Ty(getGlobalContext())), RVH.AURWArgument); 3231d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson EXPECT_EQ(Constant::getNullValue(Type::getInt32Ty(getGlobalContext())), 3240a5372ed3e8cda10d724feda3c1a1c998db05ca0Owen Anderson BitcastUser->getOperand(0)); 325c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman} 326c09b12c62208f09de9d107b320f5420ae6e4fc38Dan Gohman 3276a9291ad55cf3b3731d3512eb5aa72ac7cdf02f9Jeffrey YasskinTEST_F(ValueHandle, DestroyingOtherVHOnSameValueDoesntBreakIteration) { 3286a9291ad55cf3b3731d3512eb5aa72ac7cdf02f9Jeffrey Yasskin // When a CallbackVH modifies other ValueHandles in its callbacks, 3296a9291ad55cf3b3731d3512eb5aa72ac7cdf02f9Jeffrey Yasskin // that shouldn't interfere with non-modified ValueHandles receiving 3306a9291ad55cf3b3731d3512eb5aa72ac7cdf02f9Jeffrey Yasskin // their appropriate callbacks. 3316a9291ad55cf3b3731d3512eb5aa72ac7cdf02f9Jeffrey Yasskin // 3326a9291ad55cf3b3731d3512eb5aa72ac7cdf02f9Jeffrey Yasskin // We create the active CallbackVH in the middle of a palindromic 3336a9291ad55cf3b3731d3512eb5aa72ac7cdf02f9Jeffrey Yasskin // arrangement of other VHs so that the bad behavior would be 3346a9291ad55cf3b3731d3512eb5aa72ac7cdf02f9Jeffrey Yasskin // triggered in whichever order callbacks run. 3356a9291ad55cf3b3731d3512eb5aa72ac7cdf02f9Jeffrey Yasskin 3366a9291ad55cf3b3731d3512eb5aa72ac7cdf02f9Jeffrey Yasskin class DestroyingVH : public CallbackVH { 3376a9291ad55cf3b3731d3512eb5aa72ac7cdf02f9Jeffrey Yasskin public: 33836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::unique_ptr<WeakVH> ToClear[2]; 3396a9291ad55cf3b3731d3512eb5aa72ac7cdf02f9Jeffrey Yasskin DestroyingVH(Value *V) { 3406a9291ad55cf3b3731d3512eb5aa72ac7cdf02f9Jeffrey Yasskin ToClear[0].reset(new WeakVH(V)); 3416a9291ad55cf3b3731d3512eb5aa72ac7cdf02f9Jeffrey Yasskin setValPtr(V); 3426a9291ad55cf3b3731d3512eb5aa72ac7cdf02f9Jeffrey Yasskin ToClear[1].reset(new WeakVH(V)); 3436a9291ad55cf3b3731d3512eb5aa72ac7cdf02f9Jeffrey Yasskin } 3446a9291ad55cf3b3731d3512eb5aa72ac7cdf02f9Jeffrey Yasskin virtual void deleted() { 3456a9291ad55cf3b3731d3512eb5aa72ac7cdf02f9Jeffrey Yasskin ToClear[0].reset(); 3466a9291ad55cf3b3731d3512eb5aa72ac7cdf02f9Jeffrey Yasskin ToClear[1].reset(); 3476a9291ad55cf3b3731d3512eb5aa72ac7cdf02f9Jeffrey Yasskin CallbackVH::deleted(); 3486a9291ad55cf3b3731d3512eb5aa72ac7cdf02f9Jeffrey Yasskin } 3496a9291ad55cf3b3731d3512eb5aa72ac7cdf02f9Jeffrey Yasskin virtual void allUsesReplacedWith(Value *) { 3506a9291ad55cf3b3731d3512eb5aa72ac7cdf02f9Jeffrey Yasskin ToClear[0].reset(); 3516a9291ad55cf3b3731d3512eb5aa72ac7cdf02f9Jeffrey Yasskin ToClear[1].reset(); 3526a9291ad55cf3b3731d3512eb5aa72ac7cdf02f9Jeffrey Yasskin } 3536a9291ad55cf3b3731d3512eb5aa72ac7cdf02f9Jeffrey Yasskin }; 3546a9291ad55cf3b3731d3512eb5aa72ac7cdf02f9Jeffrey Yasskin 3556a9291ad55cf3b3731d3512eb5aa72ac7cdf02f9Jeffrey Yasskin { 3566a9291ad55cf3b3731d3512eb5aa72ac7cdf02f9Jeffrey Yasskin WeakVH ShouldBeVisited1(BitcastV.get()); 3576a9291ad55cf3b3731d3512eb5aa72ac7cdf02f9Jeffrey Yasskin DestroyingVH C(BitcastV.get()); 3586a9291ad55cf3b3731d3512eb5aa72ac7cdf02f9Jeffrey Yasskin WeakVH ShouldBeVisited2(BitcastV.get()); 3596a9291ad55cf3b3731d3512eb5aa72ac7cdf02f9Jeffrey Yasskin 3606a9291ad55cf3b3731d3512eb5aa72ac7cdf02f9Jeffrey Yasskin BitcastV->replaceAllUsesWith(ConstantV); 3616a9291ad55cf3b3731d3512eb5aa72ac7cdf02f9Jeffrey Yasskin EXPECT_EQ(ConstantV, static_cast<Value*>(ShouldBeVisited1)); 3626a9291ad55cf3b3731d3512eb5aa72ac7cdf02f9Jeffrey Yasskin EXPECT_EQ(ConstantV, static_cast<Value*>(ShouldBeVisited2)); 3636a9291ad55cf3b3731d3512eb5aa72ac7cdf02f9Jeffrey Yasskin } 3646a9291ad55cf3b3731d3512eb5aa72ac7cdf02f9Jeffrey Yasskin 3656a9291ad55cf3b3731d3512eb5aa72ac7cdf02f9Jeffrey Yasskin { 3666a9291ad55cf3b3731d3512eb5aa72ac7cdf02f9Jeffrey Yasskin WeakVH ShouldBeVisited1(BitcastV.get()); 3676a9291ad55cf3b3731d3512eb5aa72ac7cdf02f9Jeffrey Yasskin DestroyingVH C(BitcastV.get()); 3686a9291ad55cf3b3731d3512eb5aa72ac7cdf02f9Jeffrey Yasskin WeakVH ShouldBeVisited2(BitcastV.get()); 3696a9291ad55cf3b3731d3512eb5aa72ac7cdf02f9Jeffrey Yasskin 3706a9291ad55cf3b3731d3512eb5aa72ac7cdf02f9Jeffrey Yasskin BitcastV.reset(); 371cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines EXPECT_EQ(nullptr, static_cast<Value*>(ShouldBeVisited1)); 372cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines EXPECT_EQ(nullptr, static_cast<Value*>(ShouldBeVisited2)); 3736a9291ad55cf3b3731d3512eb5aa72ac7cdf02f9Jeffrey Yasskin } 3746a9291ad55cf3b3731d3512eb5aa72ac7cdf02f9Jeffrey Yasskin} 3756a9291ad55cf3b3731d3512eb5aa72ac7cdf02f9Jeffrey Yasskin 3766a9291ad55cf3b3731d3512eb5aa72ac7cdf02f9Jeffrey YasskinTEST_F(ValueHandle, AssertingVHCheckedLast) { 3776a9291ad55cf3b3731d3512eb5aa72ac7cdf02f9Jeffrey Yasskin // If a CallbackVH exists to clear out a group of AssertingVHs on 3786a9291ad55cf3b3731d3512eb5aa72ac7cdf02f9Jeffrey Yasskin // Value deletion, the CallbackVH should get a chance to do so 3796a9291ad55cf3b3731d3512eb5aa72ac7cdf02f9Jeffrey Yasskin // before the AssertingVHs assert. 3806a9291ad55cf3b3731d3512eb5aa72ac7cdf02f9Jeffrey Yasskin 3816a9291ad55cf3b3731d3512eb5aa72ac7cdf02f9Jeffrey Yasskin class ClearingVH : public CallbackVH { 3826a9291ad55cf3b3731d3512eb5aa72ac7cdf02f9Jeffrey Yasskin public: 3836a9291ad55cf3b3731d3512eb5aa72ac7cdf02f9Jeffrey Yasskin AssertingVH<Value> *ToClear[2]; 3846a9291ad55cf3b3731d3512eb5aa72ac7cdf02f9Jeffrey Yasskin ClearingVH(Value *V, 3856a9291ad55cf3b3731d3512eb5aa72ac7cdf02f9Jeffrey Yasskin AssertingVH<Value> &A0, AssertingVH<Value> &A1) 3866a9291ad55cf3b3731d3512eb5aa72ac7cdf02f9Jeffrey Yasskin : CallbackVH(V) { 3876a9291ad55cf3b3731d3512eb5aa72ac7cdf02f9Jeffrey Yasskin ToClear[0] = &A0; 3886a9291ad55cf3b3731d3512eb5aa72ac7cdf02f9Jeffrey Yasskin ToClear[1] = &A1; 3896a9291ad55cf3b3731d3512eb5aa72ac7cdf02f9Jeffrey Yasskin } 3906a9291ad55cf3b3731d3512eb5aa72ac7cdf02f9Jeffrey Yasskin 3916a9291ad55cf3b3731d3512eb5aa72ac7cdf02f9Jeffrey Yasskin virtual void deleted() { 392cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines *ToClear[0] = nullptr; 393cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines *ToClear[1] = nullptr; 3946a9291ad55cf3b3731d3512eb5aa72ac7cdf02f9Jeffrey Yasskin CallbackVH::deleted(); 3956a9291ad55cf3b3731d3512eb5aa72ac7cdf02f9Jeffrey Yasskin } 3966a9291ad55cf3b3731d3512eb5aa72ac7cdf02f9Jeffrey Yasskin }; 3976a9291ad55cf3b3731d3512eb5aa72ac7cdf02f9Jeffrey Yasskin 3986a9291ad55cf3b3731d3512eb5aa72ac7cdf02f9Jeffrey Yasskin AssertingVH<Value> A1, A2; 3996a9291ad55cf3b3731d3512eb5aa72ac7cdf02f9Jeffrey Yasskin A1 = BitcastV.get(); 4006a9291ad55cf3b3731d3512eb5aa72ac7cdf02f9Jeffrey Yasskin ClearingVH C(BitcastV.get(), A1, A2); 4016a9291ad55cf3b3731d3512eb5aa72ac7cdf02f9Jeffrey Yasskin A2 = BitcastV.get(); 4026a9291ad55cf3b3731d3512eb5aa72ac7cdf02f9Jeffrey Yasskin // C.deleted() should run first, clearing the two AssertingVHs, 4036a9291ad55cf3b3731d3512eb5aa72ac7cdf02f9Jeffrey Yasskin // which should prevent them from asserting. 4046a9291ad55cf3b3731d3512eb5aa72ac7cdf02f9Jeffrey Yasskin BitcastV.reset(); 4056a9291ad55cf3b3731d3512eb5aa72ac7cdf02f9Jeffrey Yasskin} 4066a9291ad55cf3b3731d3512eb5aa72ac7cdf02f9Jeffrey Yasskin 407487fa01673a1d13331b7173e9e6812e72dd4361eJeffrey Yasskin} 408