1 //===- llvm/unittest/Support/ValueHandleTest.cpp - ValueHandle tests --------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "llvm/Support/ValueHandle.h"
12 #include "llvm/Constants.h"
13 #include "llvm/Instructions.h"
14 #include "llvm/LLVMContext.h"
15 #include "llvm/ADT/OwningPtr.h"
17 #include "gtest/gtest.h"
25 class ValueHandle
: public testing::Test
{
28 std::auto_ptr
<BitCastInst
> BitcastV
;
31 ConstantV(ConstantInt::get(Type::getInt32Ty(getGlobalContext()), 0)),
32 BitcastV(new BitCastInst(ConstantV
, Type::getInt32Ty(getGlobalContext()))) {
36 class ConcreteCallbackVH
: public CallbackVH
{
38 ConcreteCallbackVH(Value
*V
) : CallbackVH(V
) {}
41 TEST_F(ValueHandle
, WeakVH_BasicOperation
) {
42 WeakVH
WVH(BitcastV
.get());
43 EXPECT_EQ(BitcastV
.get(), WVH
);
45 EXPECT_EQ(ConstantV
, WVH
);
47 // Make sure I can call a method on the underlying Value. It
48 // doesn't matter which method.
49 EXPECT_EQ(Type::getInt32Ty(getGlobalContext()), WVH
->getType());
50 EXPECT_EQ(Type::getInt32Ty(getGlobalContext()), (*WVH
).getType());
53 TEST_F(ValueHandle
, WeakVH_Comparisons
) {
54 WeakVH
BitcastWVH(BitcastV
.get());
55 WeakVH
ConstantWVH(ConstantV
);
57 EXPECT_TRUE(BitcastWVH
== BitcastWVH
);
58 EXPECT_TRUE(BitcastV
.get() == BitcastWVH
);
59 EXPECT_TRUE(BitcastWVH
== BitcastV
.get());
60 EXPECT_FALSE(BitcastWVH
== ConstantWVH
);
62 EXPECT_TRUE(BitcastWVH
!= ConstantWVH
);
63 EXPECT_TRUE(BitcastV
.get() != ConstantWVH
);
64 EXPECT_TRUE(BitcastWVH
!= ConstantV
);
65 EXPECT_FALSE(BitcastWVH
!= BitcastWVH
);
67 // Cast to Value* so comparisons work.
68 Value
*BV
= BitcastV
.get();
69 Value
*CV
= ConstantV
;
70 EXPECT_EQ(BV
< CV
, BitcastWVH
< ConstantWVH
);
71 EXPECT_EQ(BV
<= CV
, BitcastWVH
<= ConstantWVH
);
72 EXPECT_EQ(BV
> CV
, BitcastWVH
> ConstantWVH
);
73 EXPECT_EQ(BV
>= CV
, BitcastWVH
>= ConstantWVH
);
75 EXPECT_EQ(BV
< CV
, BitcastV
.get() < ConstantWVH
);
76 EXPECT_EQ(BV
<= CV
, BitcastV
.get() <= ConstantWVH
);
77 EXPECT_EQ(BV
> CV
, BitcastV
.get() > ConstantWVH
);
78 EXPECT_EQ(BV
>= CV
, BitcastV
.get() >= ConstantWVH
);
80 EXPECT_EQ(BV
< CV
, BitcastWVH
< ConstantV
);
81 EXPECT_EQ(BV
<= CV
, BitcastWVH
<= ConstantV
);
82 EXPECT_EQ(BV
> CV
, BitcastWVH
> ConstantV
);
83 EXPECT_EQ(BV
>= CV
, BitcastWVH
>= ConstantV
);
86 TEST_F(ValueHandle
, WeakVH_FollowsRAUW
) {
87 WeakVH
WVH(BitcastV
.get());
89 WeakVH
WVH_Recreated(BitcastV
.get());
90 BitcastV
->replaceAllUsesWith(ConstantV
);
91 EXPECT_EQ(ConstantV
, WVH
);
92 EXPECT_EQ(ConstantV
, WVH_Copy
);
93 EXPECT_EQ(ConstantV
, WVH_Recreated
);
96 TEST_F(ValueHandle
, WeakVH_NullOnDeletion
) {
97 WeakVH
WVH(BitcastV
.get());
99 WeakVH
WVH_Recreated(BitcastV
.get());
101 Value
*null_value
= NULL
;
102 EXPECT_EQ(null_value
, WVH
);
103 EXPECT_EQ(null_value
, WVH_Copy
);
104 EXPECT_EQ(null_value
, WVH_Recreated
);
108 TEST_F(ValueHandle
, AssertingVH_BasicOperation
) {
109 AssertingVH
<CastInst
> AVH(BitcastV
.get());
110 CastInst
*implicit_to_exact_type
= AVH
;
111 (void)implicit_to_exact_type
; // Avoid warning.
113 AssertingVH
<Value
> GenericAVH(BitcastV
.get());
114 EXPECT_EQ(BitcastV
.get(), GenericAVH
);
115 GenericAVH
= ConstantV
;
116 EXPECT_EQ(ConstantV
, GenericAVH
);
118 // Make sure I can call a method on the underlying CastInst. It
119 // doesn't matter which method.
120 EXPECT_FALSE(AVH
->mayWriteToMemory());
121 EXPECT_FALSE((*AVH
).mayWriteToMemory());
124 TEST_F(ValueHandle
, AssertingVH_Const
) {
125 const CastInst
*ConstBitcast
= BitcastV
.get();
126 AssertingVH
<const CastInst
> AVH(ConstBitcast
);
127 const CastInst
*implicit_to_exact_type
= AVH
;
128 (void)implicit_to_exact_type
; // Avoid warning.
131 TEST_F(ValueHandle
, AssertingVH_Comparisons
) {
132 AssertingVH
<Value
> BitcastAVH(BitcastV
.get());
133 AssertingVH
<Value
> ConstantAVH(ConstantV
);
135 EXPECT_TRUE(BitcastAVH
== BitcastAVH
);
136 EXPECT_TRUE(BitcastV
.get() == BitcastAVH
);
137 EXPECT_TRUE(BitcastAVH
== BitcastV
.get());
138 EXPECT_FALSE(BitcastAVH
== ConstantAVH
);
140 EXPECT_TRUE(BitcastAVH
!= ConstantAVH
);
141 EXPECT_TRUE(BitcastV
.get() != ConstantAVH
);
142 EXPECT_TRUE(BitcastAVH
!= ConstantV
);
143 EXPECT_FALSE(BitcastAVH
!= BitcastAVH
);
145 // Cast to Value* so comparisons work.
146 Value
*BV
= BitcastV
.get();
147 Value
*CV
= ConstantV
;
148 EXPECT_EQ(BV
< CV
, BitcastAVH
< ConstantAVH
);
149 EXPECT_EQ(BV
<= CV
, BitcastAVH
<= ConstantAVH
);
150 EXPECT_EQ(BV
> CV
, BitcastAVH
> ConstantAVH
);
151 EXPECT_EQ(BV
>= CV
, BitcastAVH
>= ConstantAVH
);
153 EXPECT_EQ(BV
< CV
, BitcastV
.get() < ConstantAVH
);
154 EXPECT_EQ(BV
<= CV
, BitcastV
.get() <= ConstantAVH
);
155 EXPECT_EQ(BV
> CV
, BitcastV
.get() > ConstantAVH
);
156 EXPECT_EQ(BV
>= CV
, BitcastV
.get() >= ConstantAVH
);
158 EXPECT_EQ(BV
< CV
, BitcastAVH
< ConstantV
);
159 EXPECT_EQ(BV
<= CV
, BitcastAVH
<= ConstantV
);
160 EXPECT_EQ(BV
> CV
, BitcastAVH
> ConstantV
);
161 EXPECT_EQ(BV
>= CV
, BitcastAVH
>= ConstantV
);
164 TEST_F(ValueHandle
, AssertingVH_DoesNotFollowRAUW
) {
165 AssertingVH
<Value
> AVH(BitcastV
.get());
166 BitcastV
->replaceAllUsesWith(ConstantV
);
167 EXPECT_EQ(BitcastV
.get(), AVH
);
172 TEST_F(ValueHandle
, AssertingVH_ReducesToPointer
) {
173 EXPECT_EQ(sizeof(CastInst
*), sizeof(AssertingVH
<CastInst
>));
178 #ifdef GTEST_HAS_DEATH_TEST
180 TEST_F(ValueHandle
, AssertingVH_Asserts
) {
181 AssertingVH
<Value
> AVH(BitcastV
.get());
182 EXPECT_DEATH({BitcastV
.reset();},
183 "An asserting value handle still pointed to this value!");
184 AssertingVH
<Value
> Copy(AVH
);
186 EXPECT_DEATH({BitcastV
.reset();},
187 "An asserting value handle still pointed to this value!");
192 #endif // GTEST_HAS_DEATH_TEST
196 TEST_F(ValueHandle
, CallbackVH_BasicOperation
) {
197 ConcreteCallbackVH
CVH(BitcastV
.get());
198 EXPECT_EQ(BitcastV
.get(), CVH
);
200 EXPECT_EQ(ConstantV
, CVH
);
202 // Make sure I can call a method on the underlying Value. It
203 // doesn't matter which method.
204 EXPECT_EQ(Type::getInt32Ty(getGlobalContext()), CVH
->getType());
205 EXPECT_EQ(Type::getInt32Ty(getGlobalContext()), (*CVH
).getType());
208 TEST_F(ValueHandle
, CallbackVH_Comparisons
) {
209 ConcreteCallbackVH
BitcastCVH(BitcastV
.get());
210 ConcreteCallbackVH
ConstantCVH(ConstantV
);
212 EXPECT_TRUE(BitcastCVH
== BitcastCVH
);
213 EXPECT_TRUE(BitcastV
.get() == BitcastCVH
);
214 EXPECT_TRUE(BitcastCVH
== BitcastV
.get());
215 EXPECT_FALSE(BitcastCVH
== ConstantCVH
);
217 EXPECT_TRUE(BitcastCVH
!= ConstantCVH
);
218 EXPECT_TRUE(BitcastV
.get() != ConstantCVH
);
219 EXPECT_TRUE(BitcastCVH
!= ConstantV
);
220 EXPECT_FALSE(BitcastCVH
!= BitcastCVH
);
222 // Cast to Value* so comparisons work.
223 Value
*BV
= BitcastV
.get();
224 Value
*CV
= ConstantV
;
225 EXPECT_EQ(BV
< CV
, BitcastCVH
< ConstantCVH
);
226 EXPECT_EQ(BV
<= CV
, BitcastCVH
<= ConstantCVH
);
227 EXPECT_EQ(BV
> CV
, BitcastCVH
> ConstantCVH
);
228 EXPECT_EQ(BV
>= CV
, BitcastCVH
>= ConstantCVH
);
230 EXPECT_EQ(BV
< CV
, BitcastV
.get() < ConstantCVH
);
231 EXPECT_EQ(BV
<= CV
, BitcastV
.get() <= ConstantCVH
);
232 EXPECT_EQ(BV
> CV
, BitcastV
.get() > ConstantCVH
);
233 EXPECT_EQ(BV
>= CV
, BitcastV
.get() >= ConstantCVH
);
235 EXPECT_EQ(BV
< CV
, BitcastCVH
< ConstantV
);
236 EXPECT_EQ(BV
<= CV
, BitcastCVH
<= ConstantV
);
237 EXPECT_EQ(BV
> CV
, BitcastCVH
> ConstantV
);
238 EXPECT_EQ(BV
>= CV
, BitcastCVH
>= ConstantV
);
241 TEST_F(ValueHandle
, CallbackVH_CallbackOnDeletion
) {
242 class RecordingVH
: public CallbackVH
{
247 RecordingVH() : DeletedCalls(0), AURWCalls(0) {}
248 RecordingVH(Value
*V
) : CallbackVH(V
), DeletedCalls(0), AURWCalls(0) {}
251 virtual void deleted() { DeletedCalls
++; CallbackVH::deleted(); }
252 virtual void allUsesReplacedWith(Value
*) { AURWCalls
++; }
256 RVH
= BitcastV
.get();
257 EXPECT_EQ(0, RVH
.DeletedCalls
);
258 EXPECT_EQ(0, RVH
.AURWCalls
);
260 EXPECT_EQ(1, RVH
.DeletedCalls
);
261 EXPECT_EQ(0, RVH
.AURWCalls
);
264 TEST_F(ValueHandle
, CallbackVH_CallbackOnRAUW
) {
265 class RecordingVH
: public CallbackVH
{
270 RecordingVH() : DeletedCalls(0), AURWArgument(NULL
) {}
271 RecordingVH(Value
*V
)
272 : CallbackVH(V
), DeletedCalls(0), AURWArgument(NULL
) {}
275 virtual void deleted() { DeletedCalls
++; CallbackVH::deleted(); }
276 virtual void allUsesReplacedWith(Value
*new_value
) {
277 EXPECT_EQ(NULL
, AURWArgument
);
278 AURWArgument
= new_value
;
283 RVH
= BitcastV
.get();
284 EXPECT_EQ(0, RVH
.DeletedCalls
);
285 EXPECT_EQ(NULL
, RVH
.AURWArgument
);
286 BitcastV
->replaceAllUsesWith(ConstantV
);
287 EXPECT_EQ(0, RVH
.DeletedCalls
);
288 EXPECT_EQ(ConstantV
, RVH
.AURWArgument
);
291 TEST_F(ValueHandle
, CallbackVH_DeletionCanRAUW
) {
292 class RecoveringVH
: public CallbackVH
{
296 LLVMContext
*Context
;
298 RecoveringVH() : DeletedCalls(0), AURWArgument(NULL
),
299 Context(&getGlobalContext()) {}
300 RecoveringVH(Value
*V
)
301 : CallbackVH(V
), DeletedCalls(0), AURWArgument(NULL
),
302 Context(&getGlobalContext()) {}
305 virtual void deleted() {
306 getValPtr()->replaceAllUsesWith(Constant::getNullValue(Type::getInt32Ty(getGlobalContext())));
309 virtual void allUsesReplacedWith(Value
*new_value
) {
310 ASSERT_TRUE(NULL
!= getValPtr());
311 EXPECT_EQ(1U, getValPtr()->getNumUses());
312 EXPECT_EQ(NULL
, AURWArgument
);
313 AURWArgument
= new_value
;
317 // Normally, if a value has uses, deleting it will crash. However, we can use
318 // a CallbackVH to remove the uses before the check for no uses.
320 RVH
= BitcastV
.get();
321 std::auto_ptr
<BinaryOperator
> BitcastUser(
322 BinaryOperator::CreateAdd(RVH
,
323 Constant::getNullValue(Type::getInt32Ty(getGlobalContext()))));
324 EXPECT_EQ(BitcastV
.get(), BitcastUser
->getOperand(0));
325 BitcastV
.reset(); // Would crash without the ValueHandler.
326 EXPECT_EQ(Constant::getNullValue(Type::getInt32Ty(getGlobalContext())), RVH
.AURWArgument
);
327 EXPECT_EQ(Constant::getNullValue(Type::getInt32Ty(getGlobalContext())),
328 BitcastUser
->getOperand(0));
331 TEST_F(ValueHandle
, DestroyingOtherVHOnSameValueDoesntBreakIteration
) {
332 // When a CallbackVH modifies other ValueHandles in its callbacks,
333 // that shouldn't interfere with non-modified ValueHandles receiving
334 // their appropriate callbacks.
336 // We create the active CallbackVH in the middle of a palindromic
337 // arrangement of other VHs so that the bad behavior would be
338 // triggered in whichever order callbacks run.
340 class DestroyingVH
: public CallbackVH
{
342 OwningPtr
<WeakVH
> ToClear
[2];
343 DestroyingVH(Value
*V
) {
344 ToClear
[0].reset(new WeakVH(V
));
346 ToClear
[1].reset(new WeakVH(V
));
348 virtual void deleted() {
351 CallbackVH::deleted();
353 virtual void allUsesReplacedWith(Value
*) {
360 WeakVH
ShouldBeVisited1(BitcastV
.get());
361 DestroyingVH
C(BitcastV
.get());
362 WeakVH
ShouldBeVisited2(BitcastV
.get());
364 BitcastV
->replaceAllUsesWith(ConstantV
);
365 EXPECT_EQ(ConstantV
, static_cast<Value
*>(ShouldBeVisited1
));
366 EXPECT_EQ(ConstantV
, static_cast<Value
*>(ShouldBeVisited2
));
370 WeakVH
ShouldBeVisited1(BitcastV
.get());
371 DestroyingVH
C(BitcastV
.get());
372 WeakVH
ShouldBeVisited2(BitcastV
.get());
375 EXPECT_EQ(NULL
, static_cast<Value
*>(ShouldBeVisited1
));
376 EXPECT_EQ(NULL
, static_cast<Value
*>(ShouldBeVisited2
));
380 TEST_F(ValueHandle
, AssertingVHCheckedLast
) {
381 // If a CallbackVH exists to clear out a group of AssertingVHs on
382 // Value deletion, the CallbackVH should get a chance to do so
383 // before the AssertingVHs assert.
385 class ClearingVH
: public CallbackVH
{
387 AssertingVH
<Value
> *ToClear
[2];
389 AssertingVH
<Value
> &A0
, AssertingVH
<Value
> &A1
)
395 virtual void deleted() {
398 CallbackVH::deleted();
402 AssertingVH
<Value
> A1
, A2
;
404 ClearingVH
C(BitcastV
.get(), A1
, A2
);
406 // C.deleted() should run first, clearing the two AssertingVHs,
407 // which should prevent them from asserting.