diff options
author | Tomasz Kamiński <tkaminsk@redhat.com> | 2025-06-27 12:35:53 +0200 |
---|---|---|
committer | Tomasz Kamiński <tkaminsk@redhat.com> | 2025-06-27 16:20:30 +0200 |
commit | 3cc45681c66e7385299cb8bdb0aa5b5123a9524e (patch) | |
tree | d53659fc9fab4e655604b5adf2a721ae7275050b /libstdc++-v3/testsuite/std | |
parent | ad18f7f88aee15b3f15aa74483ca2ebdc89e18cb (diff) | |
download | gcc-3cc45681c66e7385299cb8bdb0aa5b5123a9524e.zip gcc-3cc45681c66e7385299cb8bdb0aa5b5123a9524e.tar.gz gcc-3cc45681c66e7385299cb8bdb0aa5b5123a9524e.tar.bz2 |
libstdc++: Fix warnings introduced by type-erasing for chrono commits [PR110739]
The r16-1709-g4b3cefed1a08344495fedec4982d85168bd8173f caused `-Woverflow`
in empty_spec.cc file. This warning is not cause by any issue in shipping
code, and results in taking to much shortcut when implementing a test-only
custom representation type Rep, where long was always used to store a value.
In particular common type for Rep and long long int, was de-facto long.
This is addressed by adding Under template parameter, that controls the type
of stored value, and handling it properly in common_type specializations.
No changes to shipping code are necessary.
Secondly, extracting _M_locale_fmt calls in r16-1712-gcaac94, resulted in __ctx
format parameter no longer being used. This patch removes such parameter
entirely, and replace _FormatContext template parameter, with _OutIter parameter
for __out. For consistency type of the __out is decoupled from _FormatContext,
for functions that still need context:
* to extract locale (_M_A_a, _M_B_b, _M_c, _M_p, _M_r, _M_subsecs)
* perform formatting for duration/subseconds (_M_Q, _M_T, _M_S, _M_subsecs)
PR libstdc++/110739
libstdc++-v3/ChangeLog:
* include/bits/chrono_io.h (__formatter_chrono::_M_format_to):
Rename _Out to _OutIter for consistency, and update calls
to specifier functions.
(__formatter_chrono::_M_wi, __formatter_chrono::_M_C_y_Y)
(__formatter_chrono::_M_D_x, __formatter_chrono::_M_d_e)
(__formatter_chrono::_M_F, __formatter_chrono::_M_g_G)
(__formatter_chrono::_M_H_I, __formatter_chrono::_M_j)
(__formatter_chrono::_M_m, __formatter_chrono::_M_M)
(__formatter_chrono::_M_q, __formatter_chrono::_M_R_X)
(__formatter_chrono::_M_u_w, __formatter_chrono::_M_U_V_W)
(__formatter_chrono::_M_z, __formatter_chrono::_M_z):
Remove _FormatContext parameter, and introduce _OutIter
for __out type.
(__formatter_chrono::_M_a_A, __formatter_chrono::_M_B_b)
(__formatter_chrono::_M_p, __formatter_chrono::_M_Q)
(__formatter_chrono::_M_r, __formatter_chrono::_M_S)
(__formatter_chrono::_M_subsecs, __formatter_chrono::_M_T):
Introduce separate _OutIter template parameter for __out.
(__formatter_chrono::_M_c, __formatter_chrono::_M_T):
Likewise, and adjust calls to specifiers functions.
* testsuite/std/time/format/empty_spec.cc: Make underlying
type for Rep configurable.
Diffstat (limited to 'libstdc++-v3/testsuite/std')
-rw-r--r-- | libstdc++-v3/testsuite/std/time/format/empty_spec.cc | 43 |
1 files changed, 26 insertions, 17 deletions
diff --git a/libstdc++-v3/testsuite/std/time/format/empty_spec.cc b/libstdc++-v3/testsuite/std/time/format/empty_spec.cc index 923df3d..ef1b19d 100644 --- a/libstdc++-v3/testsuite/std/time/format/empty_spec.cc +++ b/libstdc++-v3/testsuite/std/time/format/empty_spec.cc @@ -77,15 +77,18 @@ test_padding() VERIFY( res == WIDEN("==16 is not a valid month==") ); } -template<typename Ret = void> +template<typename Ret = void, typename Under = long> struct Rep { using Return = std::conditional_t<std::is_void_v<Ret>, Rep, Ret>; - Rep(long v = 0) : val(v) {} + Rep(Under v = 0) : val(v) {} - operator long() const + template<typename ORet, typename OUnder> + Rep(Rep<ORet, OUnder> o) : val(o.val) {} + + operator Under() const { return val; } Return @@ -119,37 +122,43 @@ struct Rep operator<<(std::basic_ostream<CharT>& os, const Rep& t) { return os << t.val << WIDEN("[via <<]"); } - long val; + Under val; +}; + +template<typename Ret, typename Under1, typename Under2> +struct std::common_type<Rep<Ret, Under1>, Rep<Ret, Under2>> +{ + using type = Rep<Ret, std::common_type_t<Under1, Under2>>; }; -template<typename Ret, typename Other> +template<typename Ret, typename Under, typename Other> requires std::is_integral_v<Other> -struct std::common_type<Rep<Ret>, Other> +struct std::common_type<Rep<Ret, Under>, Other> { - using type = Rep<Ret>; + using type = Rep<Ret, std::common_type_t<Under, Other>>; }; -template<typename Ret, typename Other> +template<typename Ret, typename Under, typename Other> requires std::is_integral_v<Other> -struct std::common_type<Other, Rep<Ret>> - : std::common_type<Rep<Ret>, Other> +struct std::common_type<Other, Rep<Ret, Under>> + : std::common_type<Rep<Ret, Under>, Other> { }; -template<typename Ret> -struct std::numeric_limits<Rep<Ret>> - : std::numeric_limits<long> +template<typename Ret, typename Under> +struct std::numeric_limits<Rep<Ret, Under>> + : std::numeric_limits<Under> { }; -template<typename Ret, typename CharT> -struct std::formatter<Rep<Ret>, CharT> - : std::formatter<long, CharT> +template<typename Ret, typename Under, typename CharT> +struct std::formatter<Rep<Ret, Under>, CharT> + : std::formatter<Under, CharT> { template<typename Out> typename std::basic_format_context<Out, CharT>::iterator format(const Rep<Ret>& t, std::basic_format_context<Out, CharT>& ctx) const { constexpr std::basic_string_view<CharT> suffix = WIDEN("[via format]"); - auto out = std::formatter<long, CharT>::format(t.val, ctx); + auto out = std::formatter<Under, CharT>::format(t.val, ctx); return std::ranges::copy(suffix, out).out; } }; |