[PATCH] [libc++] Fix std::is_polymorphic fallback implementation for final classes and inaccessible destructors

Howard Hinnant hhinnant at apple.com
Tue Apr 2 14:27:00 PDT 2013


Thanks Richard, committed revision 178576.

Howard

On Apr 2, 2013, at 5:08 PM, Richard Smith <richard at metafoo.co.uk> wrote:

> Hi Howard,
> 
> It was pointed out to me off-list that libc++'s non-compiler-builtin
> implementation of std::is_polymorphic does this:
> 
> template <class _Tp> struct __is_polymorphic1 : public _Tp {};
> 
> ... 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.
> 
> 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:
> 
>  enable_if<sizeof((_Tp*)dynamic_cast<const volatile
> void*>(declval<_Tp*>())) != 0, ...>
> 
> Two things of note here:
> * 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)
> * 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
> <is_polymorphic_fallback_fix.diff>




More information about the cfe-commits mailing list