Recommit "rL366894: [yaml2obj] - Allow custom fields for the SHT_UNDEF sections."
[llvm-complete.git] / unittests / IR / ValueHandleTest.cpp
blobb799ff0958065465e244b2062b549e381f54ff83
1 //===- ValueHandleTest.cpp - ValueHandle tests ----------------------------===//
2 //
3 // 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
6 //
7 //===----------------------------------------------------------------------===//
9 #include "llvm/IR/ValueHandle.h"
10 #include "llvm/IR/Constants.h"
11 #include "llvm/IR/Instructions.h"
12 #include "llvm/IR/LLVMContext.h"
13 #include "gtest/gtest.h"
14 #include <memory>
16 using namespace llvm;
18 namespace {
20 class ValueHandle : public testing::Test {
21 protected:
22 LLVMContext Context;
23 Constant *ConstantV;
24 std::unique_ptr<BitCastInst> BitcastV;
26 ValueHandle()
27 : ConstantV(ConstantInt::get(Type::getInt32Ty(Context), 0)),
28 BitcastV(new BitCastInst(ConstantV, Type::getInt32Ty(Context))) {}
31 class ConcreteCallbackVH final : public CallbackVH {
32 public:
33 ConcreteCallbackVH(Value *V) : CallbackVH(V) {}
36 TEST_F(ValueHandle, WeakVH_BasicOperation) {
37 WeakVH WVH(BitcastV.get());
38 EXPECT_EQ(BitcastV.get(), WVH);
39 WVH = ConstantV;
40 EXPECT_EQ(ConstantV, WVH);
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());
47 WVH = BitcastV.get();
48 BitcastV->replaceAllUsesWith(ConstantV);
49 EXPECT_EQ(WVH, BitcastV.get());
50 BitcastV.reset();
51 EXPECT_EQ(WVH, nullptr);
54 TEST_F(ValueHandle, WeakTrackingVH_BasicOperation) {
55 WeakTrackingVH WVH(BitcastV.get());
56 EXPECT_EQ(BitcastV.get(), WVH);
57 WVH = ConstantV;
58 EXPECT_EQ(ConstantV, WVH);
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());
66 TEST_F(ValueHandle, WeakTrackingVH_Comparisons) {
67 WeakTrackingVH BitcastWVH(BitcastV.get());
68 WeakTrackingVH ConstantWVH(ConstantV);
70 EXPECT_TRUE(BitcastWVH == BitcastWVH);
71 EXPECT_TRUE(BitcastV.get() == BitcastWVH);
72 EXPECT_TRUE(BitcastWVH == BitcastV.get());
73 EXPECT_FALSE(BitcastWVH == ConstantWVH);
75 EXPECT_TRUE(BitcastWVH != ConstantWVH);
76 EXPECT_TRUE(BitcastV.get() != ConstantWVH);
77 EXPECT_TRUE(BitcastWVH != ConstantV);
78 EXPECT_FALSE(BitcastWVH != BitcastWVH);
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);
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);
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);
99 TEST_F(ValueHandle, WeakTrackingVH_FollowsRAUW) {
100 WeakTrackingVH WVH(BitcastV.get());
101 WeakTrackingVH WVH_Copy(WVH);
102 WeakTrackingVH WVH_Recreated(BitcastV.get());
103 BitcastV->replaceAllUsesWith(ConstantV);
104 EXPECT_EQ(ConstantV, WVH);
105 EXPECT_EQ(ConstantV, WVH_Copy);
106 EXPECT_EQ(ConstantV, WVH_Recreated);
109 TEST_F(ValueHandle, WeakTrackingVH_NullOnDeletion) {
110 WeakTrackingVH WVH(BitcastV.get());
111 WeakTrackingVH WVH_Copy(WVH);
112 WeakTrackingVH WVH_Recreated(BitcastV.get());
113 BitcastV.reset();
114 Value *null_value = nullptr;
115 EXPECT_EQ(null_value, WVH);
116 EXPECT_EQ(null_value, WVH_Copy);
117 EXPECT_EQ(null_value, WVH_Recreated);
121 TEST_F(ValueHandle, AssertingVH_BasicOperation) {
122 AssertingVH<CastInst> AVH(BitcastV.get());
123 CastInst *implicit_to_exact_type = AVH;
124 (void)implicit_to_exact_type; // Avoid warning.
126 AssertingVH<Value> GenericAVH(BitcastV.get());
127 EXPECT_EQ(BitcastV.get(), GenericAVH);
128 GenericAVH = ConstantV;
129 EXPECT_EQ(ConstantV, GenericAVH);
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());
137 TEST_F(ValueHandle, AssertingVH_Const) {
138 const CastInst *ConstBitcast = BitcastV.get();
139 AssertingVH<const CastInst> AVH(ConstBitcast);
140 const CastInst *implicit_to_exact_type = AVH;
141 (void)implicit_to_exact_type; // Avoid warning.
144 TEST_F(ValueHandle, AssertingVH_Comparisons) {
145 AssertingVH<Value> BitcastAVH(BitcastV.get());
146 AssertingVH<Value> ConstantAVH(ConstantV);
148 EXPECT_TRUE(BitcastAVH == BitcastAVH);
149 EXPECT_TRUE(BitcastV.get() == BitcastAVH);
150 EXPECT_TRUE(BitcastAVH == BitcastV.get());
151 EXPECT_FALSE(BitcastAVH == ConstantAVH);
153 EXPECT_TRUE(BitcastAVH != ConstantAVH);
154 EXPECT_TRUE(BitcastV.get() != ConstantAVH);
155 EXPECT_TRUE(BitcastAVH != ConstantV);
156 EXPECT_FALSE(BitcastAVH != BitcastAVH);
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);
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);
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);
177 TEST_F(ValueHandle, AssertingVH_DoesNotFollowRAUW) {
178 AssertingVH<Value> AVH(BitcastV.get());
179 BitcastV->replaceAllUsesWith(ConstantV);
180 EXPECT_EQ(BitcastV.get(), AVH);
183 #ifdef NDEBUG
185 TEST_F(ValueHandle, AssertingVH_ReducesToPointer) {
186 EXPECT_EQ(sizeof(CastInst *), sizeof(AssertingVH<CastInst>));
189 #else // !NDEBUG
191 #ifdef GTEST_HAS_DEATH_TEST
193 TEST_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);
198 AVH = nullptr;
199 EXPECT_DEATH({BitcastV.reset();},
200 "An asserting value handle still pointed to this value!");
201 Copy = nullptr;
202 BitcastV.reset();
205 #endif // GTEST_HAS_DEATH_TEST
207 #endif // NDEBUG
209 TEST_F(ValueHandle, CallbackVH_BasicOperation) {
210 ConcreteCallbackVH CVH(BitcastV.get());
211 EXPECT_EQ(BitcastV.get(), CVH);
212 CVH = ConstantV;
213 EXPECT_EQ(ConstantV, CVH);
215 // Make sure I can call a method on the underlying Value. It
216 // doesn't matter which method.
217 EXPECT_EQ(Type::getInt32Ty(Context), CVH->getType());
218 EXPECT_EQ(Type::getInt32Ty(Context), (*CVH).getType());
221 TEST_F(ValueHandle, CallbackVH_Comparisons) {
222 ConcreteCallbackVH BitcastCVH(BitcastV.get());
223 ConcreteCallbackVH ConstantCVH(ConstantV);
225 EXPECT_TRUE(BitcastCVH == BitcastCVH);
226 EXPECT_TRUE(BitcastV.get() == BitcastCVH);
227 EXPECT_TRUE(BitcastCVH == BitcastV.get());
228 EXPECT_FALSE(BitcastCVH == ConstantCVH);
230 EXPECT_TRUE(BitcastCVH != ConstantCVH);
231 EXPECT_TRUE(BitcastV.get() != ConstantCVH);
232 EXPECT_TRUE(BitcastCVH != ConstantV);
233 EXPECT_FALSE(BitcastCVH != BitcastCVH);
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);
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);
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);
254 TEST_F(ValueHandle, CallbackVH_CallbackOnDeletion) {
255 class RecordingVH final : public CallbackVH {
256 public:
257 int DeletedCalls;
258 int AURWCalls;
260 RecordingVH() : DeletedCalls(0), AURWCalls(0) {}
261 RecordingVH(Value *V) : CallbackVH(V), DeletedCalls(0), AURWCalls(0) {}
263 private:
264 void deleted() override {
265 DeletedCalls++;
266 CallbackVH::deleted();
268 void allUsesReplacedWith(Value *) override { AURWCalls++; }
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);
280 TEST_F(ValueHandle, CallbackVH_CallbackOnRAUW) {
281 class RecordingVH final : public CallbackVH {
282 public:
283 int DeletedCalls;
284 Value *AURWArgument;
286 RecordingVH() : DeletedCalls(0), AURWArgument(nullptr) {}
287 RecordingVH(Value *V)
288 : CallbackVH(V), DeletedCalls(0), AURWArgument(nullptr) {}
290 private:
291 void deleted() override {
292 DeletedCalls++;
293 CallbackVH::deleted();
295 void allUsesReplacedWith(Value *new_value) override {
296 EXPECT_EQ(nullptr, AURWArgument);
297 AURWArgument = new_value;
301 RecordingVH RVH;
302 RVH = BitcastV.get();
303 EXPECT_EQ(0, RVH.DeletedCalls);
304 EXPECT_EQ(nullptr, RVH.AURWArgument);
305 BitcastV->replaceAllUsesWith(ConstantV);
306 EXPECT_EQ(0, RVH.DeletedCalls);
307 EXPECT_EQ(ConstantV, RVH.AURWArgument);
310 TEST_F(ValueHandle, CallbackVH_DeletionCanRAUW) {
311 class RecoveringVH final : public CallbackVH {
312 public:
313 int DeletedCalls;
314 Value *AURWArgument;
315 LLVMContext *Context;
317 RecoveringVH(LLVMContext &TheContext)
318 : DeletedCalls(0), AURWArgument(nullptr), Context(&TheContext) {}
320 RecoveringVH(LLVMContext &TheContext, Value *V)
321 : CallbackVH(V), DeletedCalls(0), AURWArgument(nullptr),
322 Context(&TheContext) {}
324 private:
325 void deleted() override {
326 getValPtr()->replaceAllUsesWith(
327 Constant::getNullValue(Type::getInt32Ty(*Context)));
328 setValPtr(nullptr);
330 void allUsesReplacedWith(Value *new_value) override {
331 ASSERT_TRUE(nullptr != getValPtr());
332 EXPECT_EQ(1U, getValPtr()->getNumUses());
333 EXPECT_EQ(nullptr, AURWArgument);
334 AURWArgument = new_value;
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.
340 RecoveringVH RVH(Context);
341 RVH = RecoveringVH(Context, BitcastV.get());
342 std::unique_ptr<BinaryOperator> BitcastUser(BinaryOperator::CreateAdd(
343 RVH, Constant::getNullValue(Type::getInt32Ty(Context))));
344 EXPECT_EQ(BitcastV.get(), BitcastUser->getOperand(0));
345 BitcastV.reset(); // Would crash without the ValueHandler.
346 EXPECT_EQ(Constant::getNullValue(Type::getInt32Ty(Context)),
347 RVH.AURWArgument);
348 EXPECT_EQ(Constant::getNullValue(Type::getInt32Ty(Context)),
349 BitcastUser->getOperand(0));
352 TEST_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.
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.
361 class DestroyingVH final : public CallbackVH {
362 public:
363 std::unique_ptr<WeakTrackingVH> ToClear[2];
364 DestroyingVH(Value *V) {
365 ToClear[0].reset(new WeakTrackingVH(V));
366 setValPtr(V);
367 ToClear[1].reset(new WeakTrackingVH(V));
369 void deleted() override {
370 ToClear[0].reset();
371 ToClear[1].reset();
372 CallbackVH::deleted();
374 void allUsesReplacedWith(Value *) override {
375 ToClear[0].reset();
376 ToClear[1].reset();
381 WeakTrackingVH ShouldBeVisited1(BitcastV.get());
382 DestroyingVH C(BitcastV.get());
383 WeakTrackingVH ShouldBeVisited2(BitcastV.get());
385 BitcastV->replaceAllUsesWith(ConstantV);
386 EXPECT_EQ(ConstantV, static_cast<Value*>(ShouldBeVisited1));
387 EXPECT_EQ(ConstantV, static_cast<Value*>(ShouldBeVisited2));
391 WeakTrackingVH ShouldBeVisited1(BitcastV.get());
392 DestroyingVH C(BitcastV.get());
393 WeakTrackingVH ShouldBeVisited2(BitcastV.get());
395 BitcastV.reset();
396 EXPECT_EQ(nullptr, static_cast<Value*>(ShouldBeVisited1));
397 EXPECT_EQ(nullptr, static_cast<Value*>(ShouldBeVisited2));
401 TEST_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.
406 class ClearingVH final : public CallbackVH {
407 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;
416 void deleted() override {
417 *ToClear[0] = nullptr;
418 *ToClear[1] = nullptr;
419 CallbackVH::deleted();
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();
432 TEST_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.
437 PoisoningVH<Value> GenericVH(BitcastV.get());
438 EXPECT_EQ(BitcastV.get(), GenericVH);
439 GenericVH = ConstantV;
440 EXPECT_EQ(ConstantV, GenericVH);
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());
448 TEST_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.
455 TEST_F(ValueHandle, PoisoningVH_Comparisons) {
456 PoisoningVH<Value> BitcastVH(BitcastV.get());
457 PoisoningVH<Value> ConstantVH(ConstantV);
459 EXPECT_TRUE(BitcastVH == BitcastVH);
460 EXPECT_TRUE(BitcastV.get() == BitcastVH);
461 EXPECT_TRUE(BitcastVH == BitcastV.get());
462 EXPECT_FALSE(BitcastVH == ConstantVH);
464 EXPECT_TRUE(BitcastVH != ConstantVH);
465 EXPECT_TRUE(BitcastV.get() != ConstantVH);
466 EXPECT_TRUE(BitcastVH != ConstantV);
467 EXPECT_FALSE(BitcastVH != BitcastVH);
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);
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);
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);
488 TEST_F(ValueHandle, PoisoningVH_DoesNotFollowRAUW) {
489 PoisoningVH<Value> VH(BitcastV.get());
490 BitcastV->replaceAllUsesWith(ConstantV);
491 EXPECT_TRUE(DenseMapInfo<PoisoningVH<Value>>::isEqual(VH, BitcastV.get()));
494 #ifdef NDEBUG
496 TEST_F(ValueHandle, PoisoningVH_ReducesToPointer) {
497 EXPECT_EQ(sizeof(CastInst *), sizeof(PoisoningVH<CastInst>));
500 #else // !NDEBUG
502 TEST_F(ValueHandle, TrackingVH_Tracks) {
503 TrackingVH<Value> VH(BitcastV.get());
504 BitcastV->replaceAllUsesWith(ConstantV);
505 EXPECT_EQ(VH, ConstantV);
508 #ifdef GTEST_HAS_DEATH_TEST
510 TEST_F(ValueHandle, PoisoningVH_Asserts) {
511 PoisoningVH<Value> VH(BitcastV.get());
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!");
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!");
525 // Don't clear anything out here as destroying the handles should be fine.
528 TEST_F(ValueHandle, TrackingVH_Asserts) {
530 TrackingVH<Value> VH(BitcastV.get());
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!");
540 TrackingVH<Instruction> VH(BitcastV.get());
542 BitcastV->replaceAllUsesWith(ConstantV);
543 EXPECT_DEATH((void)*VH,
544 "Tracked Value was replaced by one with an invalid type!");
548 #endif // GTEST_HAS_DEATH_TEST
550 #endif // NDEBUG