On Thu, 24 Jun 2021 at 15:21, Jakub Jelinek <ja...@redhat.com> wrote: > > On Thu, Jun 24, 2021 at 03:11:01PM +0100, Jonathan Wakely wrote: > > On Thu, 24 Jun 2021 at 15:08, Jakub Jelinek wrote: > > > > > > On Thu, Jun 24, 2021 at 04:01:34PM +0200, Matthias Kretz wrote: > > > > --- a/libstdc++-v3/include/experimental/bits/simd.h > > > > +++ b/libstdc++-v3/include/experimental/bits/simd.h > > > > @@ -1598,7 +1598,9 @@ template <typename _To, typename _From> > > > > _GLIBCXX_SIMD_INTRINSIC constexpr _To > > > > __bit_cast(const _From __x) > > > > { > > > > - // TODO: implement with / replace by __builtin_bit_cast ASAP > > > > +#if __has_builtin(__builtin_bit_cast) > > > > > > Shouldn't that use #if _GLIBCXX_HAS_BUILTIN(__builtin_bit_cast) in > > > c++config to define a new macro and use that macro here? > > > Though it is true that c++config already uses > > > #if __has_builtin(__builtin_is_constant_evaluated) > > > and so would fail miserably for compilers that don't support __has_builtin > > > > GCC was the last of our supported compilers to implement > > __has_builtin, so for GCC trunk we can assume that it's always > > supported. > > We don't support mixing GCC and libstdc++ versions, so I'm not worried > about GCC. At least according to godbolt, already clang 3.0 supports it > which is 10 years old, so probably fine too, but ICC 19.0/19.1 still doesn't > support it, only ICC 2021 does. And ICC 19.1 seems to be released in > October 2020. > > So, wouldn't it be better not to #undef _GLIBCXX_HAS_BUILTIN, move its > definition a little bit earlier and use it also for > __builtin_is_constant_evaluated?
I discussed this with Judy Ward on the Intel compiler team. If you're using their compiler, you should be using the latest version. They also claim 100% compatibility with GCC, for versions they've been able to test. So if you are using libstdc++ headers from a GCC release that supports __has_builtin, then you need to use a release of the Intel compiler that supports __has_builtin. Otherwise, it's unsupported. So in GCC 12 C++ headers we support GCC 12, versions of Intel compatible with GCC 12, and the last few releases of Clang. All of those have __has_builtin. Rather than use the _GLIBCXX_HAS_BUILTIN macro more widely, I'd prefer to not use it where it isn't needed, as in the attached (untested) patch.
diff --git a/libstdc++-v3/include/bits/basic_string.h b/libstdc++-v3/include/bits/basic_string.h index 9911d4deb72..3c075966660 100644 --- a/libstdc++-v3/include/bits/basic_string.h +++ b/libstdc++-v3/include/bits/basic_string.h @@ -55,7 +55,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #ifdef __cpp_lib_is_constant_evaluated // Support P1032R1 in C++20 (but not P0980R1 yet). # define __cpp_lib_constexpr_string 201811L -#elif __cplusplus >= 201703L && _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED +#elif __cplusplus >= 201703L && __has_builtin(__builtin_is_constant_evaluated) // Support P0426R1 changes to char_traits in C++17. # define __cpp_lib_constexpr_string 201611L #elif __cplusplus > 201703L diff --git a/libstdc++-v3/include/bits/c++config b/libstdc++-v3/include/bits/c++config index 9314117aed8..3ec668b65cf 100644 --- a/libstdc++-v3/include/bits/c++config +++ b/libstdc++-v3/include/bits/c++config @@ -720,13 +720,11 @@ namespace std # define _GLIBCXX_DOUBLE_IS_IEEE_BINARY64 1 #endif -#ifdef __has_builtin -# ifdef __is_identifier +#ifdef __is_identifier // Intel and older Clang require !__is_identifier for some built-ins: -# define _GLIBCXX_HAS_BUILTIN(B) __has_builtin(B) || ! __is_identifier(B) -# else -# define _GLIBCXX_HAS_BUILTIN(B) __has_builtin(B) -# endif +# define _GLIBCXX_HAS_BUILTIN(B) __has_builtin(B) || ! __is_identifier(B) +#else +# define _GLIBCXX_HAS_BUILTIN(B) __has_builtin(B) #endif #if _GLIBCXX_HAS_BUILTIN(__has_unique_object_representations) @@ -737,18 +735,10 @@ namespace std # define _GLIBCXX_HAVE_BUILTIN_IS_AGGREGATE 1 #endif -#if _GLIBCXX_HAS_BUILTIN(__builtin_is_constant_evaluated) -# define _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED 1 -#endif - #if _GLIBCXX_HAS_BUILTIN(__is_same) # define _GLIBCXX_HAVE_BUILTIN_IS_SAME 1 #endif -#if _GLIBCXX_HAS_BUILTIN(__builtin_launder) -# define _GLIBCXX_HAVE_BUILTIN_LAUNDER 1 -#endif - #undef _GLIBCXX_HAS_BUILTIN diff --git a/libstdc++-v3/include/bits/char_traits.h b/libstdc++-v3/include/bits/char_traits.h index 3da6e28a513..77ad7be5dfb 100644 --- a/libstdc++-v3/include/bits/char_traits.h +++ b/libstdc++-v3/include/bits/char_traits.h @@ -238,7 +238,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #ifdef __cpp_lib_is_constant_evaluated // Unofficial macro indicating P1032R1 support in C++20 # define __cpp_lib_constexpr_char_traits 201811L -#elif __cplusplus >= 201703L && _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED +#elif __cplusplus >= 201703L && __has_builtin(__builtin_is_constant_evaluated) // Unofficial macro indicating P0426R1 support in C++17 # define __cpp_lib_constexpr_char_traits 201611L #endif @@ -295,7 +295,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { if (__n == 0) return 0; -#if __cplusplus >= 201703L && _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED +#if __cplusplus >= 201703L && __has_builtin(__builtin_is_constant_evaluated) if (__builtin_is_constant_evaluated()) { for (size_t __i = 0; __i < __n; ++__i) @@ -312,7 +312,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION static _GLIBCXX17_CONSTEXPR size_t length(const char_type* __s) { -#if __cplusplus >= 201703L && _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED +#if __cplusplus >= 201703L && __has_builtin(__builtin_is_constant_evaluated) if (__builtin_is_constant_evaluated()) return __gnu_cxx::char_traits<char_type>::length(__s); #endif @@ -324,7 +324,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { if (__n == 0) return 0; -#if __cplusplus >= 201703L && _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED +#if __cplusplus >= 201703L && __has_builtin(__builtin_is_constant_evaluated) if (__builtin_is_constant_evaluated()) return __gnu_cxx::char_traits<char_type>::find(__s, __n, __a); #endif @@ -422,7 +422,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { if (__n == 0) return 0; -#if __cplusplus >= 201703L && _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED +#if __cplusplus >= 201703L && __has_builtin(__builtin_is_constant_evaluated) if (__builtin_is_constant_evaluated()) return __gnu_cxx::char_traits<char_type>::compare(__s1, __s2, __n); #endif @@ -432,7 +432,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION static _GLIBCXX17_CONSTEXPR size_t length(const char_type* __s) { -#if __cplusplus >= 201703L && _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED +#if __cplusplus >= 201703L && __has_builtin(__builtin_is_constant_evaluated) if (__builtin_is_constant_evaluated()) return __gnu_cxx::char_traits<char_type>::length(__s); #endif @@ -444,7 +444,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { if (__n == 0) return 0; -#if __cplusplus >= 201703L && _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED +#if __cplusplus >= 201703L && __has_builtin(__builtin_is_constant_evaluated) if (__builtin_is_constant_evaluated()) return __gnu_cxx::char_traits<char_type>::find(__s, __n, __a); #endif @@ -539,7 +539,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { if (__n == 0) return 0; -#if __cplusplus >= 201703L && _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED +#if __cplusplus >= 201703L && __has_builtin(__builtin_is_constant_evaluated) if (__builtin_is_constant_evaluated()) return __gnu_cxx::char_traits<char_type>::compare(__s1, __s2, __n); #endif @@ -549,7 +549,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION static _GLIBCXX17_CONSTEXPR size_t length(const char_type* __s) { -#if __cplusplus >= 201703L && _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED +#if __cplusplus >= 201703L && __has_builtin(__builtin_is_constant_evaluated) if (__builtin_is_constant_evaluated()) return __gnu_cxx::char_traits<char_type>::length(__s); #endif @@ -564,7 +564,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { if (__n == 0) return 0; -#if __cplusplus >= 201703L && _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED +#if __cplusplus >= 201703L && __has_builtin(__builtin_is_constant_evaluated) if (__builtin_is_constant_evaluated()) return __gnu_cxx::char_traits<char_type>::find(__s, __n, __a); #endif diff --git a/libstdc++-v3/include/bits/stl_function.h b/libstdc++-v3/include/bits/stl_function.h index 073018d522d..774a9829284 100644 --- a/libstdc++-v3/include/bits/stl_function.h +++ b/libstdc++-v3/include/bits/stl_function.h @@ -413,12 +413,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _GLIBCXX14_CONSTEXPR bool operator()(_Tp* __x, _Tp* __y) const _GLIBCXX_NOTHROW { -#if __cplusplus >= 201402L -#ifdef _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED +#if __cplusplus >= 201402L && __has_builtin(__builtin_is_constant_evaluated) if (__builtin_is_constant_evaluated()) -#else - if (__builtin_constant_p(__x > __y)) -#endif return __x > __y; #endif return (__UINTPTR_TYPE__)__x > (__UINTPTR_TYPE__)__y; @@ -432,12 +428,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _GLIBCXX14_CONSTEXPR bool operator()(_Tp* __x, _Tp* __y) const _GLIBCXX_NOTHROW { -#if __cplusplus >= 201402L -#ifdef _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED +#if __cplusplus >= 201402L && __has_builtin(__builtin_is_constant_evaluated) if (__builtin_is_constant_evaluated()) -#else - if (__builtin_constant_p(__x < __y)) -#endif return __x < __y; #endif return (__UINTPTR_TYPE__)__x < (__UINTPTR_TYPE__)__y; @@ -451,12 +443,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _GLIBCXX14_CONSTEXPR bool operator()(_Tp* __x, _Tp* __y) const _GLIBCXX_NOTHROW { -#if __cplusplus >= 201402L -#ifdef _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED +#if __cplusplus >= 201402L && __has_builtin(__builtin_is_constant_evaluated) if (__builtin_is_constant_evaluated()) -#else - if (__builtin_constant_p(__x >= __y)) -#endif return __x >= __y; #endif return (__UINTPTR_TYPE__)__x >= (__UINTPTR_TYPE__)__y; @@ -470,12 +458,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _GLIBCXX14_CONSTEXPR bool operator()(_Tp* __x, _Tp* __y) const _GLIBCXX_NOTHROW { -#if __cplusplus >= 201402L -#ifdef _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED +#if __cplusplus >= 201402L && __has_builtin(__builtin_is_constant_evaluated) if (__builtin_is_constant_evaluated()) -#else - if (__builtin_constant_p(__x <= __y)) -#endif return __x <= __y; #endif return (__UINTPTR_TYPE__)__x <= (__UINTPTR_TYPE__)__y; diff --git a/libstdc++-v3/include/debug/helper_functions.h b/libstdc++-v3/include/debug/helper_functions.h index c0144ced979..c54311a22d1 100644 --- a/libstdc++-v3/include/debug/helper_functions.h +++ b/libstdc++-v3/include/debug/helper_functions.h @@ -125,7 +125,7 @@ namespace __gnu_debug __check_singular(_Iterator const& __x) { return -#ifdef _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED +#if __has_builtin(__builtin_is_constant_evaluated) __builtin_is_constant_evaluated() ? false : #endif __check_singular_aux(std::__addressof(__x)); @@ -138,7 +138,7 @@ namespace __gnu_debug __check_singular(_Tp* const& __ptr) { return -#ifdef _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED +#if __has_builtin(__builtin_is_constant_evaluated) __builtin_is_constant_evaluated() ? false : #endif __ptr == 0; diff --git a/libstdc++-v3/include/std/bit b/libstdc++-v3/include/std/bit index c5aae8bab03..ee8e001fd44 100644 --- a/libstdc++-v3/include/std/bit +++ b/libstdc++-v3/include/std/bit @@ -265,7 +265,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // representable as a value of _Tp, and so the result is undefined. // Want that undefined behaviour to be detected in constant expressions, // by UBSan, and by debug assertions. -#ifdef _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED +#if __has_builtin(__builtin_is_constant_evaluated) if (!__builtin_is_constant_evaluated()) { __glibcxx_assert( __shift_exponent != __int_traits<_Tp>::__digits ); diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits index d9068a06f08..95a60e406a8 100644 --- a/libstdc++-v3/include/std/type_traits +++ b/libstdc++-v3/include/std/type_traits @@ -3316,7 +3316,7 @@ template <typename _From, typename _To> inline constexpr bool is_scoped_enum_v = is_scoped_enum<_Tp>::value; #endif // C++23 -#ifdef _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED +#if __has_builtin(__builtin_is_constant_evaluated) #define __cpp_lib_is_constant_evaluated 201811L diff --git a/libstdc++-v3/include/std/version b/libstdc++-v3/include/std/version index 27bcd32cb60..3bb50d37a72 100644 --- a/libstdc++-v3/include/std/version +++ b/libstdc++-v3/include/std/version @@ -111,7 +111,7 @@ #endif #define __cpp_lib_is_invocable 201703 #define __cpp_lib_is_swappable 201603 -#ifdef _GLIBCXX_HAVE_BUILTIN_LAUNDER +#if __has_builtin(__builtin_launder) # define __cpp_lib_launder 201606 #endif #define __cpp_lib_logical_traits 201510 @@ -130,7 +130,7 @@ #define __cpp_lib_chrono 201611 #define __cpp_lib_clamp 201603 #if __cplusplus == 201703L // N.B. updated value in C++20 -# if _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED +# if __has_builtin(__builtin_is_constant_evaluated) # define __cpp_lib_constexpr_char_traits 201611L # define __cpp_lib_constexpr_string 201611L # endif @@ -188,7 +188,7 @@ #endif #define __cpp_lib_endian 201907L #define __cpp_lib_int_pow2 202002L -#ifdef _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED +#ifdef __has_builtin(__builtin_is_constant_evaluated) # define __cpp_lib_is_constant_evaluated 201811L #endif #define __cpp_lib_is_nothrow_convertible 201806L diff --git a/libstdc++-v3/libsupc++/new b/libstdc++-v3/libsupc++/new index 3349b13fd1b..8774b333b90 100644 --- a/libstdc++-v3/libsupc++/new +++ b/libstdc++-v3/libsupc++/new @@ -182,8 +182,7 @@ inline void operator delete[](void*, void*) _GLIBCXX_USE_NOEXCEPT { } //@} } // extern "C++" -#if __cplusplus >= 201703L -#ifdef _GLIBCXX_HAVE_BUILTIN_LAUNDER +#if __cplusplus >= 201703L && __has_builtin(__builtin_launder) namespace std { #define __cpp_lib_launder 201606 @@ -206,7 +205,6 @@ namespace std void launder(volatile void*) = delete; void launder(const volatile void*) = delete; } -#endif // _GLIBCXX_HAVE_BUILTIN_LAUNDER #endif // C++17 #if __cplusplus > 201703L