Skip to content

Commit 673bf4f

Browse files
tahonermanntru
authored andcommitted
[libc++] Remove use of internal glibc macros to determine if c8rtomb() and mbrtoc8() are present.
When support for declaring the c8rtomb() and mbrtoc8() functions within the std namespace was added in commit 7e7013c, internal glibc macros were used to determine if C2X extensions are enabled. Specifically, a check for whether `__GLIBC_USE` is defined and whether `__GLIBC_USE(ISOC2X)` is non-0 was added. `__GLIBC_USE` is an internal detail of the glibc implementation that may be changed or removed in the future potentially leading to inconsistency or compilation failures. This change removes the use of the internal glibc macro to avoid such problems. Unfortunately, without another mechanism to determine if C2X extensions are enabled, this removal will result in inconsistent declarations of the c8rtomb() and mbrtoc8() functions; when C++ char8_t support is not enabled, but C2X extensions are, these functions will be declared in the global namespace but not in the std namespace. This situation will improve when C23 support is finalized and the check can be re-implemented using `__STDC_VERSION__`. (cherry picked from commit cf93a3d)
1 parent 60df88f commit 673bf4f

File tree

2 files changed

+17
-7
lines changed

2 files changed

+17
-7
lines changed

libcxx/include/__config

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1227,12 +1227,12 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
12271227
// functions are declared by the C library.
12281228
# define _LIBCPP_HAS_NO_C8RTOMB_MBRTOC8
12291229
// GNU libc 2.36 and newer declare c8rtomb() and mbrtoc8() in C++ modes if
1230-
// __cpp_char8_t is defined or if C2X extensions are enabled. Unfortunately,
1231-
// determining the latter depends on internal GNU libc details. If the
1232-
// __cpp_char8_t feature test macro is not defined, then a char8_t typedef
1233-
// will be declared as well.
1234-
# if defined(_LIBCPP_GLIBC_PREREQ) && defined(__GLIBC_USE)
1235-
# if _LIBCPP_GLIBC_PREREQ(2, 36) && (defined(__cpp_char8_t) || __GLIBC_USE(ISOC2X))
1230+
// __cpp_char8_t is defined or if C2X extensions are enabled. Determining
1231+
// the latter depends on internal GNU libc details that are not appropriate
1232+
// to depend on here, so any declarations present when __cpp_char8_t is not
1233+
// defined are ignored.
1234+
# if defined(_LIBCPP_GLIBC_PREREQ)
1235+
# if _LIBCPP_GLIBC_PREREQ(2, 36) && defined(__cpp_char8_t)
12361236
# undef _LIBCPP_HAS_NO_C8RTOMB_MBRTOC8
12371237
# endif
12381238
# endif

libcxx/test/std/strings/c.strings/no_c8rtomb_mbrtoc8.verify.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,21 @@
1717

1818
#include <uchar.h>
1919

20+
#include "test_macros.h"
21+
22+
// When C++ char8_t support is not enabled, definitions of these functions that
23+
// match the C2X declarations may still be present in the global namespace with
24+
// a char8_t typedef substituted for the C++ char8_t type. If so, these are not
25+
// the declarations we are looking for, so don't test for them.
26+
#if !defined(TEST_HAS_NO_CHAR8_T)
2027
using U = decltype(::c8rtomb);
2128
using V = decltype(::mbrtoc8);
22-
#if defined(_LIBCPP_HAS_NO_C8RTOMB_MBRTOC8)
29+
# if defined(_LIBCPP_HAS_NO_C8RTOMB_MBRTOC8)
2330
// expected-error@-3 {{no member named 'c8rtomb' in the global namespace}}
2431
// expected-error@-3 {{no member named 'mbrtoc8' in the global namespace}}
32+
# else
33+
// expected-no-diagnostics
34+
# endif
2535
#else
2636
// expected-no-diagnostics
2737
#endif

0 commit comments

Comments
 (0)