Skip to content

Commit

Permalink
Workaround clang __is_base_of bug in <type_traits> (#167)
Browse files Browse the repository at this point in the history
Clang's `__is_base_of` intrinsic incorrectly handles some corner cases involving incomplete union types before LLVM 9. Workaround by guarding with `__is_class`.
  • Loading branch information
CaseyCarter authored Oct 10, 2019
1 parent 9b2207c commit f565496
Showing 1 changed file with 12 additions and 0 deletions.
12 changes: 12 additions & 0 deletions stl/inc/type_traits
Original file line number Diff line number Diff line change
Expand Up @@ -1187,13 +1187,25 @@ 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
};

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>
Expand Down

0 comments on commit f565496

Please sign in to comment.