[Modules] Move the LLVM IR pattern match header into the IR library, it
[oota-llvm.git] / unittests / Support / ValueHandleTest.cpp
index d9a5515f78ed54d1fdb262cfc182a6d21b82cad5..05aafa2d05d86ce93747951273821260c34e2919 100644 (file)
@@ -8,12 +8,11 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/Support/ValueHandle.h"
-
-#include "llvm/Constants.h"
-#include "llvm/Instructions.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;
@@ -26,14 +25,13 @@ protected:
   std::auto_ptr<BitCastInst> BitcastV;
 
   ValueHandle() :
-    ConstantV(ConstantInt::get(Type::Int32Ty, 0)),
-    BitcastV(new BitCastInst(ConstantV, Type::Int32Ty)) {
+    ConstantV(ConstantInt::get(Type::getInt32Ty(getGlobalContext()), 0)),
+    BitcastV(new BitCastInst(ConstantV, Type::getInt32Ty(getGlobalContext()))) {
   }
 };
 
 class ConcreteCallbackVH : public CallbackVH {
 public:
-  ConcreteCallbackVH() : CallbackVH() {}
   ConcreteCallbackVH(Value *V) : CallbackVH(V) {}
 };
 
@@ -45,8 +43,8 @@ TEST_F(ValueHandle, WeakVH_BasicOperation) {
 
   // Make sure I can call a method on the underlying Value.  It
   // doesn't matter which method.
-  EXPECT_EQ(Type::Int32Ty, WVH->getType());
-  EXPECT_EQ(Type::Int32Ty, (*WVH).getType());
+  EXPECT_EQ(Type::getInt32Ty(getGlobalContext()), WVH->getType());
+  EXPECT_EQ(Type::getInt32Ty(getGlobalContext()), (*WVH).getType());
 }
 
 TEST_F(ValueHandle, WeakVH_Comparisons) {
@@ -107,7 +105,7 @@ TEST_F(ValueHandle, WeakVH_NullOnDeletion) {
 TEST_F(ValueHandle, AssertingVH_BasicOperation) {
   AssertingVH<CastInst> AVH(BitcastV.get());
   CastInst *implicit_to_exact_type = AVH;
-  implicit_to_exact_type = implicit_to_exact_type;  // Avoid warning.
+  (void)implicit_to_exact_type;  // Avoid warning.
 
   AssertingVH<Value> GenericAVH(BitcastV.get());
   EXPECT_EQ(BitcastV.get(), GenericAVH);
@@ -120,6 +118,13 @@ TEST_F(ValueHandle, AssertingVH_BasicOperation) {
   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);
@@ -193,8 +198,8 @@ TEST_F(ValueHandle, CallbackVH_BasicOperation) {
 
   // Make sure I can call a method on the underlying Value.  It
   // doesn't matter which method.
-  EXPECT_EQ(Type::Int32Ty, CVH->getType());
-  EXPECT_EQ(Type::Int32Ty, (*CVH).getType());
+  EXPECT_EQ(Type::getInt32Ty(getGlobalContext()), CVH->getType());
+  EXPECT_EQ(Type::getInt32Ty(getGlobalContext()), (*CVH).getType());
 }
 
 TEST_F(ValueHandle, CallbackVH_Comparisons) {
@@ -295,7 +300,7 @@ TEST_F(ValueHandle, CallbackVH_DeletionCanRAUW) {
 
   private:
     virtual void deleted() {
-      getValPtr()->replaceAllUsesWith(Constant::getNullValue(Type::Int32Ty));
+      getValPtr()->replaceAllUsesWith(Constant::getNullValue(Type::getInt32Ty(getGlobalContext())));
       setValPtr(NULL);
     }
     virtual void allUsesReplacedWith(Value *new_value) {
@@ -312,12 +317,92 @@ TEST_F(ValueHandle, CallbackVH_DeletionCanRAUW) {
   RVH = BitcastV.get();
   std::auto_ptr<BinaryOperator> BitcastUser(
     BinaryOperator::CreateAdd(RVH, 
-                              Constant::getNullValue(Type::Int32Ty)));
+                              Constant::getNullValue(Type::getInt32Ty(getGlobalContext()))));
   EXPECT_EQ(BitcastV.get(), BitcastUser->getOperand(0));
   BitcastV.reset();  // Would crash without the ValueHandler.
-  EXPECT_EQ(Constant::getNullValue(Type::Int32Ty), RVH.AURWArgument);
-  EXPECT_EQ(Constant::getNullValue(Type::Int32Ty),
+  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();
+}
+
 }