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
;
28 ValueHandle() : ConstantV(ConstantInt::get(Type::Int32Ty
, 0)),
29 BitcastV(new BitCastInst(ConstantV
, Type::Int32Ty
)) {
33 class ConcreteCallbackVH
: public CallbackVH
{
35 ConcreteCallbackVH() : CallbackVH() {}
36 ConcreteCallbackVH(Value
*V
) : CallbackVH(V
) {}
39 TEST_F(ValueHandle
, WeakVH_BasicOperation
) {
40 WeakVH
WVH(BitcastV
.get());
41 EXPECT_EQ(BitcastV
.get(), WVH
);
43 EXPECT_EQ(ConstantV
, WVH
);
45 // Make sure I can call a method on the underlying Value. It
46 // doesn't matter which method.
47 EXPECT_EQ(Type::Int32Ty
, WVH
->getType());
48 EXPECT_EQ(Type::Int32Ty
, (*WVH
).getType());
51 TEST_F(ValueHandle
, WeakVH_Comparisons
) {
52 WeakVH
BitcastWVH(BitcastV
.get());
53 WeakVH
ConstantWVH(ConstantV
);
55 EXPECT_TRUE(BitcastWVH
== BitcastWVH
);
56 EXPECT_TRUE(BitcastV
.get() == BitcastWVH
);
57 EXPECT_TRUE(BitcastWVH
== BitcastV
.get());
58 EXPECT_FALSE(BitcastWVH
== ConstantWVH
);
60 EXPECT_TRUE(BitcastWVH
!= ConstantWVH
);
61 EXPECT_TRUE(BitcastV
.get() != ConstantWVH
);
62 EXPECT_TRUE(BitcastWVH
!= ConstantV
);
63 EXPECT_FALSE(BitcastWVH
!= BitcastWVH
);
65 // Cast to Value* so comparisons work.
66 Value
*BV
= BitcastV
.get();
67 Value
*CV
= ConstantV
;
68 EXPECT_EQ(BV
< CV
, BitcastWVH
< ConstantWVH
);
69 EXPECT_EQ(BV
<= CV
, BitcastWVH
<= ConstantWVH
);
70 EXPECT_EQ(BV
> CV
, BitcastWVH
> ConstantWVH
);
71 EXPECT_EQ(BV
>= CV
, BitcastWVH
>= ConstantWVH
);
73 EXPECT_EQ(BV
< CV
, BitcastV
.get() < 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
);
78 EXPECT_EQ(BV
< CV
, BitcastWVH
< ConstantV
);
79 EXPECT_EQ(BV
<= CV
, BitcastWVH
<= ConstantV
);
80 EXPECT_EQ(BV
> CV
, BitcastWVH
> ConstantV
);
81 EXPECT_EQ(BV
>= CV
, BitcastWVH
>= ConstantV
);
84 TEST_F(ValueHandle
, WeakVH_FollowsRAUW
) {
85 WeakVH
WVH(BitcastV
.get());
87 WeakVH
WVH_Recreated(BitcastV
.get());
88 BitcastV
->replaceAllUsesWith(ConstantV
);
89 EXPECT_EQ(ConstantV
, WVH
);
90 EXPECT_EQ(ConstantV
, WVH_Copy
);
91 EXPECT_EQ(ConstantV
, WVH_Recreated
);
94 TEST_F(ValueHandle
, WeakVH_NullOnDeletion
) {
95 WeakVH
WVH(BitcastV
.get());
97 WeakVH
WVH_Recreated(BitcastV
.get());
99 Value
*null_value
= NULL
;
100 EXPECT_EQ(null_value
, WVH
);
101 EXPECT_EQ(null_value
, WVH_Copy
);
102 EXPECT_EQ(null_value
, WVH_Recreated
);
106 TEST_F(ValueHandle
, AssertingVH_BasicOperation
) {
107 AssertingVH
<CastInst
> AVH(BitcastV
.get());
108 CastInst
*implicit_to_exact_type
= AVH
;
109 implicit_to_exact_type
= implicit_to_exact_type
; // Avoid warning.
111 AssertingVH
<Value
> GenericAVH(BitcastV
.get());
112 EXPECT_EQ(BitcastV
.get(), GenericAVH
);
113 GenericAVH
= ConstantV
;
114 EXPECT_EQ(ConstantV
, GenericAVH
);
116 // Make sure I can call a method on the underlying CastInst. It
117 // doesn't matter which method.
118 EXPECT_FALSE(AVH
->mayWriteToMemory());
119 EXPECT_FALSE((*AVH
).mayWriteToMemory());
122 TEST_F(ValueHandle
, AssertingVH_Comparisons
) {
123 AssertingVH
<Value
> BitcastAVH(BitcastV
.get());
124 AssertingVH
<Value
> ConstantAVH(ConstantV
);
126 EXPECT_TRUE(BitcastAVH
== BitcastAVH
);
127 EXPECT_TRUE(BitcastV
.get() == BitcastAVH
);
128 EXPECT_TRUE(BitcastAVH
== BitcastV
.get());
129 EXPECT_FALSE(BitcastAVH
== ConstantAVH
);
131 EXPECT_TRUE(BitcastAVH
!= ConstantAVH
);
132 EXPECT_TRUE(BitcastV
.get() != ConstantAVH
);
133 EXPECT_TRUE(BitcastAVH
!= ConstantV
);
134 EXPECT_FALSE(BitcastAVH
!= BitcastAVH
);
136 // Cast to Value* so comparisons work.
137 Value
*BV
= BitcastV
.get();
138 Value
*CV
= ConstantV
;
139 EXPECT_EQ(BV
< CV
, BitcastAVH
< ConstantAVH
);
140 EXPECT_EQ(BV
<= CV
, BitcastAVH
<= ConstantAVH
);
141 EXPECT_EQ(BV
> CV
, BitcastAVH
> ConstantAVH
);
142 EXPECT_EQ(BV
>= CV
, BitcastAVH
>= ConstantAVH
);
144 EXPECT_EQ(BV
< CV
, BitcastV
.get() < ConstantAVH
);
145 EXPECT_EQ(BV
<= CV
, BitcastV
.get() <= ConstantAVH
);
146 EXPECT_EQ(BV
> CV
, BitcastV
.get() > ConstantAVH
);
147 EXPECT_EQ(BV
>= CV
, BitcastV
.get() >= ConstantAVH
);
149 EXPECT_EQ(BV
< CV
, BitcastAVH
< ConstantV
);
150 EXPECT_EQ(BV
<= CV
, BitcastAVH
<= ConstantV
);
151 EXPECT_EQ(BV
> CV
, BitcastAVH
> ConstantV
);
152 EXPECT_EQ(BV
>= CV
, BitcastAVH
>= ConstantV
);
155 TEST_F(ValueHandle
, AssertingVH_DoesNotFollowRAUW
) {
156 AssertingVH
<Value
> AVH(BitcastV
.get());
157 BitcastV
->replaceAllUsesWith(ConstantV
);
158 EXPECT_EQ(BitcastV
.get(), AVH
);
163 TEST_F(ValueHandle
, AssertingVH_ReducesToPointer
) {
164 EXPECT_EQ(sizeof(CastInst
*), sizeof(AssertingVH
<CastInst
>));
169 #ifdef GTEST_HAS_DEATH_TEST
171 TEST_F(ValueHandle
, AssertingVH_Asserts
) {
172 AssertingVH
<Value
> AVH(BitcastV
.get());
173 EXPECT_DEATH({BitcastV
.reset();},
174 "An asserting value handle still pointed to this value!");
175 AssertingVH
<Value
> Copy(AVH
);
177 EXPECT_DEATH({BitcastV
.reset();},
178 "An asserting value handle still pointed to this value!");
183 #endif // GTEST_HAS_DEATH_TEST
187 TEST_F(ValueHandle
, CallbackVH_BasicOperation
) {
188 ConcreteCallbackVH
CVH(BitcastV
.get());
189 EXPECT_EQ(BitcastV
.get(), CVH
);
191 EXPECT_EQ(ConstantV
, CVH
);
193 // Make sure I can call a method on the underlying Value. It
194 // doesn't matter which method.
195 EXPECT_EQ(Type::Int32Ty
, CVH
->getType());
196 EXPECT_EQ(Type::Int32Ty
, (*CVH
).getType());
199 TEST_F(ValueHandle
, CallbackVH_Comparisons
) {
200 ConcreteCallbackVH
BitcastCVH(BitcastV
.get());
201 ConcreteCallbackVH
ConstantCVH(ConstantV
);
203 EXPECT_TRUE(BitcastCVH
== BitcastCVH
);
204 EXPECT_TRUE(BitcastV
.get() == BitcastCVH
);
205 EXPECT_TRUE(BitcastCVH
== BitcastV
.get());
206 EXPECT_FALSE(BitcastCVH
== ConstantCVH
);
208 EXPECT_TRUE(BitcastCVH
!= ConstantCVH
);
209 EXPECT_TRUE(BitcastV
.get() != ConstantCVH
);
210 EXPECT_TRUE(BitcastCVH
!= ConstantV
);
211 EXPECT_FALSE(BitcastCVH
!= BitcastCVH
);
213 // Cast to Value* so comparisons work.
214 Value
*BV
= BitcastV
.get();
215 Value
*CV
= ConstantV
;
216 EXPECT_EQ(BV
< CV
, BitcastCVH
< ConstantCVH
);
217 EXPECT_EQ(BV
<= CV
, BitcastCVH
<= ConstantCVH
);
218 EXPECT_EQ(BV
> CV
, BitcastCVH
> ConstantCVH
);
219 EXPECT_EQ(BV
>= CV
, BitcastCVH
>= ConstantCVH
);
221 EXPECT_EQ(BV
< CV
, BitcastV
.get() < ConstantCVH
);
222 EXPECT_EQ(BV
<= CV
, BitcastV
.get() <= ConstantCVH
);
223 EXPECT_EQ(BV
> CV
, BitcastV
.get() > ConstantCVH
);
224 EXPECT_EQ(BV
>= CV
, BitcastV
.get() >= ConstantCVH
);
226 EXPECT_EQ(BV
< CV
, BitcastCVH
< ConstantV
);
227 EXPECT_EQ(BV
<= CV
, BitcastCVH
<= ConstantV
);
228 EXPECT_EQ(BV
> CV
, BitcastCVH
> ConstantV
);
229 EXPECT_EQ(BV
>= CV
, BitcastCVH
>= ConstantV
);
232 TEST_F(ValueHandle
, CallbackVH_CallbackOnDeletion
) {
233 class RecordingVH
: public CallbackVH
{
238 RecordingVH() : DeletedCalls(0), AURWCalls(0) {}
239 RecordingVH(Value
*V
) : CallbackVH(V
), DeletedCalls(0), AURWCalls(0) {}
242 virtual void deleted() { DeletedCalls
++; CallbackVH::deleted(); }
243 virtual void allUsesReplacedWith(Value
*) { AURWCalls
++; }
247 RVH
= BitcastV
.get();
248 EXPECT_EQ(0, RVH
.DeletedCalls
);
249 EXPECT_EQ(0, RVH
.AURWCalls
);
251 EXPECT_EQ(1, RVH
.DeletedCalls
);
252 EXPECT_EQ(0, RVH
.AURWCalls
);
255 TEST_F(ValueHandle
, CallbackVH_CallbackOnRAUW
) {
256 class RecordingVH
: public CallbackVH
{
261 RecordingVH() : DeletedCalls(0), AURWArgument(NULL
) {}
262 RecordingVH(Value
*V
)
263 : CallbackVH(V
), DeletedCalls(0), AURWArgument(NULL
) {}
266 virtual void deleted() { DeletedCalls
++; CallbackVH::deleted(); }
267 virtual void allUsesReplacedWith(Value
*new_value
) {
268 EXPECT_EQ(NULL
, AURWArgument
);
269 AURWArgument
= new_value
;
274 RVH
= BitcastV
.get();
275 EXPECT_EQ(0, RVH
.DeletedCalls
);
276 EXPECT_EQ(NULL
, RVH
.AURWArgument
);
277 BitcastV
->replaceAllUsesWith(ConstantV
);
278 EXPECT_EQ(0, RVH
.DeletedCalls
);
279 EXPECT_EQ(ConstantV
, RVH
.AURWArgument
);
282 TEST_F(ValueHandle
, CallbackVH_DeletionCanRAUW
) {
283 class RecoveringVH
: public CallbackVH
{
288 RecoveringVH() : DeletedCalls(0), AURWArgument(NULL
) {}
289 RecoveringVH(Value
*V
)
290 : CallbackVH(V
), DeletedCalls(0), AURWArgument(NULL
) {}
293 virtual void deleted() {
294 getValPtr()->replaceAllUsesWith(Constant::getNullValue(Type::Int32Ty
));
297 virtual void allUsesReplacedWith(Value
*new_value
) {
298 ASSERT_TRUE(NULL
!= getValPtr());
299 EXPECT_EQ(1, getValPtr()->getNumUses());
300 EXPECT_EQ(NULL
, AURWArgument
);
301 AURWArgument
= new_value
;
305 // Normally, if a value has uses, deleting it will crash. However, we can use
306 // a CallbackVH to remove the uses before the check for no uses.
308 RVH
= BitcastV
.get();
309 std::auto_ptr
<BinaryOperator
> BitcastUser(
310 BinaryOperator::CreateAdd(RVH
, Constant::getNullValue(Type::Int32Ty
)));
311 EXPECT_EQ(BitcastV
.get(), BitcastUser
->getOperand(0));
312 BitcastV
.reset(); // Would crash without the ValueHandler.
313 EXPECT_EQ(Constant::getNullValue(Type::Int32Ty
), RVH
.AURWArgument
);
314 EXPECT_EQ(Constant::getNullValue(Type::Int32Ty
), BitcastUser
->getOperand(0));