Skip to content

Commit 4d323e4

Browse files
authored
[libc++] Allow the use of extensions in the implementation (#79532)
We've talked about allowing extensions on [discourse](https://discourse.llvm.org/t/rfc-use-language-extensions-from-future-standards-in-libc/71898/5) and in a libc++ monthly meeting and agreed to test it out in the LLVM 18 release. We've done that with the `tuple` constructor overload set (using conditional `explicit`). Since we haven't heard about any breakages, it seems safe to do. This patch enables the use of extension from later C++ standards inside the versioned `std` namespaces. This should be good enough, since almost all of our code is inside that namespace. This approach also avoids the use of extensions inside the test `std` suite. That part of the code base should stay clean, since it's a test suite that is also used by other vendors to test their implementations.
1 parent 624ea68 commit 4d323e4

File tree

2 files changed

+41
-26
lines changed

2 files changed

+41
-26
lines changed

libcxx/include/__config

Lines changed: 41 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,10 @@ _LIBCPP_HARDENING_MODE_DEBUG
406406
# define __has_include(...) 0
407407
# endif
408408

409+
# ifndef __has_warning
410+
# define __has_warning(...) 0
411+
# endif
412+
409413
# if !defined(_LIBCPP_COMPILER_CLANG_BASED) && __cplusplus < 201103L
410414
# error "libc++ only supports C++03 with Clang-based compilers. Please enable C++11"
411415
# endif
@@ -723,6 +727,23 @@ typedef __char32_t char32_t;
723727
# define _LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION _LIBCPP_ALWAYS_INLINE
724728
# endif
725729

730+
# ifdef _LIBCPP_COMPILER_CLANG_BASED
731+
# define _LIBCPP_DIAGNOSTIC_PUSH _Pragma("clang diagnostic push")
732+
# define _LIBCPP_DIAGNOSTIC_POP _Pragma("clang diagnostic pop")
733+
# define _LIBCPP_CLANG_DIAGNOSTIC_IGNORED(str) _Pragma(_LIBCPP_TOSTRING(clang diagnostic ignored str))
734+
# define _LIBCPP_GCC_DIAGNOSTIC_IGNORED(str)
735+
# elif defined(_LIBCPP_COMPILER_GCC)
736+
# define _LIBCPP_DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push")
737+
# define _LIBCPP_DIAGNOSTIC_POP _Pragma("GCC diagnostic pop")
738+
# define _LIBCPP_CLANG_DIAGNOSTIC_IGNORED(str)
739+
# define _LIBCPP_GCC_DIAGNOSTIC_IGNORED(str) _Pragma(_LIBCPP_TOSTRING(GCC diagnostic ignored str))
740+
# else
741+
# define _LIBCPP_DIAGNOSTIC_PUSH
742+
# define _LIBCPP_DIAGNOSTIC_POP
743+
# define _LIBCPP_CLANG_DIAGNOSTIC_IGNORED(str)
744+
# define _LIBCPP_GCC_DIAGNOSTIC_IGNORED(str)
745+
# endif
746+
726747
# if _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_FAST
727748
# define _LIBCPP_HARDENING_SIG f
728749
# elif _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_EXTENSIVE
@@ -810,16 +831,33 @@ typedef __char32_t char32_t;
810831
# define _LIBCPP_HIDE_FROM_ABI_AFTER_V1 _LIBCPP_HIDE_FROM_ABI
811832
# endif
812833

834+
// TODO: Remove this workaround once we drop support for Clang 16
835+
#if __has_warning("-Wc++23-extensions")
836+
# define _LIBCPP_CLANG_DIAGNOSTIC_IGNORED_CXX23_EXTENSION _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wc++23-extensions")
837+
#else
838+
# define _LIBCPP_CLANG_DIAGNOSTIC_IGNORED_CXX23_EXTENSION _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wc++2b-extensions")
839+
#endif
840+
813841
// Inline namespaces are available in Clang/GCC/MSVC regardless of C++ dialect.
814842
// clang-format off
815-
# define _LIBCPP_BEGIN_NAMESPACE_STD namespace _LIBCPP_TYPE_VISIBILITY_DEFAULT std { \
843+
# define _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_DIAGNOSTIC_PUSH \
844+
_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wc++11-extensions") \
845+
_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wc++14-extensions") \
846+
_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wc++17-extensions") \
847+
_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wc++20-extensions") \
848+
_LIBCPP_CLANG_DIAGNOSTIC_IGNORED_CXX23_EXTENSION \
849+
_LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wc++14-extensions") \
850+
_LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wc++17-extensions") \
851+
_LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wc++20-extensions") \
852+
_LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wc++23-extensions") \
853+
namespace _LIBCPP_TYPE_VISIBILITY_DEFAULT std { \
816854
inline namespace _LIBCPP_ABI_NAMESPACE {
817-
# define _LIBCPP_END_NAMESPACE_STD }}
855+
# define _LIBCPP_END_NAMESPACE_STD }} _LIBCPP_DIAGNOSTIC_POP
818856

819857
# define _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM _LIBCPP_BEGIN_NAMESPACE_STD \
820858
inline namespace __fs { namespace filesystem {
821859

822-
# define _LIBCPP_END_NAMESPACE_FILESYSTEM _LIBCPP_END_NAMESPACE_STD }}
860+
# define _LIBCPP_END_NAMESPACE_FILESYSTEM }} _LIBCPP_END_NAMESPACE_STD
823861
// clang-format on
824862

825863
# if __has_attribute(__enable_if__)
@@ -1256,23 +1294,6 @@ __sanitizer_verify_double_ended_contiguous_container(const void*, const void*, c
12561294
// the ABI inconsistent.
12571295
# endif
12581296

1259-
# ifdef _LIBCPP_COMPILER_CLANG_BASED
1260-
# define _LIBCPP_DIAGNOSTIC_PUSH _Pragma("clang diagnostic push")
1261-
# define _LIBCPP_DIAGNOSTIC_POP _Pragma("clang diagnostic pop")
1262-
# define _LIBCPP_CLANG_DIAGNOSTIC_IGNORED(str) _Pragma(_LIBCPP_TOSTRING(clang diagnostic ignored str))
1263-
# define _LIBCPP_GCC_DIAGNOSTIC_IGNORED(str)
1264-
# elif defined(_LIBCPP_COMPILER_GCC)
1265-
# define _LIBCPP_DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push")
1266-
# define _LIBCPP_DIAGNOSTIC_POP _Pragma("GCC diagnostic pop")
1267-
# define _LIBCPP_CLANG_DIAGNOSTIC_IGNORED(str)
1268-
# define _LIBCPP_GCC_DIAGNOSTIC_IGNORED(str) _Pragma(_LIBCPP_TOSTRING(GCC diagnostic ignored str))
1269-
# else
1270-
# define _LIBCPP_DIAGNOSTIC_PUSH
1271-
# define _LIBCPP_DIAGNOSTIC_POP
1272-
# define _LIBCPP_CLANG_DIAGNOSTIC_IGNORED(str)
1273-
# define _LIBCPP_GCC_DIAGNOSTIC_IGNORED(str)
1274-
# endif
1275-
12761297
// c8rtomb() and mbrtoc8() were added in C++20 and C23. Support for these
12771298
// functions is gradually being added to existing C libraries. The conditions
12781299
// below check for known C library versions and conditions under which these

libcxx/include/tuple

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -548,10 +548,6 @@ class _LIBCPP_TEMPLATE_VIS tuple {
548548
public:
549549
// [tuple.cnstr]
550550

551-
_LIBCPP_DIAGNOSTIC_PUSH
552-
_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wc++20-extensions")
553-
_LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wc++20-extensions")
554-
555551
// tuple() constructors (including allocator_arg_t variants)
556552
template <template <class...> class _IsImpDefault = __is_implicitly_default_constructible,
557553
template <class...> class _IsDefault = is_default_constructible,
@@ -833,8 +829,6 @@ public:
833829
: __base_(allocator_arg_t(), __alloc, std::move(__p)) {}
834830
# endif // _LIBCPP_STD_VER >= 23
835831

836-
_LIBCPP_DIAGNOSTIC_POP
837-
838832
// [tuple.assign]
839833
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 tuple&
840834
operator=(_If<_And<is_copy_assignable<_Tp>...>::value, tuple, __nat> const& __tuple)

0 commit comments

Comments
 (0)