From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1888) id 4E40E38582B6; Wed, 2 Nov 2022 12:57:06 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 4E40E38582B6 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1667393827; bh=gwy2MfHvFbnx05xUeRxieeGk6UlPedbA9GmNvyt+uAQ=; h=From:To:Subject:Date:From; b=rFZvMFT3x4uJyc/nDJHHAcVi6ihBDLYKUA+IpSSmLBAkzFUBDkIrBbKiw1kgomWdL 6lb005PjzJM423cp70RdvGXNW3P32J48R+Q2vb46aF2ad61meXNtWN7khxrmUOPVlH mSI5ejSXJvAqH30IazR56G+TEls2K+g228pFYzWM= MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Patrick Palka To: gcc-cvs@gcc.gnu.org, libstdc++-cvs@gcc.gnu.org Subject: [gcc r13-3609] libstdc++: Improve ERANGE behavior for fallback FP std::from_chars X-Act-Checkin: gcc X-Git-Author: Patrick Palka X-Git-Refname: refs/heads/master X-Git-Oldrev: f4874691812bc20e3d8e3302db439c27f30c472c X-Git-Newrev: 6d9dbdf51f9afe86a57fb28bc55065fa4500a72b Message-Id: <20221102125707.4E40E38582B6@sourceware.org> Date: Wed, 2 Nov 2022 12:57:06 +0000 (GMT) List-Id: https://gcc.gnu.org/g:6d9dbdf51f9afe86a57fb28bc55065fa4500a72b commit r13-3609-g6d9dbdf51f9afe86a57fb28bc55065fa4500a72b Author: Patrick Palka Date: Wed Nov 2 08:56:59 2022 -0400 libstdc++: Improve ERANGE behavior for fallback FP std::from_chars The fallback implementation of floating-point std::from_chars (used for formats other than binary32/64) just calls the C library's strtod family of functions. In case of overflow, the behavior of these functions is rigidly specified: If the correct value overflows and default rounding is in effect, plus or minus HUGE_VAL, HUGE_VALF, or HUGE_VALL is returned (according to the return type and sign of the value), and the value of the macro ERANGE is stored in errno. But in case of underflow, implementations are given more leeway: If the result underflows the functions return a value whose magnitude is no greater than the smallest normalized positive number in the return type; whether errno acquires the value ERANGE is implementation-defined. Thus the fallback implementation can (and does) portably detect overflow, but it can't portably detect underflow. However, glibc (and presumably other high-quality C library implementations) will reliably set errno to ERANGE in case of underflow as well, and it'll also return the nearest denormal number to the correct value (zero in case of true underflow), which allows callers to succesfully parse denormal numbers. So since we can't be perfect here, this patch takes the best effort approach of assuming a high quality C library implementation with respect to this underflow behavior, and refines our implementation to try to distiguish between a denormal result and true underflow by inspecting strtod's return value. libstdc++-v3/ChangeLog: * src/c++17/floating_from_chars.cc (from_chars_impl): In the ERANGE case, distinguish between a denormal result and true underflow by checking if the return value is 0. Diff: --- libstdc++-v3/src/c++17/floating_from_chars.cc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/libstdc++-v3/src/c++17/floating_from_chars.cc b/libstdc++-v3/src/c++17/floating_from_chars.cc index a25ac5ce3aa..939c751f861 100644 --- a/libstdc++-v3/src/c++17/floating_from_chars.cc +++ b/libstdc++-v3/src/c++17/floating_from_chars.cc @@ -637,8 +637,13 @@ namespace { if (__builtin_isinf(tmpval)) // overflow ec = errc::result_out_of_range; - else // underflow (LWG 3081 wants to set value = tmpval here) + else if (tmpval == 0) // underflow (LWG 3081 wants to set value = tmpval here) ec = errc::result_out_of_range; + else // denormal value + { + value = tmpval; + ec = errc(); + } } else if (n) {