Make is_convertible more robust and conformant to std::is_convertible
diff --git a/Eigen/src/Core/util/Meta.h b/Eigen/src/Core/util/Meta.h
index ef9860c..3d2bdd1 100755
--- a/Eigen/src/Core/util/Meta.h
+++ b/Eigen/src/Core/util/Meta.h
@@ -145,16 +145,19 @@
   struct yes {int a[1];};
   struct no  {int a[2];};
 
-  static yes test(const To&, int);
+  template<typename T>
+  static yes test(T, int);
+
+  template<typename T>
   static no  test(any_conversion, ...);
 
 public:
-  static From ms_from;
+  static From* ms_from;
 #ifdef __INTEL_COMPILER
   #pragma warning push
   #pragma warning ( disable : 2259 )
 #endif
-  enum { value = sizeof(test(ms_from, 0))==sizeof(yes) };
+  enum { value = sizeof(test<To>(*ms_from, 0))==sizeof(yes) };
 #ifdef __INTEL_COMPILER
   #pragma warning pop
 #endif
@@ -163,8 +166,7 @@
 template<typename From, typename To>
 struct is_convertible
 {
-  enum { value = is_convertible_impl<typename remove_all<From>::type,
-                                     typename remove_all<To  >::type>::value };
+  enum { value = is_convertible_impl<From,To>::value };
 };
 
 /** \internal Allows to enable/disable an overload
diff --git a/test/meta.cpp b/test/meta.cpp
index bd50576..4904f3b 100644
--- a/test/meta.cpp
+++ b/test/meta.cpp
@@ -19,6 +19,14 @@
   typedef int ReturnType;
 };
 
+struct MyInterface {
+  virtual void func() = 0;
+  virtual ~MyInterface() {}
+};
+struct MyImpl : public MyInterface {
+  void func() {}
+};
+
 void test_meta()
 {
   VERIFY((internal::conditional<(3<4),internal::true_type, internal::false_type>::type::value));
@@ -62,14 +70,19 @@
   VERIFY(( internal::is_same<const float,internal::remove_pointer<const float*>::type >::value));
   VERIFY(( internal::is_same<float,internal::remove_pointer<float* const >::type >::value));
   
-  VERIFY(( internal::is_convertible<float,double>::value ));
-  VERIFY(( internal::is_convertible<int,double>::value ));
-  VERIFY(( internal::is_convertible<double,int>::value ));
-  VERIFY((!internal::is_convertible<std::complex<double>,double>::value ));
-  VERIFY(( internal::is_convertible<Array33f,Matrix3f>::value ));
+
+  // is_convertible
+  STATIC_CHECK(( internal::is_convertible<float,double>::value ));
+  STATIC_CHECK(( internal::is_convertible<int,double>::value ));
+  STATIC_CHECK(( internal::is_convertible<int, short>::value ));
+  STATIC_CHECK(( internal::is_convertible<short, int>::value ));
+  STATIC_CHECK(( internal::is_convertible<double,int>::value ));
+  STATIC_CHECK(( internal::is_convertible<double,std::complex<double> >::value ));
+  STATIC_CHECK((!internal::is_convertible<std::complex<double>,double>::value ));
+  STATIC_CHECK(( internal::is_convertible<Array33f,Matrix3f>::value ));
 //   VERIFY((!internal::is_convertible<Matrix3f,Matrix3d>::value )); //does not work because the conversion is prevented by a static assertion
-  VERIFY((!internal::is_convertible<Array33f,int>::value ));
-  VERIFY((!internal::is_convertible<MatrixXf,float>::value ));
+  STATIC_CHECK((!internal::is_convertible<Array33f,int>::value ));
+  STATIC_CHECK((!internal::is_convertible<MatrixXf,float>::value ));
   {
     float f;
     MatrixXf A, B;
@@ -80,6 +93,15 @@
     VERIFY(( check_is_convertible(A*B, A) ));
   }
 
+  STATIC_CHECK(( !internal::is_convertible<MyInterface, MyImpl>::value ));
+  STATIC_CHECK(( !internal::is_convertible<MyImpl, MyInterface>::value ));
+  STATIC_CHECK((  internal::is_convertible<MyImpl, const MyInterface&>::value ));
+  {
+    int i;
+    VERIFY(( check_is_convertible(fix<3>(), i) ));
+    VERIFY((!check_is_convertible(i, fix<DynamicIndex>()) ));
+  }
+
   VERIFY((  internal::has_ReturnType<FooReturnType>::value ));
   VERIFY((  internal::has_ReturnType<ScalarBinaryOpTraits<int,int> >::value ));
   VERIFY(( !internal::has_ReturnType<MatrixXf>::value ));