A change to the C++ Standard will break some tests
Submitted by Jonathan Caves
Assigned to Nobody
Link to original bugzilla bug (#1752)
Description
Created attachment 953
Reduced test case
Hi: the C++20 the C++ committee has adopted P0929R2 (checking for abstract class types). This paper basically changes when a compiler checks for the use of an abstract class type. Previously it was an error to declare a function that had a parameter with a type that was an instance of an abstract class type - now it is an error to define or call such a function (i.e. it is not an error to just declare such a function). Note: this paper was adopted as a DR (defect report) and hence it applies to all versions of C++ not just C++20.
In the file ..\Eigen\src\test\meta.cpp there is code roughly like below (if you preprocess it):
namespace internal
{
template<typename T>
struct remove_reference {
typedef T type;
};
template<typename T>
struct remove_reference<T&> {
typedef T type;
};
template<typename From, typename To>
struct is_convertible_impl {
private:
struct any_conversion
{
template<typename T>
any_conversion(const volatile T&);
template<typename T>
any_conversion(T&);
};
struct yes { int a[1]; };
struct no { int a[2]; };
template<typename T>
static yes test(T, int);
template<typename T>
static no test(any_conversion, ...);
public:
static typename internal::remove_reference<From>::type* ms_from;
enum {
value = sizeof(test<To>(*ms_from, 0)) == sizeof(yes)
};
};
template<typename From, typename To>
struct is_convertible {
enum {
value = is_convertible_impl<From, To>::value
};
};
}
struct MyInterface {
virtual void func() = 0;
virtual ~MyInterface() {}
};
struct MyImpl : public MyInterface {
void func() {}
};
static_assert(!internal::is_convertible<MyImpl, MyInterface>::value, "EIGEN_INTERNAL_ERROR_PLEASE_FILE_A_BUG_REPORT");
The problem is that now the attempt to specialize the static member function 'test' with 'MyInterface' is no longer by itself an error and hence SFINAE does not kick in and the overload resolution process ends up pick 'test(MyInterface, int)' as the best match. This function is then called which does cause an error (specifically not a SFINAE error) and hence the compiler emits an error message.
Thanks
Jonathan Caves
Attachment 953, "Reduced test case":
t32.cpp