On Wed, 28 Oct 2020, Jonathan Wakely wrote:

> On 28/10/20 11:21 -0400, Patrick Palka via Libstdc++ wrote:
> > On Wed, 28 Oct 2020, Patrick Palka wrote:
> > 
> > > The conversion function year_month_weekday::operator sys_days computes
> > > the number of days to offset from the first weekday of the month with:
> > > 
> > >  days{(index()-1)*7}
> > >       ^~~~~~~~~~~~~  type 'unsigned'
> > > 
> > > We'd like the above to yield -7d when index() is 0u, but our 'days'
> > > alias is based on long instead of int, so the conversion from unsigned
> > > to long instead yields a large positive quantity.
> > > 
> > > This patch fixes this by casting the result of index() to int so that
> > > the initializer is sign-extended in the conversion to long.  The added
> > > testcase also verifies that we do the right thing when index() == 5.
> > > 
> > > Tested on x86_64-pc-linux-gnu, does this look OK for trunk?
> > > 
> > > libstdc++-v3/ChangeLog:
> > > 
> > >   PR libstdc++/96713
> > >   * include/std/chrono (year_month_weekday::operator sys_days):
> > >   Cast the result of index() to int so that the initializer for
> > >   days{} is sign-extended when it's converted to the underlying
> > >   type.
> > >   * testsuite/std/time/year_month_weekday/3.cc: New test.
> > > ---
> > >  libstdc++-v3/include/std/chrono               |  3 +-
> > >  .../std/time/year_month_weekday/3.cc          | 66 +++++++++++++++++++
> > >  2 files changed, 68 insertions(+), 1 deletion(-)
> > >  create mode 100644
> > > libstdc++-v3/testsuite/std/time/year_month_weekday/3.cc
> > > 
> > > diff --git a/libstdc++-v3/include/std/chrono
> > > b/libstdc++-v3/include/std/chrono
> > > index 7539d7184ea..7c35b78fe59 100644
> > > --- a/libstdc++-v3/include/std/chrono
> > > +++ b/libstdc++-v3/include/std/chrono
> > > @@ -2719,7 +2719,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> > >        operator sys_days() const noexcept
> > >        {
> > >   auto __d = sys_days{year() / month() / 1};
> > > - return __d + (weekday() - chrono::weekday(__d) + days{(index()-1)*7});
> > > + return __d + (weekday() - chrono::weekday(__d)
> > > +               + days{((int)index()-1)*7});
> > 
> > On second thought, for consistency with the rest of the header, I guess
> > we should use a functional cast instead of a C-style cast here:
> 
> Or static_cast<int>(index()) :-)
> 
> Any of those options is OK.

Thanks for the review.  I committed the patch just now, albeit with
reference to the unrelated PR96713 instead of PR97613 :( I'll adjust the
ChangeLog entry when it's generated tomorrow.

Reply via email to