[libc++] Remove some workarounds for unsupported GCC and Clang versions

There is a lot more we can do, in particular in <type_traits>, but this
removes some workarounds that were gated on checking a specific compiler
version.

Differential Revision: https://reviews.llvm.org/D108923
This commit is contained in:
Louis Dionne 2021-08-31 10:49:06 -04:00
parent 9d7ae0acde
commit a4cb5aefd5
10 changed files with 9 additions and 258 deletions

View File

@ -24,16 +24,6 @@
#ifdef __cplusplus
#ifdef __GNUC__
# define _GNUC_VER (__GNUC__ * 100 + __GNUC_MINOR__)
// The _GNUC_VER_NEW macro better represents the new GCC versioning scheme
// introduced in GCC 5.0.
# define _GNUC_VER_NEW (_GNUC_VER * 10 + __GNUC_PATCHLEVEL__)
#else
# define _GNUC_VER 0
# define _GNUC_VER_NEW 0
#endif
#define _LIBCPP_VERSION 14000
#ifndef _LIBCPP_ABI_VERSION
@ -509,22 +499,8 @@ typedef __char32_t char32_t;
#define _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK __attribute__((__no_sanitize__("unsigned-integer-overflow")))
#endif
#if __has_builtin(__builtin_launder)
#define _LIBCPP_COMPILER_HAS_BUILTIN_LAUNDER
#endif
#if __has_builtin(__builtin_constant_p)
#define _LIBCPP_COMPILER_HAS_BUILTIN_CONSTANT_P
#endif
#define _LIBCPP_ALWAYS_INLINE __attribute__ ((__always_inline__))
// Literal operators ""d and ""y are supported starting with LLVM Clang 8 and AppleClang 10.0.1
#if (defined(_LIBCPP_CLANG_VER) && _LIBCPP_CLANG_VER < 800) || \
(defined(_LIBCPP_APPLE_CLANG_VER) && _LIBCPP_APPLE_CLANG_VER < 1001)
#define _LIBCPP_HAS_NO_CXX20_CHRONO_LITERALS
#endif
#define _LIBCPP_DISABLE_EXTENSION_WARNING __extension__
#elif defined(_LIBCPP_COMPILER_GCC)
@ -547,11 +523,6 @@ typedef __char32_t char32_t;
#define _LIBCPP_HAS_NO_ASAN
#endif
#if _GNUC_VER >= 700
#define _LIBCPP_COMPILER_HAS_BUILTIN_LAUNDER
#define _LIBCPP_COMPILER_HAS_BUILTIN_CONSTANT_P
#endif
#define _LIBCPP_ALWAYS_INLINE __attribute__ ((__always_inline__))
#define _LIBCPP_DISABLE_EXTENSION_WARNING __extension__
@ -1275,7 +1246,7 @@ extern "C" _LIBCPP_FUNC_VIS void __sanitizer_annotate_contiguous_container(
# define _LIBCPP_FALLTHROUGH() [[fallthrough]]
#elif __has_cpp_attribute(clang::fallthrough)
# define _LIBCPP_FALLTHROUGH() [[clang::fallthrough]]
#elif __has_attribute(fallthrough) || _GNUC_VER >= 700
#elif __has_attribute(__fallthrough__)
# define _LIBCPP_FALLTHROUGH() __attribute__((__fallthrough__))
#else
# define _LIBCPP_FALLTHROUGH() ((void)0)
@ -1380,12 +1351,6 @@ extern "C" _LIBCPP_FUNC_VIS void __sanitizer_annotate_contiguous_container(
# define _LIBCPP_FOPEN_CLOEXEC_MODE
#endif
#ifdef _LIBCPP_COMPILER_HAS_BUILTIN_CONSTANT_P
#define _LIBCPP_BUILTIN_CONSTANT_P(x) __builtin_constant_p(x)
#else
#define _LIBCPP_BUILTIN_CONSTANT_P(x) false
#endif
// Support for _FILE_OFFSET_BITS=64 landed gradually in Android, so the full set
// of functions used in cstdio may not be available for low API levels when
// using 64-bit file offsets on LP32.

View File

@ -1496,11 +1496,8 @@ template <typename _Tp,
typename _Base = __cxx_atomic_base_impl<_Tp> >
#endif //_LIBCPP_ATOMIC_ONLY_USE_BUILTINS
struct __cxx_atomic_impl : public _Base {
#if _GNUC_VER >= 501
static_assert(is_trivially_copyable<_Tp>::value,
"std::atomic<Tp> requires that 'Tp' be a trivially copyable type");
#endif
_LIBCPP_INLINE_VISIBILITY __cxx_atomic_impl() _NOEXCEPT _LIBCPP_DEFAULT
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR explicit __cxx_atomic_impl(_Tp value) _NOEXCEPT

View File

@ -2907,7 +2907,7 @@ inline namespace literals
return chrono::duration<long double, nano> (__ns);
}
#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CXX20_CHRONO_LITERALS)
#if _LIBCPP_STD_VER > 17
constexpr chrono::day operator ""d(unsigned long long __d) noexcept
{
return chrono::day(static_cast<unsigned>(__d));

View File

@ -337,11 +337,7 @@ _LIBCPP_CONSTEXPR _Tp* __launder(_Tp* __p) _NOEXCEPT
{
static_assert (!(is_function<_Tp>::value), "can't launder functions" );
static_assert (!(is_same<void, typename remove_cv<_Tp>::type>::value), "can't launder cv-void" );
#ifdef _LIBCPP_COMPILER_HAS_BUILTIN_LAUNDER
return __builtin_launder(__p);
#else
return __p;
#endif
}
#if _LIBCPP_STD_VER > 14

View File

@ -2373,7 +2373,7 @@ basic_string<_CharT, _Traits, _Allocator>&
basic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s, size_type __n)
{
_LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::assign received nullptr");
return (_LIBCPP_BUILTIN_CONSTANT_P(__n) && __n < __min_cap)
return (__builtin_constant_p(__n) && __n < __min_cap)
? __assign_short(__s, __n)
: __assign_external(__s, __n);
}
@ -2578,7 +2578,7 @@ basic_string<_CharT, _Traits, _Allocator>&
basic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s)
{
_LIBCPP_ASSERT(__s != nullptr, "string::assign received nullptr");
return _LIBCPP_BUILTIN_CONSTANT_P(*__s)
return __builtin_constant_p(*__s)
? (traits_type::length(__s) < __min_cap
? __assign_short(__s, traits_type::length(__s))
: __assign_external(__s, traits_type::length(__s)))

View File

@ -3049,135 +3049,10 @@ struct __member_pointer_class_type<_Ret _ClassType::*> {
// template <class T, class... Args> struct is_constructible;
#if defined(_LIBCPP_COMPILER_GCC) && _GNUC_VER_NEW >= 10000
# define _LIBCPP_GCC_SUPPORTS_IS_CONSTRUCTIBLE
#endif
#if !defined(_LIBCPP_CXX03_LANG) && !__has_feature(is_constructible) && !defined(_LIBCPP_GCC_SUPPORTS_IS_CONSTRUCTIBLE)
template <class _Tp, class... _Args>
struct __libcpp_is_constructible;
template <class _To, class _From>
struct __is_invalid_base_to_derived_cast {
static_assert(is_reference<_To>::value, "Wrong specialization");
using _RawFrom = __uncvref_t<_From>;
using _RawTo = __uncvref_t<_To>;
static const bool value = _And<
_IsNotSame<_RawFrom, _RawTo>,
is_base_of<_RawFrom, _RawTo>,
_Not<__libcpp_is_constructible<_RawTo, _From>>
>::value;
};
template <class _To, class _From>
struct __is_invalid_lvalue_to_rvalue_cast : false_type {
static_assert(is_reference<_To>::value, "Wrong specialization");
};
template <class _ToRef, class _FromRef>
struct __is_invalid_lvalue_to_rvalue_cast<_ToRef&&, _FromRef&> {
using _RawFrom = __uncvref_t<_FromRef>;
using _RawTo = __uncvref_t<_ToRef>;
static const bool value = _And<
_Not<is_function<_RawTo>>,
_Or<
_IsSame<_RawFrom, _RawTo>,
is_base_of<_RawTo, _RawFrom>>
>::value;
};
struct __is_constructible_helper
{
template <class _To>
static void __eat(_To);
// This overload is needed to work around a Clang bug that disallows
// static_cast<T&&>(e) for non-reference-compatible types.
// Example: static_cast<int&&>(declval<double>());
// NOTE: The static_cast implementation below is required to support
// classes with explicit conversion operators.
template <class _To, class _From,
class = decltype(__eat<_To>(declval<_From>()))>
static true_type __test_cast(int);
template <class _To, class _From,
class = decltype(static_cast<_To>(declval<_From>()))>
static integral_constant<bool,
!__is_invalid_base_to_derived_cast<_To, _From>::value &&
!__is_invalid_lvalue_to_rvalue_cast<_To, _From>::value
> __test_cast(long);
template <class, class>
static false_type __test_cast(...);
template <class _Tp, class ..._Args,
class = decltype(_Tp(declval<_Args>()...))>
static true_type __test_nary(int);
template <class _Tp, class...>
static false_type __test_nary(...);
template <class _Tp, class _A0, class = decltype(::new _Tp(declval<_A0>()))>
static is_destructible<_Tp> __test_unary(int);
template <class, class>
static false_type __test_unary(...);
};
template <class _Tp, bool = is_void<_Tp>::value>
struct __is_default_constructible
: decltype(__is_constructible_helper::__test_nary<_Tp>(0))
{};
template <class _Tp>
struct __is_default_constructible<_Tp, true> : false_type {};
template <class _Tp>
struct __is_default_constructible<_Tp[], false> : false_type {};
template <class _Tp, size_t _Nx>
struct __is_default_constructible<_Tp[_Nx], false>
: __is_default_constructible<typename remove_all_extents<_Tp>::type> {};
template <class _Tp, class... _Args>
struct __libcpp_is_constructible
{
static_assert(sizeof...(_Args) > 1, "Wrong specialization");
typedef decltype(__is_constructible_helper::__test_nary<_Tp, _Args...>(0))
type;
};
template <class _Tp>
struct __libcpp_is_constructible<_Tp> : __is_default_constructible<_Tp> {};
template <class _Tp, class _A0>
struct __libcpp_is_constructible<_Tp, _A0>
: public decltype(__is_constructible_helper::__test_unary<_Tp, _A0>(0))
{};
template <class _Tp, class _A0>
struct __libcpp_is_constructible<_Tp&, _A0>
: public decltype(__is_constructible_helper::
__test_cast<_Tp&, _A0>(0))
{};
template <class _Tp, class _A0>
struct __libcpp_is_constructible<_Tp&&, _A0>
: public decltype(__is_constructible_helper::
__test_cast<_Tp&&, _A0>(0))
{};
#endif
#if __has_feature(is_constructible) || defined(_LIBCPP_GCC_SUPPORTS_IS_CONSTRUCTIBLE)
template <class _Tp, class ..._Args>
struct _LIBCPP_TEMPLATE_VIS is_constructible
: public integral_constant<bool, __is_constructible(_Tp, _Args...)>
{};
#else
template <class _Tp, class... _Args>
struct _LIBCPP_TEMPLATE_VIS is_constructible
: public __libcpp_is_constructible<_Tp, _Args...>::type {};
#endif
{ };
#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
template <class _Tp, class ..._Args>
@ -3250,53 +3125,12 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_move_constructible_v
// is_trivially_constructible
#if __has_feature(is_trivially_constructible) || _GNUC_VER >= 501
template <class _Tp, class... _Args>
struct _LIBCPP_TEMPLATE_VIS is_trivially_constructible
: integral_constant<bool, __is_trivially_constructible(_Tp, _Args...)>
{
};
#else // !__has_feature(is_trivially_constructible)
template <class _Tp, class... _Args>
struct _LIBCPP_TEMPLATE_VIS is_trivially_constructible
: false_type
{
};
template <class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_trivially_constructible<_Tp>
#if __has_feature(has_trivial_constructor) || defined(_LIBCPP_COMPILER_GCC)
: integral_constant<bool, __has_trivial_constructor(_Tp)>
#else
: integral_constant<bool, is_scalar<_Tp>::value>
#endif
{
};
template <class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_trivially_constructible<_Tp, _Tp&&>
: integral_constant<bool, is_scalar<_Tp>::value>
{
};
template <class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_trivially_constructible<_Tp, const _Tp&>
: integral_constant<bool, is_scalar<_Tp>::value>
{
};
template <class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_trivially_constructible<_Tp, _Tp&>
: integral_constant<bool, is_scalar<_Tp>::value>
{
};
#endif // !__has_feature(is_trivially_constructible)
#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
template <class _Tp, class... _Args>
_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_trivially_constructible_v
@ -3341,37 +3175,10 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_trivially_move_constructible_v
// is_trivially_assignable
#if __has_feature(is_trivially_assignable) || _GNUC_VER >= 501
template <class _Tp, class _Arg>
struct is_trivially_assignable
: integral_constant<bool, __is_trivially_assignable(_Tp, _Arg)>
{
};
#else // !__has_feature(is_trivially_assignable)
template <class _Tp, class _Arg>
struct is_trivially_assignable
: public false_type {};
template <class _Tp>
struct is_trivially_assignable<_Tp&, _Tp>
: integral_constant<bool, is_scalar<_Tp>::value> {};
template <class _Tp>
struct is_trivially_assignable<_Tp&, _Tp&>
: integral_constant<bool, is_scalar<_Tp>::value> {};
template <class _Tp>
struct is_trivially_assignable<_Tp&, const _Tp&>
: integral_constant<bool, is_scalar<_Tp>::value> {};
template <class _Tp>
struct is_trivially_assignable<_Tp&, _Tp&&>
: integral_constant<bool, is_scalar<_Tp>::value> {};
#endif // !__has_feature(is_trivially_assignable)
{ };
#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
template <class _Tp, class _Arg>

View File

@ -233,10 +233,7 @@ public:
_LIBCPP_BEGIN_NAMESPACE_STD
// TODO: GCC 5 lies about its support for C++17 (it says it supports it but it
// really doesn't). That breaks variant, which uses some C++17 features.
// Remove this once we drop support for GCC 5.
#if _LIBCPP_STD_VER > 14 && !(defined(_LIBCPP_COMPILER_GCC) && _GNUC_VER_NEW < 6000)
#if _LIBCPP_STD_VER > 14
// Light N-dimensional array of function pointers. Used in place of std::array to avoid
// adding a dependency.

View File

@ -24,7 +24,7 @@
&& defined(__ATOMIC_ACQ_REL) \
&& defined(__ATOMIC_SEQ_CST)
# define _LIBCPP_HAS_ATOMIC_BUILTINS
#elif !defined(__clang__) && defined(_GNUC_VER) && _GNUC_VER >= 407
#elif defined(_LIBCPP_COMPILER_GCC)
# define _LIBCPP_HAS_ATOMIC_BUILTINS
#endif

View File

@ -261,13 +261,6 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP
#endif // _LIBCPP_NO_EXCEPTIONS
}
// NOTE avoid the `base class should be explicitly initialized in the
// copy constructor` warning emitted by GCC
#if defined(__clang__) || _GNUC_VER >= 406
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wextra"
#endif
locale::__imp::__imp(const __imp& other)
: facets_(max<size_t>(N, other.facets_.size())),
name_(other.name_)
@ -278,10 +271,6 @@ locale::__imp::__imp(const __imp& other)
facets_[i]->__add_shared();
}
#if defined(__clang__) || _GNUC_VER >= 406
#pragma GCC diagnostic pop
#endif
locale::__imp::__imp(const __imp& other, const string& name, locale::category c)
: facets_(N),
name_("*")

View File

@ -28,7 +28,7 @@
&& defined(__ATOMIC_ACQ_REL) \
&& defined(__ATOMIC_SEQ_CST)
# define _LIBCXXABI_HAS_ATOMIC_BUILTINS
#elif !defined(__clang__) && defined(_GNUC_VER) && _GNUC_VER >= 407
#elif defined(_LIBCPP_COMPILER_GCC)
# define _LIBCXXABI_HAS_ATOMIC_BUILTINS
#endif