[gcc r13-8877] libstdc++: Fix std::format for chrono::duration with unsigned rep [PR115668]

Jonathan Wakely redi@gcc.gnu.org
Fri Jun 28 19:39:30 GMT 2024


https://gcc.gnu.org/g:4b64a1051a927a65a9acefbbb5714a8118c320bc

commit r13-8877-g4b64a1051a927a65a9acefbbb5714a8118c320bc
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Wed Jun 26 20:22:54 2024 +0100

    libstdc++: Fix std::format for chrono::duration with unsigned rep [PR115668]
    
    Using std::chrono::abs is only valid if numeric_limits<rep>::is_signed
    is true, so using it unconditionally made it ill-formed to format a
    duration with an unsigned rep.
    
    The duration formatter might as well negate the duration itself instead
    of using chrono::abs, because it already needs to check for a negative
    value.
    
    libstdc++-v3/ChangeLog:
    
            PR libstdc++/115668
            * include/bits/chrono_io.h (formatter<duration<R,P, C>::format):
            Do not use chrono::abs.
            * testsuite/20_util/duration/io.cc: Check formatting a duration
            with unsigned rep.
    
    (cherry picked from commit dafa750c8a6f0a088677871bfaad054881737ab1)

Diff:
---
 libstdc++-v3/include/bits/chrono_io.h         | 5 ++++-
 libstdc++-v3/testsuite/20_util/duration/io.cc | 6 ++++++
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/libstdc++-v3/include/bits/chrono_io.h b/libstdc++-v3/include/bits/chrono_io.h
index 1838ad1a8c6..d63f7c40d83 100644
--- a/libstdc++-v3/include/bits/chrono_io.h
+++ b/libstdc++-v3/include/bits/chrono_io.h
@@ -1608,7 +1608,10 @@ namespace __format
 	format(const chrono::duration<_Rep, _Period>& __d,
 	       basic_format_context<_Out, _CharT>& __fc) const
 	{
-	  return _M_f._M_format(chrono::abs(__d), __fc, __d < __d.zero());
+	  if constexpr (numeric_limits<_Rep>::is_signed)
+	    if (__d < __d.zero())
+	      return _M_f._M_format(-__d, __fc, true);
+	  return _M_f._M_format(__d, __fc, false);
 	}
 
     private:
diff --git a/libstdc++-v3/testsuite/20_util/duration/io.cc b/libstdc++-v3/testsuite/20_util/duration/io.cc
index 2043f0c4e9d..b7028a4e6c6 100644
--- a/libstdc++-v3/testsuite/20_util/duration/io.cc
+++ b/libstdc++-v3/testsuite/20_util/duration/io.cc
@@ -101,6 +101,12 @@ test_format()
   std::chrono::duration<float, std::milli> d{0.5};
   s = std::format("{}", d);
   VERIFY( s == "0.5ms" );
+
+  std::chrono::duration<unsigned, std::milli> u{500}; // PR libstdc++/115668
+  s = std::format("{}", u);
+  VERIFY( s == "500ms" );
+  s = std::format("{:%Q %q}", u);
+  VERIFY( s == "500 ms" );
 }
 
 int main()


More information about the Gcc-cvs mailing list