Hi Howard,<div><br></div><div>It was pointed out to me off-list that libc++'s non-compiler-builtin implementation of std::is_polymorphic does this:</div><div><br></div><div><div>template <class _Tp> struct __is_polymorphic1 : public _Tp {};</div>
</div><div><br></div><div>... and that g++ rejects this if _Tp has an inaccessible virtual destructor (because __is_polymorphic1<_Tp> would have a deleted virtual destructor overriding _Tp's non-deleted destructor). Clang was failing to reject this; I've fixed that in r178563, but that causes libc++'s corresponding test case to fail with both clang and gcc when using the fallback implementation. The fallback code also incorrectly rejects final types.</div>
<div><br></div><div>The attached patch fixes the fallback implementation of is_polymorphic; we now use dynamic_cast's detection of polymorphic class types rather than trying to determine if adding a virtual function makes the type larger:</div>
<div><br></div><div>  enable_if<sizeof((_Tp*)dynamic_cast<const volatile void*>(declval<_Tp*>())) != 0, ...></div><div><br></div><div>Two things of note here:</div><div>* the (_Tp*) cast is necessary to work around bugs in Clang and g++ where we otherwise don't instantiate the dynamic_cast (filed as PR15656)</div>
<div>* the 'const volatile' is here to treat is_polymorphic<cv T> as true for a polymorphic class type T -- my reading of the standard suggests this is incorrect, but it matches our builtin __is_polymorphic and gcc</div>