From 1463f2dd5b10bbd90e44089d4ae8ad92df8bdcc4 Mon Sep 17 00:00:00 2001 From: Louis Dionne Date: Fri, 25 Oct 2024 12:29:34 -0400 Subject: [PATCH 1/7] [libc++] Use proper functions instead of macros in bsd_locale_defaults.h We were using macros instead of functions, leading to the inability to properly qualify calls to those symbols inside . This is also a step towards making the locale API modules-correct. --- libcxx/include/__locale_dir/locale_base_api.h | 8 ++ .../locale_base_api/bsd_locale_defaults.h | 106 +++++++++++++++--- .../locale_base_api/bsd_locale_fallbacks.h | 4 +- libcxx/include/locale | 12 +- 4 files changed, 104 insertions(+), 26 deletions(-) diff --git a/libcxx/include/__locale_dir/locale_base_api.h b/libcxx/include/__locale_dir/locale_base_api.h index b6c80255b4d19..64615b96b784f 100644 --- a/libcxx/include/__locale_dir/locale_base_api.h +++ b/libcxx/include/__locale_dir/locale_base_api.h @@ -9,6 +9,8 @@ #ifndef _LIBCPP___LOCALE_DIR_LOCALE_BASE_API_H #define _LIBCPP___LOCALE_DIR_LOCALE_BASE_API_H +#include <__config> + #if defined(_LIBCPP_MSVCRT_LIKE) # include <__locale_dir/locale_base_api/win32.h> #elif defined(_AIX) || defined(__MVS__) @@ -27,6 +29,12 @@ # include <__locale_dir/locale_base_api/freebsd.h> #endif +#ifdef _LIBCPP_LOCALE__L_EXTENSIONS +# include <__locale_dir/locale_base_api/bsd_locale_defaults.h> +#else +# include <__locale_dir/locale_base_api/bsd_locale_fallbacks.h> +#endif + #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header #endif diff --git a/libcxx/include/__locale_dir/locale_base_api/bsd_locale_defaults.h b/libcxx/include/__locale_dir/locale_base_api/bsd_locale_defaults.h index e88eb4fa41d7a..ac3c6dc838b46 100644 --- a/libcxx/include/__locale_dir/locale_base_api/bsd_locale_defaults.h +++ b/libcxx/include/__locale_dir/locale_base_api/bsd_locale_defaults.h @@ -14,23 +14,101 @@ #ifndef _LIBCPP___LOCALE_DIR_LOCALE_BASE_API_BSD_LOCALE_DEFAULTS_H #define _LIBCPP___LOCALE_DIR_LOCALE_BASE_API_BSD_LOCALE_DEFAULTS_H +#include +#include +#include +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +# include +#endif + +// must come after the includes above since the functions it includes depend on +// what headers have been included up to that point. +#if defined(__APPLE__) || defined(__FreeBSD__) +# include +#endif + +#include <__config> +#include <__cstddef/size_t.h> +#include <__std_mbstate_t.h> +#include + #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header #endif -#define __libcpp_mb_cur_max_l(loc) MB_CUR_MAX_L(loc) -#define __libcpp_btowc_l(ch, loc) btowc_l(ch, loc) -#define __libcpp_wctob_l(wch, loc) wctob_l(wch, loc) -#define __libcpp_wcsnrtombs_l(dst, src, nwc, len, ps, loc) wcsnrtombs_l(dst, src, nwc, len, ps, loc) -#define __libcpp_wcrtomb_l(src, wc, ps, loc) wcrtomb_l(src, wc, ps, loc) -#define __libcpp_mbsnrtowcs_l(dst, src, nms, len, ps, loc) mbsnrtowcs_l(dst, src, nms, len, ps, loc) -#define __libcpp_mbrtowc_l(pwc, s, n, ps, l) mbrtowc_l(pwc, s, n, ps, l) -#define __libcpp_mbtowc_l(pwc, pmb, max, l) mbtowc_l(pwc, pmb, max, l) -#define __libcpp_mbrlen_l(s, n, ps, l) mbrlen_l(s, n, ps, l) -#define __libcpp_localeconv_l(l) localeconv_l(l) -#define __libcpp_mbsrtowcs_l(dest, src, len, ps, l) mbsrtowcs_l(dest, src, len, ps, l) -#define __libcpp_snprintf_l(...) snprintf_l(__VA_ARGS__) -#define __libcpp_asprintf_l(...) asprintf_l(__VA_ARGS__) -#define __libcpp_sscanf_l(...) sscanf_l(__VA_ARGS__) +_LIBCPP_BEGIN_NAMESPACE_STD + +inline _LIBCPP_HIDE_FROM_ABI decltype(MB_CUR_MAX) __libcpp_mb_cur_max_l(locale_t __loc) { return MB_CUR_MAX_L(__loc); } + +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +inline _LIBCPP_HIDE_FROM_ABI wint_t __libcpp_btowc_l(int __c, locale_t __loc) { return ::btowc_l(__c, __loc); } + +inline _LIBCPP_HIDE_FROM_ABI int __libcpp_wctob_l(wint_t __c, locale_t __loc) { return ::wctob_l(__c, __loc); } + +inline _LIBCPP_HIDE_FROM_ABI size_t __libcpp_wcsnrtombs_l( + char* __dest, const wchar_t** __src, size_t __nwc, size_t __len, mbstate_t* __ps, locale_t __loc) { + return ::wcsnrtombs_l(__dest, __src, __nwc, __len, __ps, __loc); +} + +inline _LIBCPP_HIDE_FROM_ABI size_t __libcpp_wcrtomb_l(char* __s, wchar_t __wc, mbstate_t* __ps, locale_t __loc) { + return ::wcrtomb_l(__s, __wc, __ps, __loc); +} + +inline _LIBCPP_HIDE_FROM_ABI size_t __libcpp_mbsnrtowcs_l( + wchar_t* __dest, const char** __src, size_t __nms, size_t __len, mbstate_t* __ps, locale_t __loc) { + return ::mbsnrtowcs_l(__dest, __src, __nms, __len, __ps, __loc); +} + +inline _LIBCPP_HIDE_FROM_ABI size_t +__libcpp_mbrtowc_l(wchar_t* __pwc, const char* __s, size_t __n, mbstate_t* __ps, locale_t __loc) { + return ::mbrtowc_l(__pwc, __s, __n, __ps, __loc); +} + +inline _LIBCPP_HIDE_FROM_ABI int __libcpp_mbtowc_l(wchar_t* __pwc, const char* __pmb, size_t __max, locale_t __loc) { + return ::mbtowc_l(__pwc, __pmb, __max, __loc); +} + +inline _LIBCPP_HIDE_FROM_ABI size_t __libcpp_mbrlen_l(const char* __s, size_t __n, mbstate_t* __ps, locale_t __loc) { + return ::mbrlen_l(__s, __n, __ps, __loc); +} +#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS + +inline _LIBCPP_HIDE_FROM_ABI lconv* __libcpp_localeconv_l(locale_t __loc) { return ::localeconv_l(__loc); } + +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +inline _LIBCPP_HIDE_FROM_ABI size_t +__libcpp_mbsrtowcs_l(wchar_t* __dest, const char** __src, size_t __len, mbstate_t* __ps, locale_t __loc) { + return ::mbsrtowcs_l(__dest, __src, __len, __ps, __loc); +} +#endif + +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 4, 5) int __libcpp_snprintf_l( + char* __s, size_t __n, locale_t __loc, const char* __format, ...) { + va_list __va; + va_start(__va, __format); + int __res = ::vsnprintf_l(__s, __n, __loc, __format, __va); + va_end(__va); + return __res; +} + +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 3, 4) int __libcpp_asprintf_l( + char** __s, locale_t __loc, const char* __format, ...) { + va_list __va; + va_start(__va, __format); + int __res = ::vasprintf_l(__s, __loc, __format, __va); + va_end(__va); + return __res; +} + +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_ATTRIBUTE_FORMAT(__scanf__, 3, 4) int __libcpp_sscanf_l( + const char* __s, locale_t __loc, const char* __format, ...) { + va_list __va; + va_start(__va, __format); + int __res = ::vsscanf_l(__s, __loc, __format, __va); + va_end(__va); + return __res; +} + +_LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP___LOCALE_DIR_LOCALE_BASE_API_BSD_LOCALE_DEFAULTS_H diff --git a/libcxx/include/__locale_dir/locale_base_api/bsd_locale_fallbacks.h b/libcxx/include/__locale_dir/locale_base_api/bsd_locale_fallbacks.h index ae2db6ae70beb..53336a35ffaf3 100644 --- a/libcxx/include/__locale_dir/locale_base_api/bsd_locale_fallbacks.h +++ b/libcxx/include/__locale_dir/locale_base_api/bsd_locale_fallbacks.h @@ -13,9 +13,11 @@ #ifndef _LIBCPP___LOCALE_DIR_LOCALE_BASE_API_BSD_LOCALE_FALLBACKS_H #define _LIBCPP___LOCALE_DIR_LOCALE_BASE_API_BSD_LOCALE_FALLBACKS_H +#include + #include <__locale_dir/locale_guard.h> -#include #include +#include #include #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS diff --git a/libcxx/include/locale b/libcxx/include/locale index 782475ea7e0eb..4706515b0a6c8 100644 --- a/libcxx/include/locale +++ b/libcxx/include/locale @@ -215,7 +215,7 @@ template class messages_byname; # include # include -// TODO: Fix __bsd_locale_defaults.h +// TODO: Properly qualify calls now that __bsd_locale_defaults.h defines functions instead of macros // NOLINTBEGIN(libcpp-robust-against-adl) # if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) @@ -230,16 +230,6 @@ template class messages_byname; # define _LIBCPP_HAS_CATOPEN 0 # endif -# ifdef _LIBCPP_LOCALE__L_EXTENSIONS -# include <__locale_dir/locale_base_api/bsd_locale_defaults.h> -# else -# include <__locale_dir/locale_base_api/bsd_locale_fallbacks.h> -# endif - -# if defined(__APPLE__) || defined(__FreeBSD__) -# include -# endif - # if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header # endif From c51b48b37a7e18aedb7329549bdacec92acb6002 Mon Sep 17 00:00:00 2001 From: Louis Dionne Date: Wed, 30 Oct 2024 05:33:59 -0400 Subject: [PATCH 2/7] XFAIL modules build on older macOS --- libcxx/test/libcxx/clang_modules_include.gen.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/libcxx/test/libcxx/clang_modules_include.gen.py b/libcxx/test/libcxx/clang_modules_include.gen.py index b897984f89881..e99d913b06987 100644 --- a/libcxx/test/libcxx/clang_modules_include.gen.py +++ b/libcxx/test/libcxx/clang_modules_include.gen.py @@ -29,6 +29,10 @@ //--- {header}.compile.pass.cpp // RUN: %{{cxx}} %s %{{flags}} %{{compile_flags}} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only +// Older macOS SDKs were not properly modularized, which causes issues with localization. +// This feature should instead be based on the SDK version. +// XFAIL: stdlib=system && target={{{{.+}}}}-apple-macosx13{{{{.*}}}} + // GCC doesn't support -fcxx-modules // UNSUPPORTED: gcc @@ -59,6 +63,10 @@ // REQUIRES: clang-modules-build +// Older macOS SDKs were not properly modularized, which causes issues with localization. +// This feature should instead be based on the SDK version. +// XFAIL: stdlib=system && target={{{{.+}}}}-apple-macosx13{{{{.*}}}} + // GCC doesn't support -fcxx-modules // UNSUPPORTED: gcc From 0ffaeeda15f6555dcdc5144c566d87622773abae Mon Sep 17 00:00:00 2001 From: Louis Dionne Date: Wed, 30 Oct 2024 05:41:12 -0400 Subject: [PATCH 3/7] Use variadics instead of non-existent function on Windows --- .../locale_base_api/bsd_locale_defaults.h | 45 ++++++++++--------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/libcxx/include/__locale_dir/locale_base_api/bsd_locale_defaults.h b/libcxx/include/__locale_dir/locale_base_api/bsd_locale_defaults.h index ac3c6dc838b46..faf974df37e8f 100644 --- a/libcxx/include/__locale_dir/locale_base_api/bsd_locale_defaults.h +++ b/libcxx/include/__locale_dir/locale_base_api/bsd_locale_defaults.h @@ -30,7 +30,7 @@ #include <__config> #include <__cstddef/size_t.h> #include <__std_mbstate_t.h> -#include +#include <__utility/forward.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -82,31 +82,32 @@ __libcpp_mbsrtowcs_l(wchar_t* __dest, const char** __src, size_t __len, mbstate_ } #endif -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 4, 5) int __libcpp_snprintf_l( - char* __s, size_t __n, locale_t __loc, const char* __format, ...) { - va_list __va; - va_start(__va, __format); - int __res = ::vsnprintf_l(__s, __n, __loc, __format, __va); - va_end(__va); - return __res; +template +_LIBCPP_HIDE_FROM_ABI int +__libcpp_snprintf_l(char* __s, size_t __n, locale_t __loc, const char* __format, _Args&&... __args) { + _LIBCPP_DIAGNOSTIC_PUSH + _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wformat-nonliteral") + _LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wformat-nonliteral") + return ::snprintf_l(__s, __n, __loc, __format, std::forward<_Args>(__args)...); + _LIBCPP_DIAGNOSTIC_POP } -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 3, 4) int __libcpp_asprintf_l( - char** __s, locale_t __loc, const char* __format, ...) { - va_list __va; - va_start(__va, __format); - int __res = ::vasprintf_l(__s, __loc, __format, __va); - va_end(__va); - return __res; +template +_LIBCPP_HIDE_FROM_ABI int __libcpp_asprintf_l(char** __s, locale_t __loc, const char* __format, _Args&&... __args) { + _LIBCPP_DIAGNOSTIC_PUSH + _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wformat-nonliteral") + _LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wformat-nonliteral") + return ::asprintf_l(__s, __loc, __format, std::forward<_Args>(__args)...); + _LIBCPP_DIAGNOSTIC_POP } -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_ATTRIBUTE_FORMAT(__scanf__, 3, 4) int __libcpp_sscanf_l( - const char* __s, locale_t __loc, const char* __format, ...) { - va_list __va; - va_start(__va, __format); - int __res = ::vsscanf_l(__s, __loc, __format, __va); - va_end(__va); - return __res; +template +_LIBCPP_HIDE_FROM_ABI int __libcpp_sscanf_l(const char* __s, locale_t __loc, const char* __format, _Args&&... __args) { + _LIBCPP_DIAGNOSTIC_PUSH + _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wformat-nonliteral") + _LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wformat-nonliteral") + return ::sscanf_l(__s, __loc, __format, std::forward<_Args>(__args)...); + _LIBCPP_DIAGNOSTIC_POP } _LIBCPP_END_NAMESPACE_STD From 5373c0a82138183a9202c7064eaaa32dfc6d63c2 Mon Sep 17 00:00:00 2001 From: Louis Dionne Date: Wed, 30 Oct 2024 07:12:11 -0400 Subject: [PATCH 4/7] XFAIL -> UNSUPPORTED --- libcxx/test/libcxx/clang_modules_include.gen.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libcxx/test/libcxx/clang_modules_include.gen.py b/libcxx/test/libcxx/clang_modules_include.gen.py index e99d913b06987..4a14217738e78 100644 --- a/libcxx/test/libcxx/clang_modules_include.gen.py +++ b/libcxx/test/libcxx/clang_modules_include.gen.py @@ -31,7 +31,7 @@ // Older macOS SDKs were not properly modularized, which causes issues with localization. // This feature should instead be based on the SDK version. -// XFAIL: stdlib=system && target={{{{.+}}}}-apple-macosx13{{{{.*}}}} +// UNSUPPORTED: stdlib=system && target={{{{.+}}}}-apple-macosx13{{{{.*}}}} // GCC doesn't support -fcxx-modules // UNSUPPORTED: gcc @@ -65,7 +65,7 @@ // Older macOS SDKs were not properly modularized, which causes issues with localization. // This feature should instead be based on the SDK version. -// XFAIL: stdlib=system && target={{{{.+}}}}-apple-macosx13{{{{.*}}}} +// UNSUPPORTED: stdlib=system && target={{{{.+}}}}-apple-macosx13{{{{.*}}}} // GCC doesn't support -fcxx-modules // UNSUPPORTED: gcc From cf90006e0676383f1795c685fa1f1c844561c2a9 Mon Sep 17 00:00:00 2001 From: Louis Dionne Date: Wed, 30 Oct 2024 14:27:32 -0400 Subject: [PATCH 5/7] Pass by ref in localeconv to avoid copying, since Windows doesn't seem to like that --- libcxx/include/__locale_dir/locale_base_api.h | 2 +- .../include/__locale_dir/locale_base_api/bsd_locale_defaults.h | 2 +- .../include/__locale_dir/locale_base_api/bsd_locale_fallbacks.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libcxx/include/__locale_dir/locale_base_api.h b/libcxx/include/__locale_dir/locale_base_api.h index 64615b96b784f..719e9475f3a0e 100644 --- a/libcxx/include/__locale_dir/locale_base_api.h +++ b/libcxx/include/__locale_dir/locale_base_api.h @@ -54,7 +54,7 @@ size_t __libcpp_mbsnrtowcs_l(wchar_t* dest, const char** src, size_t max_out, si size_t __libcpp_mbrtowc_l(wchar_t* dest, cosnt char* src, size_t count, mbstate_t*, locale_t); int __libcpp_mbtowc_l(wchar_t* dest, const char* src, size_t count, locale_t); size_t __libcpp_mbrlen_l(const char* str, size_t count, mbstate_t*, locale_t); -lconv* __libcpp_localeconv_l(locale_t); +lconv* __libcpp_localeconv_l(locale_t&); size_t __libcpp_mbsrtowcs_l(wchar_t* dest, const char** src, size_t len, mbstate_t*, locale_t); int __libcpp_snprintf_l(char* dest, size_t buff_size, locale_t, const char* format, ...); int __libcpp_asprintf_l(char** dest, locale_t, const char* format, ...); diff --git a/libcxx/include/__locale_dir/locale_base_api/bsd_locale_defaults.h b/libcxx/include/__locale_dir/locale_base_api/bsd_locale_defaults.h index faf974df37e8f..2ff625b696bde 100644 --- a/libcxx/include/__locale_dir/locale_base_api/bsd_locale_defaults.h +++ b/libcxx/include/__locale_dir/locale_base_api/bsd_locale_defaults.h @@ -73,7 +73,7 @@ inline _LIBCPP_HIDE_FROM_ABI size_t __libcpp_mbrlen_l(const char* __s, size_t __ } #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS -inline _LIBCPP_HIDE_FROM_ABI lconv* __libcpp_localeconv_l(locale_t __loc) { return ::localeconv_l(__loc); } +inline _LIBCPP_HIDE_FROM_ABI lconv* __libcpp_localeconv_l(locale_t& __loc) { return ::localeconv_l(__loc); } #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS inline _LIBCPP_HIDE_FROM_ABI size_t diff --git a/libcxx/include/__locale_dir/locale_base_api/bsd_locale_fallbacks.h b/libcxx/include/__locale_dir/locale_base_api/bsd_locale_fallbacks.h index 53336a35ffaf3..a8f45a931007c 100644 --- a/libcxx/include/__locale_dir/locale_base_api/bsd_locale_fallbacks.h +++ b/libcxx/include/__locale_dir/locale_base_api/bsd_locale_fallbacks.h @@ -80,7 +80,7 @@ inline _LIBCPP_HIDE_FROM_ABI size_t __libcpp_mbrlen_l(const char* __s, size_t __ } #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS -inline _LIBCPP_HIDE_FROM_ABI lconv* __libcpp_localeconv_l(locale_t __l) { +inline _LIBCPP_HIDE_FROM_ABI lconv* __libcpp_localeconv_l(locale_t& __l) { __locale_guard __current(__l); return localeconv(); } From 57492affcc6550f52bcf3e600480567899dbcf30 Mon Sep 17 00:00:00 2001 From: Louis Dionne Date: Thu, 31 Oct 2024 13:27:36 -0400 Subject: [PATCH 6/7] Add TODO comment about locale_t by reference in localeconv --- libcxx/include/__locale_dir/locale_base_api.h | 1 + 1 file changed, 1 insertion(+) diff --git a/libcxx/include/__locale_dir/locale_base_api.h b/libcxx/include/__locale_dir/locale_base_api.h index 719e9475f3a0e..bef10db1e1e59 100644 --- a/libcxx/include/__locale_dir/locale_base_api.h +++ b/libcxx/include/__locale_dir/locale_base_api.h @@ -54,6 +54,7 @@ size_t __libcpp_mbsnrtowcs_l(wchar_t* dest, const char** src, size_t max_out, si size_t __libcpp_mbrtowc_l(wchar_t* dest, cosnt char* src, size_t count, mbstate_t*, locale_t); int __libcpp_mbtowc_l(wchar_t* dest, const char* src, size_t count, locale_t); size_t __libcpp_mbrlen_l(const char* str, size_t count, mbstate_t*, locale_t); +// TODO: __libcpp_localeconv_l shouldn't take a reference, but the Windows implementation doesn't allow copying locale_t lconv* __libcpp_localeconv_l(locale_t&); size_t __libcpp_mbsrtowcs_l(wchar_t* dest, const char** src, size_t len, mbstate_t*, locale_t); int __libcpp_snprintf_l(char* dest, size_t buff_size, locale_t, const char* format, ...); From 94f713383c8c0cf9bdd21d5814889693c5cae9c1 Mon Sep 17 00:00:00 2001 From: Louis Dionne Date: Thu, 31 Oct 2024 13:31:41 -0400 Subject: [PATCH 7/7] Use attribute format --- .../locale_base_api/bsd_locale_defaults.h | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/libcxx/include/__locale_dir/locale_base_api/bsd_locale_defaults.h b/libcxx/include/__locale_dir/locale_base_api/bsd_locale_defaults.h index 2ff625b696bde..52f31fb37236c 100644 --- a/libcxx/include/__locale_dir/locale_base_api/bsd_locale_defaults.h +++ b/libcxx/include/__locale_dir/locale_base_api/bsd_locale_defaults.h @@ -82,33 +82,33 @@ __libcpp_mbsrtowcs_l(wchar_t* __dest, const char** __src, size_t __len, mbstate_ } #endif +_LIBCPP_DIAGNOSTIC_PUSH +_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wgcc-compat") +_LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wformat-nonliteral") // GCC doesn't support [[gnu::format]] on variadic templates +#ifdef _LIBCPP_COMPILER_CLANG_BASED +# define _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT(...) _LIBCPP_ATTRIBUTE_FORMAT(__VA_ARGS__) +#else +# define _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT +#endif + template -_LIBCPP_HIDE_FROM_ABI int -__libcpp_snprintf_l(char* __s, size_t __n, locale_t __loc, const char* __format, _Args&&... __args) { - _LIBCPP_DIAGNOSTIC_PUSH - _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wformat-nonliteral") - _LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wformat-nonliteral") +_LIBCPP_HIDE_FROM_ABI _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT(__printf__, 4, 5) int __libcpp_snprintf_l( + char* __s, size_t __n, locale_t __loc, const char* __format, _Args&&... __args) { return ::snprintf_l(__s, __n, __loc, __format, std::forward<_Args>(__args)...); - _LIBCPP_DIAGNOSTIC_POP } template -_LIBCPP_HIDE_FROM_ABI int __libcpp_asprintf_l(char** __s, locale_t __loc, const char* __format, _Args&&... __args) { - _LIBCPP_DIAGNOSTIC_PUSH - _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wformat-nonliteral") - _LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wformat-nonliteral") +_LIBCPP_HIDE_FROM_ABI _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT(__printf__, 3, 4) int __libcpp_asprintf_l( + char** __s, locale_t __loc, const char* __format, _Args&&... __args) { return ::asprintf_l(__s, __loc, __format, std::forward<_Args>(__args)...); - _LIBCPP_DIAGNOSTIC_POP } template -_LIBCPP_HIDE_FROM_ABI int __libcpp_sscanf_l(const char* __s, locale_t __loc, const char* __format, _Args&&... __args) { - _LIBCPP_DIAGNOSTIC_PUSH - _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wformat-nonliteral") - _LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wformat-nonliteral") +_LIBCPP_HIDE_FROM_ABI _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT(__scanf__, 3, 4) int __libcpp_sscanf_l( + const char* __s, locale_t __loc, const char* __format, _Args&&... __args) { return ::sscanf_l(__s, __loc, __format, std::forward<_Args>(__args)...); - _LIBCPP_DIAGNOSTIC_POP } +_LIBCPP_DIAGNOSTIC_POP _LIBCPP_END_NAMESPACE_STD