[PATCH] libstdc++: Fix arithmetic bug in year_month_weekday conversion [PR96713]

Jonathan Wakely jwakely@redhat.com
Wed Oct 28 16:01:26 GMT 2020


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.



More information about the Libstdc++ mailing list