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"
15 #include "gtest/gtest.h"
23 class ValueHandle
: public testing::Test
{
26 std::auto_ptr
<BitCastInst
> BitcastV
;
29 ConstantV(ConstantInt::get(Type::getInt32Ty(getGlobalContext()), 0)),
30 BitcastV(new BitCastInst(ConstantV
, Type::getInt32Ty(getGlobalContext()))) {
34 class ConcreteCallbackVH
: public CallbackVH
{
36 ConcreteCallbackVH() : CallbackVH() {}
37 ConcreteCallbackVH(Value
*V
) : CallbackVH(V
) {}
40 TEST_F(ValueHandle
, WeakVH_BasicOperation
) {
41 WeakVH
WVH(BitcastV
.get());
42 EXPECT_EQ(BitcastV
.get(), WVH
);
44 EXPECT_EQ(ConstantV
, WVH
);
46 // Make sure I can call a method on the underlying Value. It
47 // doesn't matter which method.
48 EXPECT_EQ(Type::getInt32Ty(getGlobalContext()), WVH
->getType());
49 EXPECT_EQ(Type::getInt32Ty(getGlobalContext()), (*WVH
).getType());
52 TEST_F(ValueHandle
, WeakVH_Comparisons
) {
53 WeakVH
BitcastWVH(BitcastV
.get());
54 WeakVH
ConstantWVH(ConstantV
);
56 EXPECT_TRUE(BitcastWVH
== BitcastWVH
);
57 EXPECT_TRUE(BitcastV
.get() == BitcastWVH
);
58 EXPECT_TRUE(BitcastWVH
== BitcastV
.get());
59 EXPECT_FALSE(BitcastWVH
== ConstantWVH
);
61 EXPECT_TRUE(BitcastWVH
!= ConstantWVH
);
62 EXPECT_TRUE(BitcastV
.get() != ConstantWVH
);
63 EXPECT_TRUE(BitcastWVH
!= ConstantV
);
64 EXPECT_FALSE(BitcastWVH
!= BitcastWVH
);
66 // Cast to Value* so comparisons work.
67 Value
*BV
= BitcastV
.get();
68 Value
*CV
= ConstantV
;
69 EXPECT_EQ(BV
< CV
, BitcastWVH
< ConstantWVH
);
70 EXPECT_EQ(BV
<= CV
, BitcastWVH
<= ConstantWVH
);
71 EXPECT_EQ(BV
> CV
, BitcastWVH
> ConstantWVH
);
72 EXPECT_EQ(BV
>= CV
, BitcastWVH
>= ConstantWVH
);
74 EXPECT_EQ(BV
< CV
, BitcastV
.get() < 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
);
79 EXPECT_EQ(BV
< CV
, BitcastWVH
< ConstantV
);
80 EXPECT_EQ(BV
<= CV
, BitcastWVH
<= ConstantV
);
81 EXPECT_EQ(BV
> CV
, BitcastWVH
> ConstantV
);
82 EXPECT_EQ(BV
>= CV
, BitcastWVH
>= ConstantV
);
85 TEST_F(ValueHandle
, WeakVH_FollowsRAUW
) {
86 WeakVH
WVH(BitcastV
.get());
88 WeakVH
WVH_Recreated(BitcastV
.get());
89 BitcastV
->replaceAllUsesWith(ConstantV
);
90 EXPECT_EQ(ConstantV
, WVH
);
91 EXPECT_EQ(ConstantV
, WVH_Copy
);
92 EXPECT_EQ(ConstantV
, WVH_Recreated
);
95 TEST_F(ValueHandle
, WeakVH_NullOnDeletion
) {
96 WeakVH
WVH(BitcastV
.get());
98 WeakVH
WVH_Recreated(BitcastV
.get());
100 Value
*null_value
= NULL
;
101 EXPECT_EQ(null_value
, WVH
);
102 EXPECT_EQ(null_value
, WVH_Copy
);
103 EXPECT_EQ(null_value
, WVH_Recreated
);
107 TEST_F(ValueHandle
, AssertingVH_BasicOperation
) {
108 AssertingVH
<CastInst
> AVH(BitcastV
.get());
109 CastInst
*implicit_to_exact_type
= AVH
;
110 implicit_to_exact_type
= implicit_to_exact_type
; // Avoid warning.
112 AssertingVH
<Value
> GenericAVH(BitcastV
.get());
113 EXPECT_EQ(BitcastV
.get(), GenericAVH
);
114 GenericAVH
= ConstantV
;
115 EXPECT_EQ(ConstantV
, GenericAVH
);
117 // Make sure I can call a method on the underlying CastInst. It
118 // doesn't matter which method.
119 EXPECT_FALSE(AVH
->mayWriteToMemory());
120 EXPECT_FALSE((*AVH
).mayWriteToMemory());
123 TEST_F(ValueHandle
, AssertingVH_Const
) {
124 const CastInst
*ConstBitcast
= BitcastV
.get();
125 AssertingVH
<const CastInst
> AVH(ConstBitcast
);
126 const CastInst
*implicit_to_exact_type
= AVH
;
127 implicit_to_exact_type
= implicit_to_exact_type
; // Avoid warning.
130 TEST_F(ValueHandle
, AssertingVH_Comparisons
) {
131 AssertingVH
<Value
> BitcastAVH(BitcastV
.get());
132 AssertingVH
<Value
> ConstantAVH(ConstantV
);
134 EXPECT_TRUE(BitcastAVH
== BitcastAVH
);
135 EXPECT_TRUE(BitcastV
.get() == BitcastAVH
);
136 EXPECT_TRUE(BitcastAVH
== BitcastV
.get());
137 EXPECT_FALSE(BitcastAVH
== ConstantAVH
);
139 EXPECT_TRUE(BitcastAVH
!= ConstantAVH
);
140 EXPECT_TRUE(BitcastV
.get() != ConstantAVH
);
141 EXPECT_TRUE(BitcastAVH
!= ConstantV
);
142 EXPECT_FALSE(BitcastAVH
!= BitcastAVH
);
144 // Cast to Value* so comparisons work.
145 Value
*BV
= BitcastV
.get();
146 Value
*CV
= ConstantV
;
147 EXPECT_EQ(BV
< CV
, BitcastAVH
< ConstantAVH
);
148 EXPECT_EQ(BV
<= CV
, BitcastAVH
<= ConstantAVH
);
149 EXPECT_EQ(BV
> CV
, BitcastAVH
> ConstantAVH
);
150 EXPECT_EQ(BV
>= CV
, BitcastAVH
>= ConstantAVH
);
152 EXPECT_EQ(BV
< CV
, BitcastV
.get() < 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
);
157 EXPECT_EQ(BV
< CV
, BitcastAVH
< ConstantV
);
158 EXPECT_EQ(BV
<= CV
, BitcastAVH
<= ConstantV
);
159 EXPECT_EQ(BV
> CV
, BitcastAVH
> ConstantV
);
160 EXPECT_EQ(BV
>= CV
, BitcastAVH
>= ConstantV
);
163 TEST_F(ValueHandle
, AssertingVH_DoesNotFollowRAUW
) {
164 AssertingVH
<Value
> AVH(BitcastV
.get());
165 BitcastV
->replaceAllUsesWith(ConstantV
);
166 EXPECT_EQ(BitcastV
.get(), AVH
);
171 TEST_F(ValueHandle
, AssertingVH_ReducesToPointer
) {
172 EXPECT_EQ(sizeof(CastInst
*), sizeof(AssertingVH
<CastInst
>));
177 #ifdef GTEST_HAS_DEATH_TEST
179 TEST_F(ValueHandle
, AssertingVH_Asserts
) {
180 AssertingVH
<Value
> AVH(BitcastV
.get());
181 EXPECT_DEATH({BitcastV
.reset();},
182 "An asserting value handle still pointed to this value!");
183 AssertingVH
<Value
> Copy(AVH
);
185 EXPECT_DEATH({BitcastV
.reset();},
186 "An asserting value handle still pointed to this value!");
191 #endif // GTEST_HAS_DEATH_TEST
195 TEST_F(ValueHandle
, CallbackVH_BasicOperation
) {
196 ConcreteCallbackVH
CVH(BitcastV
.get());
197 EXPECT_EQ(BitcastV
.get(), CVH
);
199 EXPECT_EQ(ConstantV
, CVH
);
201 // Make sure I can call a method on the underlying Value. It
202 // doesn't matter which method.
203 EXPECT_EQ(Type::getInt32Ty(getGlobalContext()), CVH
->getType());
204 EXPECT_EQ(Type::getInt32Ty(getGlobalContext()), (*CVH
).getType());
207 TEST_F(ValueHandle
, CallbackVH_Comparisons
) {
208 ConcreteCallbackVH
BitcastCVH(BitcastV
.get());
209 ConcreteCallbackVH
ConstantCVH(ConstantV
);
211 EXPECT_TRUE(BitcastCVH
== BitcastCVH
);
212 EXPECT_TRUE(BitcastV
.get() == BitcastCVH
);
213 EXPECT_TRUE(BitcastCVH
== BitcastV
.get());
214 EXPECT_FALSE(BitcastCVH
== ConstantCVH
);
216 EXPECT_TRUE(BitcastCVH
!= ConstantCVH
);
217 EXPECT_TRUE(BitcastV
.get() != ConstantCVH
);
218 EXPECT_TRUE(BitcastCVH
!= ConstantV
);
219 EXPECT_FALSE(BitcastCVH
!= BitcastCVH
);
221 // Cast to Value* so comparisons work.
222 Value
*BV
= BitcastV
.get();
223 Value
*CV
= ConstantV
;
224 EXPECT_EQ(BV
< CV
, BitcastCVH
< ConstantCVH
);
225 EXPECT_EQ(BV
<= CV
, BitcastCVH
<= ConstantCVH
);
226 EXPECT_EQ(BV
> CV
, BitcastCVH
> ConstantCVH
);
227 EXPECT_EQ(BV
>= CV
, BitcastCVH
>= ConstantCVH
);
229 EXPECT_EQ(BV
< CV
, BitcastV
.get() < 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
);
234 EXPECT_EQ(BV
< CV
, BitcastCVH
< ConstantV
);
235 EXPECT_EQ(BV
<= CV
, BitcastCVH
<= ConstantV
);
236 EXPECT_EQ(BV
> CV
, BitcastCVH
> ConstantV
);
237 EXPECT_EQ(BV
>= CV
, BitcastCVH
>= ConstantV
);
240 TEST_F(ValueHandle
, CallbackVH_CallbackOnDeletion
) {
241 class RecordingVH
: public CallbackVH
{
246 RecordingVH() : DeletedCalls(0), AURWCalls(0) {}
247 RecordingVH(Value
*V
) : CallbackVH(V
), DeletedCalls(0), AURWCalls(0) {}
250 virtual void deleted() { DeletedCalls
++; CallbackVH::deleted(); }
251 virtual void allUsesReplacedWith(Value
*) { AURWCalls
++; }
255 RVH
= BitcastV
.get();
256 EXPECT_EQ(0, RVH
.DeletedCalls
);
257 EXPECT_EQ(0, RVH
.AURWCalls
);
259 EXPECT_EQ(1, RVH
.DeletedCalls
);
260 EXPECT_EQ(0, RVH
.AURWCalls
);
263 TEST_F(ValueHandle
, CallbackVH_CallbackOnRAUW
) {
264 class RecordingVH
: public CallbackVH
{
269 RecordingVH() : DeletedCalls(0), AURWArgument(NULL
) {}
270 RecordingVH(Value
*V
)
271 : CallbackVH(V
), DeletedCalls(0), AURWArgument(NULL
) {}
274 virtual void deleted() { DeletedCalls
++; CallbackVH::deleted(); }
275 virtual void allUsesReplacedWith(Value
*new_value
) {
276 EXPECT_EQ(NULL
, AURWArgument
);
277 AURWArgument
= new_value
;
282 RVH
= BitcastV
.get();
283 EXPECT_EQ(0, RVH
.DeletedCalls
);
284 EXPECT_EQ(NULL
, RVH
.AURWArgument
);
285 BitcastV
->replaceAllUsesWith(ConstantV
);
286 EXPECT_EQ(0, RVH
.DeletedCalls
);
287 EXPECT_EQ(ConstantV
, RVH
.AURWArgument
);
290 TEST_F(ValueHandle
, CallbackVH_DeletionCanRAUW
) {
291 class RecoveringVH
: public CallbackVH
{
295 LLVMContext
*Context
;
297 RecoveringVH() : DeletedCalls(0), AURWArgument(NULL
),
298 Context(&getGlobalContext()) {}
299 RecoveringVH(Value
*V
)
300 : CallbackVH(V
), DeletedCalls(0), AURWArgument(NULL
),
301 Context(&getGlobalContext()) {}
304 virtual void deleted() {
305 getValPtr()->replaceAllUsesWith(Constant::getNullValue(Type::getInt32Ty(getGlobalContext())));
308 virtual void allUsesReplacedWith(Value
*new_value
) {
309 ASSERT_TRUE(NULL
!= getValPtr());
310 EXPECT_EQ(1U, getValPtr()->getNumUses());
311 EXPECT_EQ(NULL
, AURWArgument
);
312 AURWArgument
= new_value
;
316 // Normally, if a value has uses, deleting it will crash. However, we can use
317 // a CallbackVH to remove the uses before the check for no uses.
319 RVH
= BitcastV
.get();
320 std::auto_ptr
<BinaryOperator
> BitcastUser(
321 BinaryOperator::CreateAdd(RVH
,
322 Constant::getNullValue(Type::getInt32Ty(getGlobalContext()))));
323 EXPECT_EQ(BitcastV
.get(), BitcastUser
->getOperand(0));
324 BitcastV
.reset(); // Would crash without the ValueHandler.
325 EXPECT_EQ(Constant::getNullValue(Type::getInt32Ty(getGlobalContext())), RVH
.AURWArgument
);
326 EXPECT_EQ(Constant::getNullValue(Type::getInt32Ty(getGlobalContext())),
327 BitcastUser
->getOperand(0));