Fix PR32097 - is_abstract doesn't work on class templates.

This patch fixes llvm.org/PR32097 by using the __is_abstract
builtin type-trait instead of the previous library-only implementation.

All supported compilers provide this trait. I've tested as far
back as Clang 3.2, GCC 4.6 and MSVC trunk.

llvm-svn: 296561
This commit is contained in:
Eric Fiselier 2017-03-01 01:27:14 +00:00
parent b75c5c564c
commit 1ad881c3e4
2 changed files with 12 additions and 12 deletions

View File

@ -1297,18 +1297,8 @@ template <class _Tp> using decay_t = typename decay<_Tp>::type;
// is_abstract
namespace __is_abstract_imp
{
template <class _Tp> char __test(_Tp (*)[1]);
template <class _Tp> __two __test(...);
}
template <class _Tp, bool = is_class<_Tp>::value>
struct __libcpp_abstract : public integral_constant<bool, sizeof(__is_abstract_imp::__test<_Tp>(0)) != 1> {};
template <class _Tp> struct __libcpp_abstract<_Tp, false> : public false_type {};
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_abstract : public __libcpp_abstract<_Tp> {};
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_abstract
: public integral_constant<bool, __is_abstract(_Tp)> {};
#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
template <class _Tp> _LIBCPP_CONSTEXPR bool is_abstract_v

View File

@ -65,6 +65,14 @@ class Abstract
virtual ~Abstract() = 0;
};
template <class>
struct AbstractTemplate {
virtual void test() = 0;
};
template <>
struct AbstractTemplate<double> {};
int main()
{
test_is_not_abstract<void>();
@ -81,4 +89,6 @@ int main()
test_is_not_abstract<NotEmpty>();
test_is_abstract<Abstract>();
test_is_abstract<AbstractTemplate<int> >();
test_is_not_abstract<AbstractTemplate<double> >();
}