On 27/02/21 12:42 +0100, Hans-Peter Nilsson via Libstdc++ wrote:
Since 97d6161f6a7fa712 / r11-7370 "libstdc++: More efficient
days from date" I see an additional 81 testsuite-errors for
cris-elf, with this in g++.log for one randomly picked
regressing test:

FAIL: g++.dg/cpp1y/pr57640.C  -std=c++2a (test for excess errors)
Excess errors:
/x/gccobj/cris-elf/libstdc++-v3/include/chrono:2483:25: error: invalid 
'static_cast' from type 'const std::chrono::month' to type 'uint32_t' {aka 
'long unsigned int'}
/x/gccobj/cris-elf/libstdc++-v3/include/chrono:2484:25: error: invalid 
'static_cast' from type 'const std::chrono::day' to type 'uint32_t' {aka 'long 
unsigned int'}
/x/gccobj/cris-elf/libstdc++-v3/include/chrono:2496:69: error: no matching function for call to 
'std::chrono::duration<long long int, std::ratio<86400> 
>::duration(<brace-enclosed initializer list>)'

The commit shows conversions to uint32_t, which for
e.g. x86_64-linux is "unsigned int", and there are explicit
conversions to unsigned int for month and day (see patch
context).

But, "newlib ILP32 targets" have an uint32_t that is
effectively typedef'd "long unsigned int" (see
newlib-stdint.h UINT32_TYPE).

Better provide an unsigned long conversion aside the
unsigned ones.

No, the allowed conversions are specific by the standard. The right
fix is to convert to unsigned explicitly.

I've pushed the attached patch after testing on x86_64-linux. This
should work for newlib ILP32 targets too.

commit 699672d4dccfb5579dbe48977bda86f6836225a0
Author: Jonathan Wakely <jwak...@redhat.com>
Date:   Sat Feb 27 12:50:53 2021

    libstdc++: Fix conversions from date types to integers [PR 99301]
    
    The conversions to integer types are explicit, so need to use the
    correct type. Converting to uint32_t only works if that is the same type
    as unsigned.
    
    libstdc++-v3/ChangeLog:
    
            PR libstdc++/99301
            * include/std/chrono (year_month_day::_M_days_since_epoch()):
            Convert chrono::month and chrono::day to unsigned before
            converting to uint32_t.

diff --git a/libstdc++-v3/include/std/chrono b/libstdc++-v3/include/std/chrono
index fcdaee7328e..11729aae708 100644
--- a/libstdc++-v3/include/std/chrono
+++ b/libstdc++-v3/include/std/chrono
@@ -2496,8 +2496,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       auto constexpr __r2_e3 = static_cast<uint32_t>(536895458);
 
       const auto __y1 = static_cast<uint32_t>(static_cast<int>(_M_y)) - __z2;
-      const auto __m1 = static_cast<uint32_t>(_M_m);
-      const auto __d1 = static_cast<uint32_t>(_M_d);
+      const auto __m1 = static_cast<uint32_t>(static_cast<unsigned>(_M_m));
+      const auto __d1 = static_cast<uint32_t>(static_cast<unsigned>(_M_d));
 
       const auto __j  = static_cast<uint32_t>(__m1 < 3);
       const auto __y0 = __y1 - __j;

Reply via email to