llvm-project

Форк
0
/
ValueHandleTest.cpp 
578 строк · 17.8 Кб
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
//===----------------------------------------------------------------------===//
8

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>
15

16
using namespace llvm;
17

18
namespace {
19

20
class ValueHandle : public testing::Test {
21
protected:
22
  LLVMContext Context;
23
  Constant *ConstantV;
24
  std::unique_ptr<BitCastInst> BitcastV;
25

26
  ValueHandle()
27
      : ConstantV(ConstantInt::get(Type::getInt32Ty(Context), 0)),
28
        BitcastV(new BitCastInst(ConstantV, Type::getInt32Ty(Context))) {}
29
};
30

31
class ConcreteCallbackVH final : public CallbackVH {
32
public:
33
  ConcreteCallbackVH(Value *V) : CallbackVH(V) {}
34
};
35

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);
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

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);
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());
64
}
65

66
TEST_F(ValueHandle, WeakTrackingVH_Comparisons) {
67
  WeakTrackingVH BitcastWVH(BitcastV.get());
68
  WeakTrackingVH ConstantWVH(ConstantV);
69

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

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);
107
}
108

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);
118
}
119

120

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.
125

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

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.
142
}
143

144
TEST_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

177
TEST_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

185
TEST_F(ValueHandle, AssertingVH_ReducesToPointer) {
186
  EXPECT_EQ(sizeof(CastInst *), sizeof(AssertingVH<CastInst>));
187
}
188

189
#elif LLVM_ENABLE_ABI_BREAKING_CHECKS // && !NDEBUG
190

191
#ifdef GTEST_HAS_DEATH_TEST
192

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();
203
}
204

205
#endif  // GTEST_HAS_DEATH_TEST
206

207
#endif  // NDEBUG
208

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);
214

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());
219
}
220

221
TEST_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

254
TEST_F(ValueHandle, CallbackVH_CallbackOnDeletion) {
255
  class RecordingVH final : public CallbackVH {
256
  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:
264
    void deleted() override {
265
      DeletedCalls++;
266
      CallbackVH::deleted();
267
    }
268
    void allUsesReplacedWith(Value *) override { AURWCalls++; }
269
  };
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

280
TEST_F(ValueHandle, CallbackVH_CallbackOnRAUW) {
281
  class RecordingVH final : public CallbackVH {
282
  public:
283
    int DeletedCalls;
284
    Value *AURWArgument;
285

286
    RecordingVH() : DeletedCalls(0), AURWArgument(nullptr) {}
287
    RecordingVH(Value *V)
288
      : CallbackVH(V), DeletedCalls(0), AURWArgument(nullptr) {}
289

290
  private:
291
    void deleted() override {
292
      DeletedCalls++;
293
      CallbackVH::deleted();
294
    }
295
    void allUsesReplacedWith(Value *new_value) override {
296
      EXPECT_EQ(nullptr, AURWArgument);
297
      AURWArgument = new_value;
298
    }
299
  };
300

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);
308
}
309

310
TEST_F(ValueHandle, CallbackVH_DeletionCanRAUW) {
311
  class RecoveringVH final : public CallbackVH {
312
  public:
313
    int DeletedCalls;
314
    Value *AURWArgument;
315
    LLVMContext *Context;
316

317
    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) {}
323

324
  private:
325
    void deleted() override {
326
      getValPtr()->replaceAllUsesWith(
327
          Constant::getNullValue(Type::getInt32Ty(*Context)));
328
      setValPtr(nullptr);
329
    }
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;
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.
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));
350
}
351

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.
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

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));
368
    }
369
    void deleted() override {
370
      ToClear[0].reset();
371
      ToClear[1].reset();
372
      CallbackVH::deleted();
373
    }
374
    void allUsesReplacedWith(Value *) override {
375
      ToClear[0].reset();
376
      ToClear[1].reset();
377
    }
378
  };
379

380
  {
381
    WeakTrackingVH ShouldBeVisited1(BitcastV.get());
382
    DestroyingVH C(BitcastV.get());
383
    WeakTrackingVH ShouldBeVisited2(BitcastV.get());
384

385
    BitcastV->replaceAllUsesWith(ConstantV);
386
    EXPECT_EQ(ConstantV, static_cast<Value*>(ShouldBeVisited1));
387
    EXPECT_EQ(ConstantV, static_cast<Value*>(ShouldBeVisited2));
388
  }
389

390
  {
391
    WeakTrackingVH ShouldBeVisited1(BitcastV.get());
392
    DestroyingVH C(BitcastV.get());
393
    WeakTrackingVH ShouldBeVisited2(BitcastV.get());
394

395
    BitcastV.reset();
396
    EXPECT_EQ(nullptr, static_cast<Value*>(ShouldBeVisited1));
397
    EXPECT_EQ(nullptr, static_cast<Value*>(ShouldBeVisited2));
398
  }
399
}
400

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.
405

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;
414
    }
415

416
    void deleted() override {
417
      *ToClear[0] = nullptr;
418
      *ToClear[1] = nullptr;
419
      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

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.
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

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.
453
}
454

455
TEST_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

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()));
492
}
493

494
TEST_F(ValueHandle, AssertingVH_DenseMap) {
495
  DenseMap<AssertingVH<Value>, int> Map;
496
  Map.insert({BitcastV.get(), 1});
497
  Map.insert({ConstantV, 2});
498
  // These will create a temporary AssertingVH during lookup.
499
  EXPECT_TRUE(Map.contains(BitcastV.get()));
500
  EXPECT_TRUE(Map.contains(ConstantV));
501
  // These will not create a temporary AssertingVH.
502
  EXPECT_TRUE(Map.find_as(BitcastV.get()) != Map.end());
503
  EXPECT_TRUE(Map.find_as(ConstantV) != Map.end());
504
}
505

506
TEST_F(ValueHandle, PoisoningVH_DenseMap) {
507
  DenseMap<PoisoningVH<Value>, int> Map;
508
  Map.insert({BitcastV.get(), 1});
509
  Map.insert({ConstantV, 2});
510
  // These will create a temporary PoisoningVH during lookup.
511
  EXPECT_TRUE(Map.contains(BitcastV.get()));
512
  EXPECT_TRUE(Map.contains(ConstantV));
513
  // These will not create a temporary PoisoningVH.
514
  EXPECT_TRUE(Map.find_as(BitcastV.get()) != Map.end());
515
  EXPECT_TRUE(Map.find_as(ConstantV) != Map.end());
516
}
517

518
#ifdef NDEBUG
519

520
TEST_F(ValueHandle, PoisoningVH_ReducesToPointer) {
521
  EXPECT_EQ(sizeof(CastInst *), sizeof(PoisoningVH<CastInst>));
522
}
523

524
#else // !NDEBUG
525

526
TEST_F(ValueHandle, TrackingVH_Tracks) {
527
  TrackingVH<Value> VH(BitcastV.get());
528
  BitcastV->replaceAllUsesWith(ConstantV);
529
  EXPECT_EQ(VH, ConstantV);
530
}
531

532
#ifdef GTEST_HAS_DEATH_TEST
533
#if LLVM_ENABLE_ABI_BREAKING_CHECKS
534

535
TEST_F(ValueHandle, PoisoningVH_Asserts) {
536
  PoisoningVH<Value> VH(BitcastV.get());
537

538
  // The poisoned handle shouldn't assert when the value is deleted.
539
  BitcastV.reset(new BitCastInst(ConstantV, Type::getInt32Ty(Context)));
540
  // But should when we access the handle.
541
  EXPECT_DEATH((void)*VH, "Accessed a poisoned value handle!");
542

543
  // Now check that poison catches RAUW.
544
  VH = BitcastV.get();
545
  // The replace doesn't trigger anything immediately.
546
  BitcastV->replaceAllUsesWith(ConstantV);
547
  // But a use does.
548
  EXPECT_DEATH((void)*VH, "Accessed a poisoned value handle!");
549

550
  // Don't clear anything out here as destroying the handles should be fine.
551
}
552

553
#endif // LLVM_ENABLE_ABI_BREAKING_CHECKS
554

555
TEST_F(ValueHandle, TrackingVH_Asserts) {
556
  {
557
    TrackingVH<Value> VH(BitcastV.get());
558

559
    // The tracking handle shouldn't assert when the value is deleted.
560
    BitcastV.reset(new BitCastInst(ConstantV, Type::getInt32Ty(Context)));
561
    // But should when we access the handle.
562
    EXPECT_DEATH((void)*VH,
563
                 "TrackingVH must be non-null and valid on dereference!");
564
  }
565

566
  {
567
    TrackingVH<Instruction> VH(BitcastV.get());
568

569
    BitcastV->replaceAllUsesWith(ConstantV);
570
    EXPECT_DEATH((void)*VH,
571
                 "Tracked Value was replaced by one with an invalid type!");
572
  }
573
}
574

575
#endif // GTEST_HAS_DEATH_TEST
576

577
#endif // NDEBUG
578
}
579

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.