[4/6] libstdc++: Adjust fast_float's over/underflow behavior for conformnace
Commit Message
This makes fast_float handle the situation where std::from_chars is
specified to return result_out_of_range, i.e. when the parsed value
is outside the representable range of the floating-point type.
This adjusts fast_float's behavior in case of over/underflow: instead of
returning errc{} and setting value to +-0 or +-infinity, return
result_out_of_range and don't modify value, as per [charconv.from.chars]/1.
libstdc++-v3/ChangeLog:
* src/c++17/fast_float/LOCAL_PATCHES: Update.
* src/c++17/fast_float/fast_float.h (from_chars_advanced): In
case of over/underflow, return errc::result_out_of_range and don't
modify 'value'.
---
libstdc++-v3/src/c++17/fast_float/LOCAL_PATCHES | 1 +
libstdc++-v3/src/c++17/fast_float/fast_float.h | 9 +++++++++
2 files changed, 10 insertions(+)
Comments
On Sun, 16 Jan 2022 at 18:12, Patrick Palka via Libstdc++ <
libstdc++@gcc.gnu.org> wrote:
> This makes fast_float handle the situation where std::from_chars is
> specified to return result_out_of_range, i.e. when the parsed value
> is outside the representable range of the floating-point type.
>
> This adjusts fast_float's behavior in case of over/underflow: instead of
> returning errc{} and setting value to +-0 or +-infinity, return
> result_out_of_range and don't modify value, as per [charconv.from.chars]/1.
>
> libstdc++-v3/ChangeLog:
>
> * src/c++17/fast_float/LOCAL_PATCHES: Update.
> * src/c++17/fast_float/fast_float.h (from_chars_advanced): In
> case of over/underflow, return errc::result_out_of_range and don't
> modify 'value'.
>
>
Typo in the commit summary line "conformnace".
OK for trunk.
Please report this as an issue to the upstream project, if you didn't
already (and if they haven't documented this as an intentional deviation
from the standard).
On Mon, Jan 17, 2022 at 5:49 AM Jonathan Wakely <jwakely@redhat.com> wrote:
>
>
>
> On Sun, 16 Jan 2022 at 18:12, Patrick Palka via Libstdc++ <libstdc++@gcc.gnu.org> wrote:
>>
>> This makes fast_float handle the situation where std::from_chars is
>> specified to return result_out_of_range, i.e. when the parsed value
>> is outside the representable range of the floating-point type.
>>
>> This adjusts fast_float's behavior in case of over/underflow: instead of
>> returning errc{} and setting value to +-0 or +-infinity, return
>> result_out_of_range and don't modify value, as per [charconv.from.chars]/1.
>>
>> libstdc++-v3/ChangeLog:
>>
>> * src/c++17/fast_float/LOCAL_PATCHES: Update.
>> * src/c++17/fast_float/fast_float.h (from_chars_advanced): In
>> case of over/underflow, return errc::result_out_of_range and don't
>> modify 'value'.
>>
>
> Typo in the commit summary line "conformnace".
>
> OK for trunk.
>
> Please report this as an issue to the upstream project, if you didn't already (and if they haven't documented this as an intentional deviation from the standard).
This behavior difference isn't documented AFAICT, so I reported the
issue upstream at https://github.com/fastfloat/fast_float/issues/120
@@ -1 +1,2 @@
r12-????
+r12-????
@@ -2884,6 +2884,15 @@ from_chars_result from_chars_advanced(const char *first, const char *last,
// If we called compute_float<binary_format<T>>(pns.exponent, pns.mantissa) and we have an invalid power (am.power2 < 0),
// then we need to go the long way around again. This is very uncommon.
if(am.power2 < 0) { am = digit_comp<T>(pns, am); }
+
+ if((pns.mantissa != 0 && am.mantissa == 0 && am.power2 == 0) || am.power2 == binary_format<T>::infinite_power()) {
+ // In case of over/underflow, return result_out_of_range and don't modify value,
+ // as per [charconv.from.chars]/1. Note that LWG 3081 wants to modify value in
+ // this case too.
+ answer.ec = std::errc::result_out_of_range;
+ return answer;
+ }
+
to_float(pns.negative, am, value);
return answer;
}