Workaround clang __is_base_of bug in <type_traits> (#167)

Clang's `__is_base_of` intrinsic incorrectly handles some corner cases involving incomplete union types before LLVM 9. Workaround by guarding with `__is_class`.
This commit is contained in:
Casey Carter 2019-10-09 18:21:10 -07:00 коммит произвёл GitHub
Родитель 9b2207c14e
Коммит f565496875
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
1 изменённых файлов: 12 добавлений и 0 удалений

Просмотреть файл

@ -1187,6 +1187,17 @@ template <class _Ty, unsigned int _Ix = 0>
struct extent : integral_constant<size_t, extent_v<_Ty, _Ix>> {};
// STRUCT TEMPLATE is_base_of
#ifdef __clang__ // TRANSITION, Clang 9
template <class _Base, class _Derived, bool = __is_class(_Base) && __is_class(_Derived)>
_INLINE_VAR constexpr bool is_base_of_v = __is_base_of(_Base, _Derived);
template <class _Base, class _Derived>
_INLINE_VAR constexpr bool is_base_of_v<_Base, _Derived, false> = false;
template <class _Base, class _Derived>
struct is_base_of : bool_constant<is_base_of_v<_Base, _Derived>> {};
#else // ^^^ workaround / no workaround vvv
template <class _Base, class _Derived>
struct is_base_of : bool_constant<__is_base_of(_Base, _Derived)> {
// determine whether _Base is a base of or the same as _Derived
@ -1194,6 +1205,7 @@ struct is_base_of : bool_constant<__is_base_of(_Base, _Derived)> {
template <class _Base, class _Derived>
_INLINE_VAR constexpr bool is_base_of_v = __is_base_of(_Base, _Derived);
#endif // TRANSITION, Clang 9
// STRUCT TEMPLATE decay
template <class _Ty>