summaryrefslogtreecommitdiff
path: root/unittests/Support/ValueHandleTest.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'unittests/Support/ValueHandleTest.cpp')
-rw-r--r--unittests/Support/ValueHandleTest.cpp408
1 files changed, 0 insertions, 408 deletions
diff --git a/unittests/Support/ValueHandleTest.cpp b/unittests/Support/ValueHandleTest.cpp
deleted file mode 100644
index 05aafa2d05..0000000000
--- a/unittests/Support/ValueHandleTest.cpp
+++ /dev/null
@@ -1,408 +0,0 @@
-//===- llvm/unittest/Support/ValueHandleTest.cpp - ValueHandle tests --------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Support/ValueHandle.h"
-#include "llvm/ADT/OwningPtr.h"
-#include "llvm/IR/Constants.h"
-#include "llvm/IR/Instructions.h"
-#include "llvm/IR/LLVMContext.h"
-#include "gtest/gtest.h"
-#include <memory>
-
-using namespace llvm;
-
-namespace {
-
-class ValueHandle : public testing::Test {
-protected:
- Constant *ConstantV;
- std::auto_ptr<BitCastInst> BitcastV;
-
- ValueHandle() :
- ConstantV(ConstantInt::get(Type::getInt32Ty(getGlobalContext()), 0)),
- BitcastV(new BitCastInst(ConstantV, Type::getInt32Ty(getGlobalContext()))) {
- }
-};
-
-class ConcreteCallbackVH : public CallbackVH {
-public:
- ConcreteCallbackVH(Value *V) : CallbackVH(V) {}
-};
-
-TEST_F(ValueHandle, WeakVH_BasicOperation) {
- WeakVH WVH(BitcastV.get());
- EXPECT_EQ(BitcastV.get(), WVH);
- WVH = ConstantV;
- EXPECT_EQ(ConstantV, WVH);
-
- // Make sure I can call a method on the underlying Value. It
- // doesn't matter which method.
- EXPECT_EQ(Type::getInt32Ty(getGlobalContext()), WVH->getType());
- EXPECT_EQ(Type::getInt32Ty(getGlobalContext()), (*WVH).getType());
-}
-
-TEST_F(ValueHandle, WeakVH_Comparisons) {
- WeakVH BitcastWVH(BitcastV.get());
- WeakVH ConstantWVH(ConstantV);
-
- EXPECT_TRUE(BitcastWVH == BitcastWVH);
- EXPECT_TRUE(BitcastV.get() == BitcastWVH);
- EXPECT_TRUE(BitcastWVH == BitcastV.get());
- EXPECT_FALSE(BitcastWVH == ConstantWVH);
-
- EXPECT_TRUE(BitcastWVH != ConstantWVH);
- EXPECT_TRUE(BitcastV.get() != ConstantWVH);
- EXPECT_TRUE(BitcastWVH != ConstantV);
- EXPECT_FALSE(BitcastWVH != BitcastWVH);
-
- // Cast to Value* so comparisons work.
- Value *BV = BitcastV.get();
- Value *CV = ConstantV;
- EXPECT_EQ(BV < CV, BitcastWVH < ConstantWVH);
- EXPECT_EQ(BV <= CV, BitcastWVH <= ConstantWVH);
- EXPECT_EQ(BV > CV, BitcastWVH > ConstantWVH);
- EXPECT_EQ(BV >= CV, BitcastWVH >= ConstantWVH);
-
- EXPECT_EQ(BV < CV, BitcastV.get() < ConstantWVH);
- EXPECT_EQ(BV <= CV, BitcastV.get() <= ConstantWVH);
- EXPECT_EQ(BV > CV, BitcastV.get() > ConstantWVH);
- EXPECT_EQ(BV >= CV, BitcastV.get() >= ConstantWVH);
-
- EXPECT_EQ(BV < CV, BitcastWVH < ConstantV);
- EXPECT_EQ(BV <= CV, BitcastWVH <= ConstantV);
- EXPECT_EQ(BV > CV, BitcastWVH > ConstantV);
- EXPECT_EQ(BV >= CV, BitcastWVH >= ConstantV);
-}
-
-TEST_F(ValueHandle, WeakVH_FollowsRAUW) {
- WeakVH WVH(BitcastV.get());
- WeakVH WVH_Copy(WVH);
- WeakVH WVH_Recreated(BitcastV.get());
- BitcastV->replaceAllUsesWith(ConstantV);
- EXPECT_EQ(ConstantV, WVH);
- EXPECT_EQ(ConstantV, WVH_Copy);
- EXPECT_EQ(ConstantV, WVH_Recreated);
-}
-
-TEST_F(ValueHandle, WeakVH_NullOnDeletion) {
- WeakVH WVH(BitcastV.get());
- WeakVH WVH_Copy(WVH);
- WeakVH WVH_Recreated(BitcastV.get());
- BitcastV.reset();
- Value *null_value = NULL;
- EXPECT_EQ(null_value, WVH);
- EXPECT_EQ(null_value, WVH_Copy);
- EXPECT_EQ(null_value, WVH_Recreated);
-}
-
-
-TEST_F(ValueHandle, AssertingVH_BasicOperation) {
- AssertingVH<CastInst> AVH(BitcastV.get());
- CastInst *implicit_to_exact_type = AVH;
- (void)implicit_to_exact_type; // Avoid warning.
-
- AssertingVH<Value> GenericAVH(BitcastV.get());
- EXPECT_EQ(BitcastV.get(), GenericAVH);
- GenericAVH = ConstantV;
- EXPECT_EQ(ConstantV, GenericAVH);
-
- // Make sure I can call a method on the underlying CastInst. It
- // doesn't matter which method.
- EXPECT_FALSE(AVH->mayWriteToMemory());
- EXPECT_FALSE((*AVH).mayWriteToMemory());
-}
-
-TEST_F(ValueHandle, AssertingVH_Const) {
- const CastInst *ConstBitcast = BitcastV.get();
- AssertingVH<const CastInst> AVH(ConstBitcast);
- const CastInst *implicit_to_exact_type = AVH;
- (void)implicit_to_exact_type; // Avoid warning.
-}
-
-TEST_F(ValueHandle, AssertingVH_Comparisons) {
- AssertingVH<Value> BitcastAVH(BitcastV.get());
- AssertingVH<Value> ConstantAVH(ConstantV);
-
- EXPECT_TRUE(BitcastAVH == BitcastAVH);
- EXPECT_TRUE(BitcastV.get() == BitcastAVH);
- EXPECT_TRUE(BitcastAVH == BitcastV.get());
- EXPECT_FALSE(BitcastAVH == ConstantAVH);
-
- EXPECT_TRUE(BitcastAVH != ConstantAVH);
- EXPECT_TRUE(BitcastV.get() != ConstantAVH);
- EXPECT_TRUE(BitcastAVH != ConstantV);
- EXPECT_FALSE(BitcastAVH != BitcastAVH);
-
- // Cast to Value* so comparisons work.
- Value *BV = BitcastV.get();
- Value *CV = ConstantV;
- EXPECT_EQ(BV < CV, BitcastAVH < ConstantAVH);
- EXPECT_EQ(BV <= CV, BitcastAVH <= ConstantAVH);
- EXPECT_EQ(BV > CV, BitcastAVH > ConstantAVH);
- EXPECT_EQ(BV >= CV, BitcastAVH >= ConstantAVH);
-
- EXPECT_EQ(BV < CV, BitcastV.get() < ConstantAVH);
- EXPECT_EQ(BV <= CV, BitcastV.get() <= ConstantAVH);
- EXPECT_EQ(BV > CV, BitcastV.get() > ConstantAVH);
- EXPECT_EQ(BV >= CV, BitcastV.get() >= ConstantAVH);
-
- EXPECT_EQ(BV < CV, BitcastAVH < ConstantV);
- EXPECT_EQ(BV <= CV, BitcastAVH <= ConstantV);
- EXPECT_EQ(BV > CV, BitcastAVH > ConstantV);
- EXPECT_EQ(BV >= CV, BitcastAVH >= ConstantV);
-}
-
-TEST_F(ValueHandle, AssertingVH_DoesNotFollowRAUW) {
- AssertingVH<Value> AVH(BitcastV.get());
- BitcastV->replaceAllUsesWith(ConstantV);
- EXPECT_EQ(BitcastV.get(), AVH);
-}
-
-#ifdef NDEBUG
-
-TEST_F(ValueHandle, AssertingVH_ReducesToPointer) {
- EXPECT_EQ(sizeof(CastInst *), sizeof(AssertingVH<CastInst>));
-}
-
-#else // !NDEBUG
-
-#ifdef GTEST_HAS_DEATH_TEST
-
-TEST_F(ValueHandle, AssertingVH_Asserts) {
- AssertingVH<Value> AVH(BitcastV.get());
- EXPECT_DEATH({BitcastV.reset();},
- "An asserting value handle still pointed to this value!");
- AssertingVH<Value> Copy(AVH);
- AVH = NULL;
- EXPECT_DEATH({BitcastV.reset();},
- "An asserting value handle still pointed to this value!");
- Copy = NULL;
- BitcastV.reset();
-}
-
-#endif // GTEST_HAS_DEATH_TEST
-
-#endif // NDEBUG
-
-TEST_F(ValueHandle, CallbackVH_BasicOperation) {
- ConcreteCallbackVH CVH(BitcastV.get());
- EXPECT_EQ(BitcastV.get(), CVH);
- CVH = ConstantV;
- EXPECT_EQ(ConstantV, CVH);
-
- // Make sure I can call a method on the underlying Value. It
- // doesn't matter which method.
- EXPECT_EQ(Type::getInt32Ty(getGlobalContext()), CVH->getType());
- EXPECT_EQ(Type::getInt32Ty(getGlobalContext()), (*CVH).getType());
-}
-
-TEST_F(ValueHandle, CallbackVH_Comparisons) {
- ConcreteCallbackVH BitcastCVH(BitcastV.get());
- ConcreteCallbackVH ConstantCVH(ConstantV);
-
- EXPECT_TRUE(BitcastCVH == BitcastCVH);
- EXPECT_TRUE(BitcastV.get() == BitcastCVH);
- EXPECT_TRUE(BitcastCVH == BitcastV.get());
- EXPECT_FALSE(BitcastCVH == ConstantCVH);
-
- EXPECT_TRUE(BitcastCVH != ConstantCVH);
- EXPECT_TRUE(BitcastV.get() != ConstantCVH);
- EXPECT_TRUE(BitcastCVH != ConstantV);
- EXPECT_FALSE(BitcastCVH != BitcastCVH);
-
- // Cast to Value* so comparisons work.
- Value *BV = BitcastV.get();
- Value *CV = ConstantV;
- EXPECT_EQ(BV < CV, BitcastCVH < ConstantCVH);
- EXPECT_EQ(BV <= CV, BitcastCVH <= ConstantCVH);
- EXPECT_EQ(BV > CV, BitcastCVH > ConstantCVH);
- EXPECT_EQ(BV >= CV, BitcastCVH >= ConstantCVH);
-
- EXPECT_EQ(BV < CV, BitcastV.get() < ConstantCVH);
- EXPECT_EQ(BV <= CV, BitcastV.get() <= ConstantCVH);
- EXPECT_EQ(BV > CV, BitcastV.get() > ConstantCVH);
- EXPECT_EQ(BV >= CV, BitcastV.get() >= ConstantCVH);
-
- EXPECT_EQ(BV < CV, BitcastCVH < ConstantV);
- EXPECT_EQ(BV <= CV, BitcastCVH <= ConstantV);
- EXPECT_EQ(BV > CV, BitcastCVH > ConstantV);
- EXPECT_EQ(BV >= CV, BitcastCVH >= ConstantV);
-}
-
-TEST_F(ValueHandle, CallbackVH_CallbackOnDeletion) {
- class RecordingVH : public CallbackVH {
- public:
- int DeletedCalls;
- int AURWCalls;
-
- RecordingVH() : DeletedCalls(0), AURWCalls(0) {}
- RecordingVH(Value *V) : CallbackVH(V), DeletedCalls(0), AURWCalls(0) {}
-
- private:
- virtual void deleted() { DeletedCalls++; CallbackVH::deleted(); }
- virtual void allUsesReplacedWith(Value *) { AURWCalls++; }
- };
-
- RecordingVH RVH;
- RVH = BitcastV.get();
- EXPECT_EQ(0, RVH.DeletedCalls);
- EXPECT_EQ(0, RVH.AURWCalls);
- BitcastV.reset();
- EXPECT_EQ(1, RVH.DeletedCalls);
- EXPECT_EQ(0, RVH.AURWCalls);
-}
-
-TEST_F(ValueHandle, CallbackVH_CallbackOnRAUW) {
- class RecordingVH : public CallbackVH {
- public:
- int DeletedCalls;
- Value *AURWArgument;
-
- RecordingVH() : DeletedCalls(0), AURWArgument(NULL) {}
- RecordingVH(Value *V)
- : CallbackVH(V), DeletedCalls(0), AURWArgument(NULL) {}
-
- private:
- virtual void deleted() { DeletedCalls++; CallbackVH::deleted(); }
- virtual void allUsesReplacedWith(Value *new_value) {
- EXPECT_EQ(NULL, AURWArgument);
- AURWArgument = new_value;
- }
- };
-
- RecordingVH RVH;
- RVH = BitcastV.get();
- EXPECT_EQ(0, RVH.DeletedCalls);
- EXPECT_EQ(NULL, RVH.AURWArgument);
- BitcastV->replaceAllUsesWith(ConstantV);
- EXPECT_EQ(0, RVH.DeletedCalls);
- EXPECT_EQ(ConstantV, RVH.AURWArgument);
-}
-
-TEST_F(ValueHandle, CallbackVH_DeletionCanRAUW) {
- class RecoveringVH : public CallbackVH {
- public:
- int DeletedCalls;
- Value *AURWArgument;
- LLVMContext *Context;
-
- RecoveringVH() : DeletedCalls(0), AURWArgument(NULL),
- Context(&getGlobalContext()) {}
- RecoveringVH(Value *V)
- : CallbackVH(V), DeletedCalls(0), AURWArgument(NULL),
- Context(&getGlobalContext()) {}
-
- private:
- virtual void deleted() {
- getValPtr()->replaceAllUsesWith(Constant::getNullValue(Type::getInt32Ty(getGlobalContext())));
- setValPtr(NULL);
- }
- virtual void allUsesReplacedWith(Value *new_value) {
- ASSERT_TRUE(NULL != getValPtr());
- EXPECT_EQ(1U, getValPtr()->getNumUses());
- EXPECT_EQ(NULL, AURWArgument);
- AURWArgument = new_value;
- }
- };
-
- // Normally, if a value has uses, deleting it will crash. However, we can use
- // a CallbackVH to remove the uses before the check for no uses.
- RecoveringVH RVH;
- RVH = BitcastV.get();
- std::auto_ptr<BinaryOperator> BitcastUser(
- BinaryOperator::CreateAdd(RVH,
- Constant::getNullValue(Type::getInt32Ty(getGlobalContext()))));
- EXPECT_EQ(BitcastV.get(), BitcastUser->getOperand(0));
- BitcastV.reset(); // Would crash without the ValueHandler.
- EXPECT_EQ(Constant::getNullValue(Type::getInt32Ty(getGlobalContext())), RVH.AURWArgument);
- EXPECT_EQ(Constant::getNullValue(Type::getInt32Ty(getGlobalContext())),
- BitcastUser->getOperand(0));
-}
-
-TEST_F(ValueHandle, DestroyingOtherVHOnSameValueDoesntBreakIteration) {
- // When a CallbackVH modifies other ValueHandles in its callbacks,
- // that shouldn't interfere with non-modified ValueHandles receiving
- // their appropriate callbacks.
- //
- // We create the active CallbackVH in the middle of a palindromic
- // arrangement of other VHs so that the bad behavior would be
- // triggered in whichever order callbacks run.
-
- class DestroyingVH : public CallbackVH {
- public:
- OwningPtr<WeakVH> ToClear[2];
- DestroyingVH(Value *V) {
- ToClear[0].reset(new WeakVH(V));
- setValPtr(V);
- ToClear[1].reset(new WeakVH(V));
- }
- virtual void deleted() {
- ToClear[0].reset();
- ToClear[1].reset();
- CallbackVH::deleted();
- }
- virtual void allUsesReplacedWith(Value *) {
- ToClear[0].reset();
- ToClear[1].reset();
- }
- };
-
- {
- WeakVH ShouldBeVisited1(BitcastV.get());
- DestroyingVH C(BitcastV.get());
- WeakVH ShouldBeVisited2(BitcastV.get());
-
- BitcastV->replaceAllUsesWith(ConstantV);
- EXPECT_EQ(ConstantV, static_cast<Value*>(ShouldBeVisited1));
- EXPECT_EQ(ConstantV, static_cast<Value*>(ShouldBeVisited2));
- }
-
- {
- WeakVH ShouldBeVisited1(BitcastV.get());
- DestroyingVH C(BitcastV.get());
- WeakVH ShouldBeVisited2(BitcastV.get());
-
- BitcastV.reset();
- EXPECT_EQ(NULL, static_cast<Value*>(ShouldBeVisited1));
- EXPECT_EQ(NULL, static_cast<Value*>(ShouldBeVisited2));
- }
-}
-
-TEST_F(ValueHandle, AssertingVHCheckedLast) {
- // If a CallbackVH exists to clear out a group of AssertingVHs on
- // Value deletion, the CallbackVH should get a chance to do so
- // before the AssertingVHs assert.
-
- class ClearingVH : public CallbackVH {
- public:
- AssertingVH<Value> *ToClear[2];
- ClearingVH(Value *V,
- AssertingVH<Value> &A0, AssertingVH<Value> &A1)
- : CallbackVH(V) {
- ToClear[0] = &A0;
- ToClear[1] = &A1;
- }
-
- virtual void deleted() {
- *ToClear[0] = 0;
- *ToClear[1] = 0;
- CallbackVH::deleted();
- }
- };
-
- AssertingVH<Value> A1, A2;
- A1 = BitcastV.get();
- ClearingVH C(BitcastV.get(), A1, A2);
- A2 = BitcastV.get();
- // C.deleted() should run first, clearing the two AssertingVHs,
- // which should prevent them from asserting.
- BitcastV.reset();
-}
-
-}