Skip to content

Commit

Permalink
[libc++] Remove some workarounds for unsupported GCC and Clang versions
Browse files Browse the repository at this point in the history
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
  • Loading branch information
ldionne committed Sep 1, 2021
1 parent 9d7ae0a commit a4cb5ae
Show file tree
Hide file tree
Showing 10 changed files with 9 additions and 258 deletions.
37 changes: 1 addition & 36 deletions libcxx/include/__config
Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand All @@ -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__
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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.
Expand Down
3 changes: 0 additions & 3 deletions libcxx/include/atomic
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion libcxx/include/chrono
Expand Up @@ -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));
Expand Down
4 changes: 0 additions & 4 deletions libcxx/include/new
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions libcxx/include/string
Expand Up @@ -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);
}
Expand Down Expand Up @@ -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)))
Expand Down
197 changes: 2 additions & 195 deletions libcxx/include/type_traits
Expand Up @@ -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>
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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>
Expand Down
5 changes: 1 addition & 4 deletions libcxx/include/variant
Expand Up @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion libcxx/src/include/atomic_support.h
Expand Up @@ -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

Expand Down

0 comments on commit a4cb5ae

Please sign in to comment.