blob: b799ff0958065465e244b2062b549e381f54ff83 [file] [log] [blame]
Chandler Carruth4220e9c2014-03-04 11:17:44 +00001//===- ValueHandleTest.cpp - ValueHandle tests ----------------------------===//
Jeffrey Yasskin41f24772009-04-27 20:32:07 +00002//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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
Jeffrey Yasskin41f24772009-04-27 20:32:07 +00006//
7//===----------------------------------------------------------------------===//
8
Chandler Carruth4220e9c2014-03-04 11:17:44 +00009#include "llvm/IR/ValueHandle.h"
Chandler Carruth9fb823b2013-01-02 11:36:10 +000010#include "llvm/IR/Constants.h"
11#include "llvm/IR/Instructions.h"
12#include "llvm/IR/LLVMContext.h"
Jeffrey Yasskin41f24772009-04-27 20:32:07 +000013#include "gtest/gtest.h"
Jeffrey Yasskin41f24772009-04-27 20:32:07 +000014#include <memory>
15
16using namespace llvm;
17
18namespace {
19
20class ValueHandle : public testing::Test {
21protected:
Mehdi Amini03b42e42016-04-14 21:59:01 +000022 LLVMContext Context;
Jeffrey Yasskin41f24772009-04-27 20:32:07 +000023 Constant *ConstantV;
David Blaikie17ab82c2015-04-22 04:39:13 +000024 std::unique_ptr<BitCastInst> BitcastV;
Jeffrey Yasskin41f24772009-04-27 20:32:07 +000025
Mehdi Amini03b42e42016-04-14 21:59:01 +000026 ValueHandle()
27 : ConstantV(ConstantInt::get(Type::getInt32Ty(Context), 0)),
28 BitcastV(new BitCastInst(ConstantV, Type::getInt32Ty(Context))) {}
Jeffrey Yasskin41f24772009-04-27 20:32:07 +000029};
30
David Blaikie774b5842015-08-03 22:30:24 +000031class ConcreteCallbackVH final : public CallbackVH {
Dan Gohman745ad442009-05-02 21:10:48 +000032public:
Dan Gohman745ad442009-05-02 21:10:48 +000033 ConcreteCallbackVH(Value *V) : CallbackVH(V) {}
34};
35
Sanjoy Dasf1c0eaf2017-05-01 17:07:54 +000036TEST_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
Sanjoy Dase6bca0e2017-05-01 17:07:49 +000054TEST_F(ValueHandle, WeakTrackingVH_BasicOperation) {
55 WeakTrackingVH WVH(BitcastV.get());
Sanjoy Das7de051b2017-04-26 16:20:59 +000056 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());
Sanjoy Das7de051b2017-04-26 16:20:59 +000064}
65
Sanjoy Dase6bca0e2017-05-01 17:07:49 +000066TEST_F(ValueHandle, WeakTrackingVH_Comparisons) {
67 WeakTrackingVH BitcastWVH(BitcastV.get());
68 WeakTrackingVH ConstantWVH(ConstantV);
Jeffrey Yasskin41f24772009-04-27 20:32:07 +000069
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
Sanjoy Dase6bca0e2017-05-01 17:07:49 +000099TEST_F(ValueHandle, WeakTrackingVH_FollowsRAUW) {
100 WeakTrackingVH WVH(BitcastV.get());
101 WeakTrackingVH WVH_Copy(WVH);
102 WeakTrackingVH WVH_Recreated(BitcastV.get());
Jeffrey Yasskin41f24772009-04-27 20:32:07 +0000103 BitcastV->replaceAllUsesWith(ConstantV);
104 EXPECT_EQ(ConstantV, WVH);
105 EXPECT_EQ(ConstantV, WVH_Copy);
106 EXPECT_EQ(ConstantV, WVH_Recreated);
107}
108
Sanjoy Dase6bca0e2017-05-01 17:07:49 +0000109TEST_F(ValueHandle, WeakTrackingVH_NullOnDeletion) {
110 WeakTrackingVH WVH(BitcastV.get());
111 WeakTrackingVH WVH_Copy(WVH);
112 WeakTrackingVH WVH_Recreated(BitcastV.get());
Jeffrey Yasskin41f24772009-04-27 20:32:07 +0000113 BitcastV.reset();
Craig Topper66f09ad2014-06-08 22:29:17 +0000114 Value *null_value = nullptr;
Jeffrey Yasskin41f24772009-04-27 20:32:07 +0000115 EXPECT_EQ(null_value, WVH);
116 EXPECT_EQ(null_value, WVH_Copy);
117 EXPECT_EQ(null_value, WVH_Recreated);
118}
119
120
121TEST_F(ValueHandle, AssertingVH_BasicOperation) {
122 AssertingVH<CastInst> AVH(BitcastV.get());
123 CastInst *implicit_to_exact_type = AVH;
Jeffrey Yasskin9b43f332010-12-23 00:58:24 +0000124 (void)implicit_to_exact_type; // Avoid warning.
Jeffrey Yasskin41f24772009-04-27 20:32:07 +0000125
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
Jeffrey Yasskin6bf87df2009-08-07 19:54:29 +0000137TEST_F(ValueHandle, AssertingVH_Const) {
138 const CastInst *ConstBitcast = BitcastV.get();
139 AssertingVH<const CastInst> AVH(ConstBitcast);
140 const CastInst *implicit_to_exact_type = AVH;
Jeffrey Yasskin9b43f332010-12-23 00:58:24 +0000141 (void)implicit_to_exact_type; // Avoid warning.
Jeffrey Yasskin6bf87df2009-08-07 19:54:29 +0000142}
143
Jeffrey Yasskin41f24772009-04-27 20:32:07 +0000144TEST_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
177TEST_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
185TEST_F(ValueHandle, AssertingVH_ReducesToPointer) {
186 EXPECT_EQ(sizeof(CastInst *), sizeof(AssertingVH<CastInst>));
187}
188
189#else // !NDEBUG
190
191#ifdef GTEST_HAS_DEATH_TEST
192
193TEST_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);
Craig Topper66f09ad2014-06-08 22:29:17 +0000198 AVH = nullptr;
Jeffrey Yasskin41f24772009-04-27 20:32:07 +0000199 EXPECT_DEATH({BitcastV.reset();},
200 "An asserting value handle still pointed to this value!");
Craig Topper66f09ad2014-06-08 22:29:17 +0000201 Copy = nullptr;
Jeffrey Yasskin41f24772009-04-27 20:32:07 +0000202 BitcastV.reset();
203}
204
205#endif // GTEST_HAS_DEATH_TEST
206
207#endif // NDEBUG
208
Dan Gohman745ad442009-05-02 21:10:48 +0000209TEST_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.
Mehdi Amini03b42e42016-04-14 21:59:01 +0000217 EXPECT_EQ(Type::getInt32Ty(Context), CVH->getType());
218 EXPECT_EQ(Type::getInt32Ty(Context), (*CVH).getType());
Dan Gohman745ad442009-05-02 21:10:48 +0000219}
220
221TEST_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
254TEST_F(ValueHandle, CallbackVH_CallbackOnDeletion) {
David Blaikie774b5842015-08-03 22:30:24 +0000255 class RecordingVH final : public CallbackVH {
Dan Gohman745ad442009-05-02 21:10:48 +0000256 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:
Alexander Kornienkof817c1c2015-04-11 02:11:45 +0000264 void deleted() override {
265 DeletedCalls++;
266 CallbackVH::deleted();
267 }
268 void allUsesReplacedWith(Value *) override { AURWCalls++; }
Dan Gohman745ad442009-05-02 21:10:48 +0000269 };
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
280TEST_F(ValueHandle, CallbackVH_CallbackOnRAUW) {
David Blaikie774b5842015-08-03 22:30:24 +0000281 class RecordingVH final : public CallbackVH {
Dan Gohman745ad442009-05-02 21:10:48 +0000282 public:
283 int DeletedCalls;
284 Value *AURWArgument;
285
Craig Topper66f09ad2014-06-08 22:29:17 +0000286 RecordingVH() : DeletedCalls(0), AURWArgument(nullptr) {}
Dan Gohman745ad442009-05-02 21:10:48 +0000287 RecordingVH(Value *V)
Craig Topper66f09ad2014-06-08 22:29:17 +0000288 : CallbackVH(V), DeletedCalls(0), AURWArgument(nullptr) {}
Dan Gohman745ad442009-05-02 21:10:48 +0000289
290 private:
Alexander Kornienkof817c1c2015-04-11 02:11:45 +0000291 void deleted() override {
292 DeletedCalls++;
293 CallbackVH::deleted();
294 }
295 void allUsesReplacedWith(Value *new_value) override {
Craig Topper66f09ad2014-06-08 22:29:17 +0000296 EXPECT_EQ(nullptr, AURWArgument);
Dan Gohman745ad442009-05-02 21:10:48 +0000297 AURWArgument = new_value;
298 }
299 };
300
301 RecordingVH RVH;
302 RVH = BitcastV.get();
303 EXPECT_EQ(0, RVH.DeletedCalls);
Craig Topper66f09ad2014-06-08 22:29:17 +0000304 EXPECT_EQ(nullptr, RVH.AURWArgument);
Dan Gohman745ad442009-05-02 21:10:48 +0000305 BitcastV->replaceAllUsesWith(ConstantV);
306 EXPECT_EQ(0, RVH.DeletedCalls);
307 EXPECT_EQ(ConstantV, RVH.AURWArgument);
308}
309
310TEST_F(ValueHandle, CallbackVH_DeletionCanRAUW) {
David Blaikie774b5842015-08-03 22:30:24 +0000311 class RecoveringVH final : public CallbackVH {
Dan Gohman745ad442009-05-02 21:10:48 +0000312 public:
313 int DeletedCalls;
314 Value *AURWArgument;
Owen Anderson53a52212009-07-13 04:09:18 +0000315 LLVMContext *Context;
Dan Gohman745ad442009-05-02 21:10:48 +0000316
Mehdi Amini03b42e42016-04-14 21:59:01 +0000317 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) {}
Dan Gohman745ad442009-05-02 21:10:48 +0000323
324 private:
Alexander Kornienkof817c1c2015-04-11 02:11:45 +0000325 void deleted() override {
Mehdi Amini03b42e42016-04-14 21:59:01 +0000326 getValPtr()->replaceAllUsesWith(
327 Constant::getNullValue(Type::getInt32Ty(*Context)));
Craig Topper66f09ad2014-06-08 22:29:17 +0000328 setValPtr(nullptr);
Dan Gohman745ad442009-05-02 21:10:48 +0000329 }
Alexander Kornienkof817c1c2015-04-11 02:11:45 +0000330 void allUsesReplacedWith(Value *new_value) override {
Craig Topper66f09ad2014-06-08 22:29:17 +0000331 ASSERT_TRUE(nullptr != getValPtr());
Daniel Dunbar5d816542009-05-18 03:44:24 +0000332 EXPECT_EQ(1U, getValPtr()->getNumUses());
Craig Topper66f09ad2014-06-08 22:29:17 +0000333 EXPECT_EQ(nullptr, AURWArgument);
Dan Gohman745ad442009-05-02 21:10:48 +0000334 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.
Mehdi Amini03b42e42016-04-14 21:59:01 +0000340 RecoveringVH RVH(Context);
341 RVH = RecoveringVH(Context, BitcastV.get());
342 std::unique_ptr<BinaryOperator> BitcastUser(BinaryOperator::CreateAdd(
343 RVH, Constant::getNullValue(Type::getInt32Ty(Context))));
Dan Gohman745ad442009-05-02 21:10:48 +0000344 EXPECT_EQ(BitcastV.get(), BitcastUser->getOperand(0));
345 BitcastV.reset(); // Would crash without the ValueHandler.
Mehdi Amini03b42e42016-04-14 21:59:01 +0000346 EXPECT_EQ(Constant::getNullValue(Type::getInt32Ty(Context)),
347 RVH.AURWArgument);
348 EXPECT_EQ(Constant::getNullValue(Type::getInt32Ty(Context)),
Owen Anderson53a52212009-07-13 04:09:18 +0000349 BitcastUser->getOperand(0));
Dan Gohman745ad442009-05-02 21:10:48 +0000350}
351
Jeffrey Yasskin406ac812009-10-12 17:43:32 +0000352TEST_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
David Blaikie774b5842015-08-03 22:30:24 +0000361 class DestroyingVH final : public CallbackVH {
Jeffrey Yasskin406ac812009-10-12 17:43:32 +0000362 public:
Sanjoy Dase6bca0e2017-05-01 17:07:49 +0000363 std::unique_ptr<WeakTrackingVH> ToClear[2];
Jeffrey Yasskin406ac812009-10-12 17:43:32 +0000364 DestroyingVH(Value *V) {
Sanjoy Dase6bca0e2017-05-01 17:07:49 +0000365 ToClear[0].reset(new WeakTrackingVH(V));
Jeffrey Yasskin406ac812009-10-12 17:43:32 +0000366 setValPtr(V);
Sanjoy Dase6bca0e2017-05-01 17:07:49 +0000367 ToClear[1].reset(new WeakTrackingVH(V));
Jeffrey Yasskin406ac812009-10-12 17:43:32 +0000368 }
Alexander Kornienkof817c1c2015-04-11 02:11:45 +0000369 void deleted() override {
Jeffrey Yasskin406ac812009-10-12 17:43:32 +0000370 ToClear[0].reset();
371 ToClear[1].reset();
372 CallbackVH::deleted();
373 }
Alexander Kornienkof817c1c2015-04-11 02:11:45 +0000374 void allUsesReplacedWith(Value *) override {
Jeffrey Yasskin406ac812009-10-12 17:43:32 +0000375 ToClear[0].reset();
376 ToClear[1].reset();
377 }
378 };
379
380 {
Sanjoy Dase6bca0e2017-05-01 17:07:49 +0000381 WeakTrackingVH ShouldBeVisited1(BitcastV.get());
Jeffrey Yasskin406ac812009-10-12 17:43:32 +0000382 DestroyingVH C(BitcastV.get());
Sanjoy Dase6bca0e2017-05-01 17:07:49 +0000383 WeakTrackingVH ShouldBeVisited2(BitcastV.get());
Jeffrey Yasskin406ac812009-10-12 17:43:32 +0000384
385 BitcastV->replaceAllUsesWith(ConstantV);
386 EXPECT_EQ(ConstantV, static_cast<Value*>(ShouldBeVisited1));
387 EXPECT_EQ(ConstantV, static_cast<Value*>(ShouldBeVisited2));
388 }
389
390 {
Sanjoy Dase6bca0e2017-05-01 17:07:49 +0000391 WeakTrackingVH ShouldBeVisited1(BitcastV.get());
Jeffrey Yasskin406ac812009-10-12 17:43:32 +0000392 DestroyingVH C(BitcastV.get());
Sanjoy Dase6bca0e2017-05-01 17:07:49 +0000393 WeakTrackingVH ShouldBeVisited2(BitcastV.get());
Jeffrey Yasskin406ac812009-10-12 17:43:32 +0000394
395 BitcastV.reset();
Craig Topper66f09ad2014-06-08 22:29:17 +0000396 EXPECT_EQ(nullptr, static_cast<Value*>(ShouldBeVisited1));
397 EXPECT_EQ(nullptr, static_cast<Value*>(ShouldBeVisited2));
Jeffrey Yasskin406ac812009-10-12 17:43:32 +0000398 }
399}
400
401TEST_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
David Blaikie774b5842015-08-03 22:30:24 +0000406 class ClearingVH final : public CallbackVH {
Jeffrey Yasskin406ac812009-10-12 17:43:32 +0000407 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
Alexander Kornienkof817c1c2015-04-11 02:11:45 +0000416 void deleted() override {
Craig Topper66f09ad2014-06-08 22:29:17 +0000417 *ToClear[0] = nullptr;
418 *ToClear[1] = nullptr;
Jeffrey Yasskin406ac812009-10-12 17:43:32 +0000419 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
Chandler Carruth942c3142017-01-24 12:34:47 +0000432TEST_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
448TEST_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
455TEST_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
488TEST_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#ifdef NDEBUG
495
496TEST_F(ValueHandle, PoisoningVH_ReducesToPointer) {
497 EXPECT_EQ(sizeof(CastInst *), sizeof(PoisoningVH<CastInst>));
498}
499
500#else // !NDEBUG
501
Sanjoy Das8a6238202017-05-01 16:28:58 +0000502TEST_F(ValueHandle, TrackingVH_Tracks) {
503 TrackingVH<Value> VH(BitcastV.get());
504 BitcastV->replaceAllUsesWith(ConstantV);
505 EXPECT_EQ(VH, ConstantV);
506}
507
Chandler Carruth942c3142017-01-24 12:34:47 +0000508#ifdef GTEST_HAS_DEATH_TEST
509
510TEST_F(ValueHandle, PoisoningVH_Asserts) {
511 PoisoningVH<Value> VH(BitcastV.get());
512
513 // The poisoned handle shouldn't assert when the value is deleted.
514 BitcastV.reset(new BitCastInst(ConstantV, Type::getInt32Ty(Context)));
515 // But should when we access the handle.
516 EXPECT_DEATH((void)*VH, "Accessed a poisoned value handle!");
517
518 // Now check that poison catches RAUW.
519 VH = BitcastV.get();
520 // The replace doesn't trigger anything immediately.
521 BitcastV->replaceAllUsesWith(ConstantV);
522 // But a use does.
523 EXPECT_DEATH((void)*VH, "Accessed a poisoned value handle!");
524
525 // Don't clear anything out here as destroying the handles should be fine.
526}
527
Sanjoy Das8a6238202017-05-01 16:28:58 +0000528TEST_F(ValueHandle, TrackingVH_Asserts) {
529 {
530 TrackingVH<Value> VH(BitcastV.get());
531
532 // The tracking handle shouldn't assert when the value is deleted.
533 BitcastV.reset(new BitCastInst(ConstantV, Type::getInt32Ty(Context)));
534 // But should when we access the handle.
535 EXPECT_DEATH((void)*VH,
536 "TrackingVH must be non-null and valid on dereference!");
537 }
538
539 {
540 TrackingVH<Instruction> VH(BitcastV.get());
541
542 BitcastV->replaceAllUsesWith(ConstantV);
543 EXPECT_DEATH((void)*VH,
544 "Tracked Value was replaced by one with an invalid type!");
545 }
546}
547
Chandler Carruth942c3142017-01-24 12:34:47 +0000548#endif // GTEST_HAS_DEATH_TEST
549
550#endif // NDEBUG
Jeffrey Yasskin41f24772009-04-27 20:32:07 +0000551}