-
Notifications
You must be signed in to change notification settings - Fork 12k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[libc++][RFC] Always define internal feature test macros #89178
Conversation
@llvm/pr-subscribers-libcxxabi @llvm/pr-subscribers-libcxx Author: Nikolas Klauser (philnik777) ChangesCurrently, the library-internal feature test macros are only defined if the feature is not available, and always have the prefix The current patch only touches the macros defined in Patch is 205.98 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/89178.diff 111 Files Affected:
diff --git a/libcxx/include/__atomic/aliases.h b/libcxx/include/__atomic/aliases.h
index e27e09af6b77d9..afc64eaaa69e7b 100644
--- a/libcxx/include/__atomic/aliases.h
+++ b/libcxx/include/__atomic/aliases.h
@@ -37,7 +37,7 @@ using atomic_long = atomic<long>;
using atomic_ulong = atomic<unsigned long>;
using atomic_llong = atomic<long long>;
using atomic_ullong = atomic<unsigned long long>;
-#ifndef _LIBCPP_HAS_NO_CHAR8_T
+#if _LIBCPP_HAS_CHAR8_T
using atomic_char8_t = atomic<char8_t>;
#endif
using atomic_char16_t = atomic<char16_t>;
diff --git a/libcxx/include/__atomic/atomic_lock_free.h b/libcxx/include/__atomic/atomic_lock_free.h
index 0715439db45039..3ae9b8856e8102 100644
--- a/libcxx/include/__atomic/atomic_lock_free.h
+++ b/libcxx/include/__atomic/atomic_lock_free.h
@@ -18,7 +18,7 @@
#if defined(__CLANG_ATOMIC_BOOL_LOCK_FREE)
# define ATOMIC_BOOL_LOCK_FREE __CLANG_ATOMIC_BOOL_LOCK_FREE
# define ATOMIC_CHAR_LOCK_FREE __CLANG_ATOMIC_CHAR_LOCK_FREE
-# ifndef _LIBCPP_HAS_NO_CHAR8_T
+# if _LIBCPP_HAS_CHAR8_T
# define ATOMIC_CHAR8_T_LOCK_FREE __CLANG_ATOMIC_CHAR8_T_LOCK_FREE
# endif
# define ATOMIC_CHAR16_T_LOCK_FREE __CLANG_ATOMIC_CHAR16_T_LOCK_FREE
@@ -32,7 +32,7 @@
#elif defined(__GCC_ATOMIC_BOOL_LOCK_FREE)
# define ATOMIC_BOOL_LOCK_FREE __GCC_ATOMIC_BOOL_LOCK_FREE
# define ATOMIC_CHAR_LOCK_FREE __GCC_ATOMIC_CHAR_LOCK_FREE
-# ifndef _LIBCPP_HAS_NO_CHAR8_T
+# if _LIBCPP_HAS_CHAR8_T
# define ATOMIC_CHAR8_T_LOCK_FREE __GCC_ATOMIC_CHAR8_T_LOCK_FREE
# endif
# define ATOMIC_CHAR16_T_LOCK_FREE __GCC_ATOMIC_CHAR16_T_LOCK_FREE
diff --git a/libcxx/include/__availability b/libcxx/include/__availability
index aa761eb5bfe5e3..413c54d7a334cc 100644
--- a/libcxx/include/__availability
+++ b/libcxx/include/__availability
@@ -315,10 +315,10 @@
#endif
-// Define availability attributes that depend on _LIBCPP_HAS_NO_EXCEPTIONS.
+// Define availability attributes that depend on _LIBCPP_HAS_EXCEPTIONS.
// Those are defined in terms of the availability attributes above, and
// should not be vendor-specific.
-#if defined(_LIBCPP_HAS_NO_EXCEPTIONS)
+#if !_LIBCPP_HAS_EXCEPTIONS
# define _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST
# define _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
# define _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS
@@ -329,8 +329,8 @@
#endif
// Define availability attributes that depend on both
-// _LIBCPP_HAS_NO_EXCEPTIONS and _LIBCPP_HAS_NO_RTTI.
-#if defined(_LIBCPP_HAS_NO_EXCEPTIONS) || defined(_LIBCPP_HAS_NO_RTTI)
+// _LIBCPP_HAS_EXCEPTIONS and _LIBCPP_HAS_RTTI.
+#if !_LIBCPP_HAS_EXCEPTIONS || !_LIBCPP_HAS_RTTI
# undef _LIBCPP_AVAILABILITY_HAS_INIT_PRIMARY_EXCEPTION
# undef _LIBCPP_AVAILABILITY_INIT_PRIMARY_EXCEPTION
# define _LIBCPP_AVAILABILITY_HAS_INIT_PRIMARY_EXCEPTION 0
diff --git a/libcxx/include/__bit/byteswap.h b/libcxx/include/__bit/byteswap.h
index 20045d6fd43cb5..6226862cdc9c63 100644
--- a/libcxx/include/__bit/byteswap.h
+++ b/libcxx/include/__bit/byteswap.h
@@ -32,7 +32,7 @@ _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Tp byteswap(_Tp __val) no
return __builtin_bswap32(__val);
} else if constexpr (sizeof(_Tp) == 8) {
return __builtin_bswap64(__val);
-# ifndef _LIBCPP_HAS_NO_INT128
+# if _LIBCPP_HAS_INT128
} else if constexpr (sizeof(_Tp) == 16) {
# if __has_builtin(__builtin_bswap128)
return __builtin_bswap128(__val);
@@ -40,7 +40,7 @@ _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Tp byteswap(_Tp __val) no
return static_cast<_Tp>(byteswap(static_cast<uint64_t>(__val))) << 64 |
static_cast<_Tp>(byteswap(static_cast<uint64_t>(__val >> 64)));
# endif // __has_builtin(__builtin_bswap128)
-# endif // _LIBCPP_HAS_NO_INT128
+# endif // _LIBCPP_HAS_INT128
} else {
static_assert(sizeof(_Tp) == 0, "byteswap is unimplemented for integral types of this size");
}
diff --git a/libcxx/include/__bit/countl.h b/libcxx/include/__bit/countl.h
index 13df8d4e66c402..767052ddabe913 100644
--- a/libcxx/include/__bit/countl.h
+++ b/libcxx/include/__bit/countl.h
@@ -39,7 +39,7 @@ _LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int __libcpp_cl
return __builtin_clzll(__x);
}
-#ifndef _LIBCPP_HAS_NO_INT128
+#if _LIBCPP_HAS_INT128
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int __libcpp_clz(__uint128_t __x) _NOEXCEPT {
# if __has_builtin(__builtin_clzg)
return __builtin_clzg(__x);
@@ -57,7 +57,7 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int __libcpp_clz(__uint128_t __x)
: __builtin_clzll(static_cast<unsigned long long>(__x >> 64));
# endif
}
-#endif // _LIBCPP_HAS_NO_INT128
+#endif // _LIBCPP_HAS_INT128
template <class _Tp>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 int __countl_zero(_Tp __t) _NOEXCEPT {
diff --git a/libcxx/include/__charconv/tables.h b/libcxx/include/__charconv/tables.h
index 6b93536b8c1bac..9568bf841cd029 100644
--- a/libcxx/include/__charconv/tables.h
+++ b/libcxx/include/__charconv/tables.h
@@ -95,7 +95,7 @@ inline constexpr uint64_t __pow10_64[20] = {
UINT64_C(1000000000000000000),
UINT64_C(10000000000000000000)};
-# ifndef _LIBCPP_HAS_NO_INT128
+# if _LIBCPP_HAS_INT128
inline constexpr int __pow10_128_offset = 0;
inline constexpr __uint128_t __pow10_128[40] = {
UINT64_C(0),
diff --git a/libcxx/include/__charconv/to_chars_base_10.h b/libcxx/include/__charconv/to_chars_base_10.h
index c49f4f6797aa43..06e4e692337df5 100644
--- a/libcxx/include/__charconv/to_chars_base_10.h
+++ b/libcxx/include/__charconv/to_chars_base_10.h
@@ -124,7 +124,7 @@ __base_10_u64(char* __buffer, uint64_t __value) noexcept {
return __itoa::__append10(__buffer, __value);
}
-# ifndef _LIBCPP_HAS_NO_INT128
+# if _LIBCPP_HAS_INT128
/// \returns 10^\a exp
///
/// \pre \a exp [19, 39]
diff --git a/libcxx/include/__charconv/to_chars_integral.h b/libcxx/include/__charconv/to_chars_integral.h
index 0369f4dfb9bda6..e7583bcdaa64b5 100644
--- a/libcxx/include/__charconv/to_chars_integral.h
+++ b/libcxx/include/__charconv/to_chars_integral.h
@@ -70,7 +70,7 @@ __to_chars_itoa(char* __first, char* __last, _Tp __value, false_type) {
return {__last, errc::value_too_large};
}
-# ifndef _LIBCPP_HAS_NO_INT128
+# if _LIBCPP_HAS_INT128
template <>
inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result
__to_chars_itoa(char* __first, char* __last, __uint128_t __value, false_type) {
diff --git a/libcxx/include/__charconv/traits.h b/libcxx/include/__charconv/traits.h
index c91c6da3247978..2cb37c8cfb0238 100644
--- a/libcxx/include/__charconv/traits.h
+++ b/libcxx/include/__charconv/traits.h
@@ -88,7 +88,7 @@ struct _LIBCPP_HIDDEN __traits_base<_Tp, __enable_if_t<sizeof(_Tp) == sizeof(uin
}
};
-# ifndef _LIBCPP_HAS_NO_INT128
+# if _LIBCPP_HAS_INT128
template <typename _Tp>
struct _LIBCPP_HIDDEN __traits_base<_Tp, __enable_if_t<sizeof(_Tp) == sizeof(__uint128_t)> > {
using type = __uint128_t;
diff --git a/libcxx/include/__chrono/file_clock.h b/libcxx/include/__chrono/file_clock.h
index 7d25729fec013a..f791614c253909 100644
--- a/libcxx/include/__chrono/file_clock.h
+++ b/libcxx/include/__chrono/file_clock.h
@@ -48,7 +48,7 @@ _LIBCPP_END_NAMESPACE_STD
#ifndef _LIBCPP_CXX03_LANG
_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
struct _FilesystemClock {
-# if !defined(_LIBCPP_HAS_NO_INT128)
+# if _LIBCPP_HAS_INT128
typedef __int128_t rep;
typedef nano period;
# else
diff --git a/libcxx/include/__config b/libcxx/include/__config
index 4ccef2ca0d73b4..f2e12e9106d937 100644
--- a/libcxx/include/__config
+++ b/libcxx/include/__config
@@ -533,6 +533,7 @@ _LIBCPP_HARDENING_MODE_DEBUG
# define _NOEXCEPT noexcept
# define _NOEXCEPT_(...) noexcept(__VA_ARGS__)
# define _LIBCPP_CONSTEXPR constexpr
+# define _LIBCPP_HAS_NOEXCEPT 1
# else
@@ -540,7 +541,7 @@ _LIBCPP_HARDENING_MODE_DEBUG
# define _ALIGNAS_TYPE(x) __attribute__((__aligned__(_LIBCPP_ALIGNOF(x))))
# define _ALIGNAS(x) __attribute__((__aligned__(x)))
# define _LIBCPP_NORETURN __attribute__((__noreturn__))
-# define _LIBCPP_HAS_NO_NOEXCEPT
+# define _LIBCPP_HAS_NOEXCEPT 0
# define nullptr __nullptr
# define _NOEXCEPT throw()
# define _NOEXCEPT_(...)
@@ -554,7 +555,9 @@ typedef __char32_t char32_t;
# endif
# if !defined(__cpp_exceptions) || __cpp_exceptions < 199711L
-# define _LIBCPP_HAS_NO_EXCEPTIONS
+# define _LIBCPP_HAS_EXCEPTIONS 0
+# else
+# define _LIBCPP_HAS_EXCEPTIONS 1
# endif
# define _LIBCPP_PREFERRED_ALIGNOF(_Tp) __alignof(_Tp)
@@ -591,8 +594,10 @@ typedef __char32_t char32_t;
# define _LIBCPP_HAS_BLOCKS_RUNTIME
# endif
-# if !__has_feature(address_sanitizer)
-# define _LIBCPP_HAS_NO_ASAN
+# if __has_feature(address_sanitizer)
+# define _LIBCPP_HAS_ASAN 1
+# else
+# define _LIBCPP_HAS_ASAN 0
# endif
# define _LIBCPP_ALWAYS_INLINE __attribute__((__always_inline__))
@@ -601,8 +606,10 @@ typedef __char32_t char32_t;
# elif defined(_LIBCPP_COMPILER_GCC)
-# if !defined(__SANITIZE_ADDRESS__)
-# define _LIBCPP_HAS_NO_ASAN
+# if defined(__SANITIZE_ADDRESS__)
+# define _LIBCPP_HAS_ASAN 1
+# else
+# define _LIBCPP_HAS_ASAN 0
# endif
# define _LIBCPP_ALWAYS_INLINE __attribute__((__always_inline__))
@@ -727,7 +734,7 @@ typedef __char32_t char32_t;
# define _LIBCPP_HARDENING_SIG n // "none"
# endif
-# ifdef _LIBCPP_HAS_NO_EXCEPTIONS
+# if !_LIBCPP_HAS_EXCEPTIONS
# define _LIBCPP_EXCEPTIONS_SIG n
# else
# define _LIBCPP_EXCEPTIONS_SIG e
@@ -856,7 +863,9 @@ typedef __char32_t char32_t;
# endif
# if !defined(__SIZEOF_INT128__) || defined(_MSC_VER)
-# define _LIBCPP_HAS_NO_INT128
+# define _LIBCPP_HAS_INT128 0
+# else
+# define _LIBCPP_HAS_INT128 1
# endif
# ifdef _LIBCPP_CXX03_LANG
@@ -888,17 +897,21 @@ typedef __char32_t char32_t;
// If we are getting operator new from the MSVC CRT, then allocation overloads
// for align_val_t were added in 19.12, aka VS 2017 version 15.3.
# if defined(_LIBCPP_MSVCRT) && defined(_MSC_VER) && _MSC_VER < 1912
-# define _LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION
+# define _LIBCPP_HAS_LIBRARY_ALIGNED_ALLOCATION 0
# elif defined(_LIBCPP_ABI_VCRUNTIME) && !defined(__cpp_aligned_new)
// We're deferring to Microsoft's STL to provide aligned new et al. We don't
// have it unless the language feature test macro is defined.
-# define _LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION
+# define _LIBCPP_HAS_LIBRARY_ALIGNED_ALLOCATION 0
# elif defined(__MVS__)
-# define _LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION
+# define _LIBCPP_HAS_LIBRARY_ALIGNED_ALLOCATION 0
+# else
+# define _LIBCPP_HAS_LIBRARY_ALIGNED_ALLOCATION 1
# endif
-# if defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION) || (!defined(__cpp_aligned_new) || __cpp_aligned_new < 201606)
-# define _LIBCPP_HAS_NO_ALIGNED_ALLOCATION
+# if !_LIBCPP_HAS_LIBRARY_ALIGNED_ALLOCATION || (!defined(__cpp_aligned_new) || __cpp_aligned_new < 201606)
+# define _LIBCPP_HAS_ALIGNED_ALLOCATION 0
+# else
+# define _LIBCPP_HAS_ALIGNED_ALLOCATION 1
# endif
// It is not yet possible to use aligned_alloc() on all Apple platforms since
@@ -906,11 +919,15 @@ typedef __char32_t char32_t;
# if defined(__APPLE__)
# if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && \
__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101500)
-# define _LIBCPP_HAS_NO_C11_ALIGNED_ALLOC
+# define _LIBCPP_HAS_C11_ALIGNED_ALLOC 0
+# else
+# define _LIBCPP_HAS_C11_ALIGNED_ALLOC 1
# endif
# elif defined(__ANDROID__) && __ANDROID_API__ < 28
// Android only provides aligned_alloc when targeting API 28 or higher.
-# define _LIBCPP_HAS_NO_C11_ALIGNED_ALLOC
+# define _LIBCPP_HAS_C11_ALIGNED_ALLOC 0
+# else
+# define _LIBCPP_HAS_C11_ALIGNED_ALLOC 1
# endif
# if defined(__APPLE__) || defined(__FreeBSD__)
@@ -922,7 +939,9 @@ typedef __char32_t char32_t;
# endif
# if _LIBCPP_STD_VER <= 17 || !defined(__cpp_char8_t)
-# define _LIBCPP_HAS_NO_CHAR8_T
+# define _LIBCPP_HAS_CHAR8_T 0
+# else
+# define _LIBCPP_HAS_CHAR8_T 1
# endif
// Deprecation macros.
@@ -989,7 +1008,7 @@ typedef __char32_t char32_t;
# define _LIBCPP_DEPRECATED_IN_CXX26
# endif
-# if !defined(_LIBCPP_HAS_NO_CHAR8_T)
+# if _LIBCPP_HAS_CHAR8_T
# define _LIBCPP_DEPRECATED_WITH_CHAR8_T _LIBCPP_DEPRECATED
# else
# define _LIBCPP_DEPRECATED_WITH_CHAR8_T
@@ -1044,7 +1063,9 @@ typedef __char32_t char32_t;
// Try to find out if RTTI is disabled.
# if !defined(__cpp_rtti) || __cpp_rtti < 199711L
-# define _LIBCPP_HAS_NO_RTTI
+# define _LIBCPP_HAS_RTTI 0
+# else
+# define _LIBCPP_HAS_RTTI 1
# endif
# ifndef _LIBCPP_WEAK
@@ -1153,8 +1174,9 @@ typedef __char32_t char32_t;
# if !defined(_LIBCPP_HAS_C_ATOMIC_IMP) && !defined(_LIBCPP_HAS_GCC_ATOMIC_IMP) && \
!defined(_LIBCPP_HAS_EXTERNAL_ATOMIC_IMP)
-# define _LIBCPP_HAS_NO_ATOMIC_HEADER
+# define _LIBCPP_HAS_ATOMIC_HEADER 0
# else
+# define _LIBCPP_HAS_ATOMIC_HEADER 1
# ifndef _LIBCPP_ATOMIC_FLAG_TYPE
# define _LIBCPP_ATOMIC_FLAG_TYPE bool
# endif
@@ -1271,7 +1293,7 @@ typedef __char32_t char32_t;
// functions is gradually being added to existing C libraries. The conditions
// below check for known C library versions and conditions under which these
// functions are declared by the C library.
-# define _LIBCPP_HAS_NO_C8RTOMB_MBRTOC8
+
// GNU libc 2.36 and newer declare c8rtomb() and mbrtoc8() in C++ modes if
// __cpp_char8_t is defined or if C2X extensions are enabled. Determining
// the latter depends on internal GNU libc details that are not appropriate
@@ -1279,8 +1301,12 @@ typedef __char32_t char32_t;
// defined are ignored.
# if defined(_LIBCPP_GLIBC_PREREQ)
# if _LIBCPP_GLIBC_PREREQ(2, 36) && defined(__cpp_char8_t)
-# undef _LIBCPP_HAS_NO_C8RTOMB_MBRTOC8
+# define _LIBCPP_HAS_C8RTOMB_MBRTOC8 1
+# else
+# define _LIBCPP_HAS_C8RTOMB_MBRTOC8 0
# endif
+# else
+# define _LIBCPP_HAS_C8RTOMB_MBRTOC8 0
# endif
// There are a handful of public standard library types that are intended to
diff --git a/libcxx/include/__debug_utils/sanitizers.h b/libcxx/include/__debug_utils/sanitizers.h
index d8547e32493303..73d192711eabb6 100644
--- a/libcxx/include/__debug_utils/sanitizers.h
+++ b/libcxx/include/__debug_utils/sanitizers.h
@@ -17,7 +17,7 @@
# pragma GCC system_header
#endif
-#ifndef _LIBCPP_HAS_NO_ASAN
+#if _LIBCPP_HAS_ASAN
extern "C" {
_LIBCPP_EXPORTED_FROM_ABI void
@@ -28,12 +28,12 @@ _LIBCPP_EXPORTED_FROM_ABI int
__sanitizer_verify_double_ended_contiguous_container(const void*, const void*, const void*, const void*);
}
-#endif // _LIBCPP_HAS_NO_ASAN
+#endif // _LIBCPP_HAS_ASAN
_LIBCPP_BEGIN_NAMESPACE_STD
// ASan choices
-#ifndef _LIBCPP_HAS_NO_ASAN
+#if _LIBCPP_HAS_ASAN
# define _LIBCPP_HAS_ASAN_CONTAINER_ANNOTATIONS_FOR_ALL_ALLOCATORS 1
#endif
@@ -57,7 +57,7 @@ _LIBCPP_HIDE_FROM_ABI void __annotate_double_ended_contiguous_container(
const void* __last_old_contained,
const void* __first_new_contained,
const void* __last_new_contained) {
-#ifdef _LIBCPP_HAS_NO_ASAN
+#if !_LIBCPP_HAS_ASAN
(void)__first_storage;
(void)__last_storage;
(void)__first_old_contained;
@@ -86,7 +86,7 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void __annotate_contiguous_c
const void* __last_storage,
const void* __old_last_contained,
const void* __new_last_contained) {
-#ifdef _LIBCPP_HAS_NO_ASAN
+#if !_LIBCPP_HAS_ASAN
(void)__first_storage;
(void)__last_storage;
(void)__old_last_contained;
diff --git a/libcxx/include/__exception/exception_ptr.h b/libcxx/include/__exception/exception_ptr.h
index c9027de9238cdd..b0c59017d9424a 100644
--- a/libcxx/include/__exception/exception_ptr.h
+++ b/libcxx/include/__exception/exception_ptr.h
@@ -87,7 +87,7 @@ class _LIBCPP_EXPORTED_FROM_ABI exception_ptr {
template <class _Ep>
_LIBCPP_HIDE_FROM_ABI exception_ptr make_exception_ptr(_Ep __e) _NOEXCEPT {
-# ifndef _LIBCPP_HAS_NO_EXCEPTIONS
+# if _LIBCPP_HAS_EXCEPTIONS
# if _LIBCPP_AVAILABILITY_HAS_INIT_PRIMARY_EXCEPTION && __cplusplus >= 201103L
using _Ep2 = __decay_t<_Ep>;
diff --git a/libcxx/include/__exception/nested_exception.h b/libcxx/include/__exception/nested_exception.h
index 1bf2df939258a6..4fa49e7a9c7a7f 100644
--- a/libcxx/include/__exception/nested_exception.h
+++ b/libcxx/include/__exception/nested_exception.h
@@ -47,7 +47,7 @@ struct __nested : public _Tp, public nested_exception {
_LIBCPP_HIDE_FROM_ABI explicit __nested(const _Tp& __t) : _Tp(__t) {}
};
-#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
+#if _LIBCPP_HAS_EXCEPTIONS
template <class _Tp, class _Up, bool>
struct __throw_with_nested;
@@ -66,7 +66,7 @@ struct __throw_with_nested<_Tp, _Up, false> {
template <class _Tp>
_LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI void throw_with_nested(_Tp&& __t) {
-#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
+#if _LIBCPP_HAS_EXCEPTIONS
using _Up = __decay_t<_Tp>;
static_assert(is_copy_constructible<_Up>::value, "type thrown must be CopyConstructible");
__throw_with_nested<_Tp,
diff --git a/libcxx/include/__expected/expected.h b/libcxx/include/__expected/expected.h
index d7adaac7567b2f..a60b0a3b6f8856 100644
--- a/libcxx/include/__expected/expected.h
+++ b/libcxx/include/__expected/expected.h
@@ -70,7 +70,7 @@ struct __expected_construct_unexpected_from_invoke_tag {};
template <class _Err, class _Arg>
_LIBCPP_HIDE_FROM_ABI void __throw_bad_expected_access(_Arg&& __arg) {
-# ifndef _LIBCPP_HAS_NO_EXCEPTIONS
+# if _LIBCPP_HAS_EXCEPTIONS
throw bad_expected_access<_Err>(std::forward<_Arg>(__arg));
# else
(void)__arg;
diff --git a/libcxx/include/__filesystem/filesystem_error.h b/libcxx/include/__filesystem/filesystem_error.h
index bfdcc5eaee521f..822a428d02ba6b 100644
--- a/libcxx/include/__filesystem/filesystem_error.h
+++ b/libcxx/include/__filesystem/filesystem_error.h
@@ -68,7 +68,7 @@ class _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_EXPORTED_FROM_ABI filesyst
shared_ptr<_Storage> __storage_;
};
-# ifndef _LIBCPP_HAS_NO_EXCEPTIONS
+# if _LIBCPP_HAS_EXCEPTIONS
template <class... _Args>
_LIBCPP_NORETURN inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY void
__throw_filesystem_error(_Args&&... __args) {
diff --git a/libcxx/include/__filesystem/path.h b/libcxx/include/__filesystem/path.h
index 9ffc90ada5e716..d8aa0af93ac9e0 100644
--- a/libcxx/include/__filesystem/path.h
+++ b/libcxx/include/__filesystem/path.h
@@ -60,7 +60,7 @@ struct __can_convert_char<wchar_t> {
static const bool value = true;
using __char_type = wchar_t;
};
-# ifndef _LIBCPP_HAS_NO_CHAR8_T
+# if _LIBCPP_HAS_CHAR8_T
template <>
struct __can_convert_char<char8_t> {
static const bool value = true;
@@ -87,7 +87,7 @@ _LIBCPP_HIDE_FROM_ABI bool __is_separator(_ECharT __e) {
# endif
}
-# ifndef _LIBCPP_HAS_NO_CHAR8_T
+# if _LIBCPP_HAS_CHAR8_T
typedef u8string __u8_string;
# else
typedef string __u8_string;
@@ -366,7 +366,7 @@ struct _PathExport<char16_t> {
}
};
-# ifndef _LIBCPP_HAS_NO_CHAR8_T
+# if _LIBCPP_HAS_CHAR8_T
template <>
struct _PathExport<char8_t> {
typedef __narrow_to_utf8<sizeof(wchar_t) * __CHAR_BIT__> _Narrower;
@@ -376,7 +376,7 @@ struct _PathExport<char8_t> {
_Narrower()(back_inserter(__dest), __src.data(), __src.data() + __src.size());
}
};
-# endif /* !_LIBCPP_HAS_NO_CHAR8_T */
+# endif // _LIBCPP_HAS_CHAR8_T
# endif /* _LIBCPP_WIN32API */
class _LIBCPP_EXPORTED_FROM_ABI path {
@@ -730,7 +730,7 @@ class _LIBCPP_EXPORTED_FROM_ABI path {
# else /* _LIBCPP_WIN32API */
_LIBCPP_HIDE_FROM_ABI std::string string() const { return __pn_; }
-# ifndef _LIBCPP_HAS_NO_CHAR8_T
+# if _LIBCPP_HAS_CHAR8_T
_LIBCPP_HIDE_FROM_ABI std::u8string u8string() const { return std::u8string(__pn_.begin(), __pn_.end()); }
# else
_LIBCPP_HIDE_FROM_ABI std::string u8string() const { return __pn_; }
@@ -756,7 +756,7 @@ class _LIBCPP_EXPORTED_FROM_ABI path {
// generic format observers
_LIBCPP_HIDE_FROM_ABI std::string generic_string() const { return __pn_; }
-# ifndef _LIBCPP_HAS_NO_CHAR8_T
+# if _LIBCPP_HAS_CHAR8_T
_LIBCPP_HIDE_FROM_ABI std::u8string generic_u8string() const...
[truncated]
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I generally like this change.
On the one hand, I love getting rid of the double negative, the fact that we'll trigger -Wundef
and the fact that we make it a bit clearer what is intended to be set by the library and not by users.
On the other hand, this change makes it look a bit like _LIBCPP_HAS_EXCEPTION
is an "optional" feature just like having ASAN turned on. I guess they are actually the same and I just don't think about them that way, but it could be that _LIBCPP_HAS_NO_EXCEPTIONS
has been there for so long and is so prevalent that it has a special place in my mind.
I am generally happy with this patch, but I expect it will require a bit of adjustment for downstreams. Pinging @llvm/libcxx-vendors for awareness.
I'm eager to know what other folks think about this, so I won't approve just yet. Let's let this bake for at least a few days.
What kinds of adjustments downstream do you expect this will require? Maybe it's just something historical, but I see some OTOH, it seems suspicious that we're setting these in the first place. If the conditions in One common option I see being set is +1 to this patch being an improvement, especially with the removal of double-negative as mentioned. |
Since this touches a lot of widely used macros, any downstream-only code that is conditionalized on exceptions would likely use
If you can share which
Exactly, right. So libc++ has a notion of "user configurable settings", but not all the In the general case, users are not expected to define any
It looks like an oversight on @philnik777 's part. It also seems incorrect for users to be setting that, since this should be done via IMO this patch can be a first step towards formalizing what is and isn't a user-configurable setting. We could potentially use a different naming convention to make it more obvious what is configurable. Or we could potentially do something like
That would make it clear what we intend for users to set and what we don't. But any such thing should be left for a different patch. |
Or we could also use final macros, which I just learned about: https://clang.llvm.org/docs/LanguageExtensions.html#final-macros #pragma clang final(_LIBCPP_HAS_EXCEPTIONS)
#if __has_feature(__cxx_exceptions)
# define _LIBCPP_HAS_EXCEPTIONS 1
#else
# define _LIBCPP_HAS_EXCEPTIONS 0
#endif IDK if that behaves exactly how we want, but basically we have a few options on the table. |
Oh, I was only looking at build configurations, I completely forgot about that. I see quite a bit more when I expand the scope for things like that, e.g. https://github.com/abseil/abseil-cpp/blob/192e959b16809f751d565b53a949b21129d904fb/absl/hash/internal/hash.h#L73 Probably still tractable, but not as trivial as I thought. It may help to temporarily leave in the old definitions for downstream use, even if libc++ itself does not use it, i.e.
(we may just need this for some popular subset of macros)
_LIBCPP_HAS_NO_FILESYSTEM_LIBRARY
It looks like all the usage is in build macros to generate a |
As I said in the commit message, this only changes FTMs configured in
We don't use these macro names anymore, so any code that checks the macro is already broken.
I don't know why anybody would ever want to define that. Maybe some workaround for a bug?
I'd be really interested what the reasoning for these is. Maybe not properly configured libc++ builds and people try to work around it?
I don't plan to change that one, but it should really only be set by our tests. OTOH I don't really care if people can't configure their warnings correctly because they define library-internal macros. |
GCC does not implement the availability attribute (yet) I've been working on it - but it won't be in GCC-14 - so this would potentially affect GCC on Apple platforms.
No 32b targets left? |
Availability annotations are disabled automatically on non-Clang compilers and __int128 availability is also detected through |
eebe2de
to
06875ef
Compare
72bd8d4
to
96bc5d5
Compare
This specific usage looks wrong. I think it was a workaround for the fact that feature-test macros didn't take into account availability on the deployment target, but this has been fixed now. Checking for the feature-test macro only should be sufficient. |
95b5825
to
a9b419b
Compare
I have a preference for the existing mechanisms. They've not caused my any trouble in my time on the project. I think the existing mechanisms encourage/enforce the use of negative feature test macro names (ex. This would change very long standing existing practice, which according to my recollection hasn't caused any major problems. Generally the macros are specified in the negative form (ex. _LIBCPP_HAS_NO_EXCEPTIONS), so they're only defined when a feature isn't available. Because the current practice is so long standing, I would like this change to come with a clang-tidy that looked for misapplication of |
I'm not sure how the current mechanism is more robust. A misspelling might not be caught other than by testing the actual code (eg.
While the practice is long-standing, the names of the individual macros changed before (cf65d27, b22aa3d, 5c40c99, 66a562d), without any major fallout I'm aware of. So I don't think a clang-tidy check pulls its weight here. A general check for internal macros might be nice, but is definitely out of scope for this change. |
Yes, like with That said, lets say had #ifndef _LIBCPP_HAS_NO_EXXXXCEPTIONS
throw 42;
#endif This gets caught because the code fails to compile. If the code successfully compiles, that means there's some other bugs going on that needs fixing. So it catches both misspellings and misconfigurations. Note that the negative naming of the macro matters here. It's And is important even with the new approach. With this change, we open up a bunch of new failure modes. I'm more ok with changing to 1 or 0 than I am removing the negative feature test names. Did the Let me know if I need to do a better job of explaining why positive names are less desirable than negative ones.
Would you mind referencing the change?
You're renaming the macros because macro usage is bug prone. I'm don't agree with the claim, and I don't think it's out of scope, given that this change is about catching macro bugs and is otherwise NFC. Let me know how you would like to proceed. |
I would like to better understand this aspect. My understanding is that we've been using negative "configuration macros" mainly because when we use However, note that this pattern doesn't always make sense. For example, @philnik777 pointed out to me that we have This patch basically puts all the configuration macros on the "same level" and uses a consistent mechanism to handle all of them. There's still the question of whether we want to have #if !_LIBCPP_HAS_NO_EXCEPTIONS
...
#endif versus #if _LIBCPP_HAS_EXCEPTIONS
...
#endif IMO, avoiding the double-negative in this case makes things a lot easier to understand. To summarize: I agree that negative macros make more sense in a |
I agree, I don't like double negation. It's hard to read. If the change makes our lives easier we should do it. |
I agree with most of what @ldionne said. There in benefit to the negative macro formulation that is lost. This can be mitigated by testing, and by tooling. If we're going to go this path, I think we should change the naming scheme to remove I might suggest |
I don't believe any of those changes changed the way the macro works. They simply re-named things. So I wouldn't expect them to have "fallout" in the way I'm suggesting. Also, if the purpose of this change is entirely for bug prevention & macro misuse, then a tool to assist with that is well in scope. |
a9b419b
to
574abbd
Compare
In light of the discussion we had in the libc++ monthly, I think we could update this patch. @philnik777 |
d2c09d2
to
b65c0ef
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This basically LGTM with a few comments. Let's try to land this soon to avoid many merge conflicts. I'd still like to have another look once the comments have been addressed.
This simplifies some complicated conditionals so much.
cc8658f
to
a8c8d14
Compare
@@ -98,7 +100,7 @@ inline _LIBCPP_HIDE_FROM_ABI _ValueType __libcpp_acquire_load(_ValueType const* | |||
|
|||
template <class _Tp> | |||
inline _LIBCPP_HIDE_FROM_ABI _Tp __libcpp_atomic_refcount_increment(_Tp& __t) _NOEXCEPT { | |||
#if defined(_LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT) && !defined(_LIBCPP_HAS_NO_THREADS) | |||
#if _LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT && !defined(_LIBCPP_HAS_NO_THREADS) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to very quickly switch over to the same scheme for _LIBCPP_HAS_NO_THREADS
and other things in __config_site
, because that will become really confusing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll work on it as soon as this is landed.
a8c8d14
to
9510968
Compare
Currently, the library-internal feature test macros are only defined if the feature is not available, and always have the prefix `_LIBCPP_HAS_NO_`. This patch changes that, so that they are always defined and have the prefix `_LIBCPP_HAS_` instead. This changes the canonical use of these macros to `#if _LIBCPP_HAS_FEATURE`, which means that using an undefined macro (e.g. due to a missing include) is diagnosed now. While this is rather unlikely currently, a similar change in `<__configuration/availability.h>` caught a few bugs. This also improves readability, since it removes the double-negation of `#ifndef _LIBCPP_HAS_NO_FEATURE`. The current patch only touches the macros defined in `<__config>`. If people are happy with this approach, I'll make a follow-up PR to also change the macros defined in `<__config_site>`.
Currently, the library-internal feature test macros are only defined if the feature is not available, and always have the prefix `_LIBCPP_HAS_NO_`. This patch changes that, so that they are always defined and have the prefix `_LIBCPP_HAS_` instead. This changes the canonical use of these macros to `#if _LIBCPP_HAS_FEATURE`, which means that using an undefined macro (e.g. due to a missing include) is diagnosed now. While this is rather unlikely currently, a similar change in `<__configuration/availability.h>` caught a few bugs. This also improves readability, since it removes the double-negation of `#ifndef _LIBCPP_HAS_NO_FEATURE`. The current patch only touches the macros defined in `<__config>`. If people are happy with this approach, I'll make a follow-up PR to also change the macros defined in `<__config_site>`.
Currently, the library-internal feature test macros are only defined if the feature is not available, and always have the prefix `_LIBCPP_HAS_NO_`. This patch changes that, so that they are always defined and have the prefix `_LIBCPP_HAS_` instead. This changes the canonical use of these macros to `#if _LIBCPP_HAS_FEATURE`, which means that using an undefined macro (e.g. due to a missing include) is diagnosed now. While this is rather unlikely currently, a similar change in `<__configuration/availability.h>` caught a few bugs. This also improves readability, since it removes the double-negation of `#ifndef _LIBCPP_HAS_NO_FEATURE`. The current patch only touches the macros defined in `<__config>`. If people are happy with this approach, I'll make a follow-up PR to also change the macros defined in `<__config_site>`.
Currently, the library-internal feature test macros are only defined if the feature is not available, and always have the prefix
_LIBCPP_HAS_NO_
. This patch changes that, so that they are always defined and have the prefix_LIBCPP_HAS_
instead. This changes the canonical use of these macros to#if _LIBCPP_HAS_FEATURE
, which means that using an undefined macro (e.g. due to a missing include) is diagnosed now. While this is rather unlikely currently, a similar change in<__configuration/availability.h>
caught a few bugs. This also improves readability, since it removes the double-negation of#ifndef _LIBCPP_HAS_NO_FEATURE
.The current patch only touches the macros defined in
<__config>
. If people are happy with this approach, I'll make a follow-up PR to also change the macros defined in<__config_site>
.