From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTPS id 378D43858D35 for ; Tue, 1 Nov 2022 21:30:41 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 378D43858D35 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1667338240; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=B1oGOaPsuPJ+XeBkLeSxO0Dp+xhL7nHqfc4x41Rey6k=; b=dJWYwamLPGrKcEWA/GdKpCsA0k92E6sxzon5APS8Mv1iRON3yBmBTYuGalHmNS0zAyYHwd IND5Dhs+ayl/7kJpVr+50ZgDKX/EGOSYa0RXWk3R1dJlCTG2KSV9xBXcnq3JB7lEgONO8B lDb+6wEfjSL9O/jqA8uc0jKAcgXxYO0= Received: from mail-qt1-f200.google.com (mail-qt1-f200.google.com [209.85.160.200]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_128_GCM_SHA256) id us-mta-328-rJcJzx5aO5C_wD9Sa9wXqQ-1; Tue, 01 Nov 2022 17:30:39 -0400 X-MC-Unique: rJcJzx5aO5C_wD9Sa9wXqQ-1 Received: by mail-qt1-f200.google.com with SMTP id fz10-20020a05622a5a8a00b003a4f466998cso10693127qtb.16 for ; Tue, 01 Nov 2022 14:30:39 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=B1oGOaPsuPJ+XeBkLeSxO0Dp+xhL7nHqfc4x41Rey6k=; b=OhP9q87Z47jwcYTHmOoatCuPPpkBc9kt2H+TlE4BD3yxZgv+27lS6zDhUiXQTtwmES zh52gMRciLWD0jrbdMyLQu/onL2xYSfXDVMzee+2gHChlcNbjtRNxemwuEBc4CkuJbqs ckEhJn4GJ//XYpI0u7vRG9xZZ/mf5oYmW2m2w57asEmI5wXa5Ww7t5MdiXyGyA4yhMHJ 92bZy4AKbPu91d4b3gvkkQ8TFIJwZwItPn54XF3AWntFcLMECDVBaSClUOsw6tlMWFA4 QP/gFIiHuVUGJ/4CllyqIsvqclZF7uL16uniUoXd3vxln+Ily9v9ON7xc2rmYnDgheaP Ehcg== X-Gm-Message-State: ACrzQf1T5CwV730/v1iv50wPU1fXV3fTx9tsO5sBzPg87YYJkkiG+liW D4kt2XrZ0wGLAcxcG35kEP+yc8PXjdKLgzeygl1ULqHvOs+2ZVEAiPWpB3lZccWCUMLM1bTvlbE AvPsUu9ksrW9/h+s= X-Received: by 2002:a37:ad0d:0:b0:6fa:39fa:973f with SMTP id f13-20020a37ad0d000000b006fa39fa973fmr6701586qkm.563.1667338239227; Tue, 01 Nov 2022 14:30:39 -0700 (PDT) X-Google-Smtp-Source: AMsMyM6CChaMwAg5+XPJ0JdoGQqfkPsXfhrdRnjg00brmH0KGvnW6bjD3BeD95P+hJqIz6XsvuoFXQ== X-Received: by 2002:a37:ad0d:0:b0:6fa:39fa:973f with SMTP id f13-20020a37ad0d000000b006fa39fa973fmr6701570qkm.563.1667338238979; Tue, 01 Nov 2022 14:30:38 -0700 (PDT) Received: from localhost.localdomain (ool-457670bb.dyn.optonline.net. [69.118.112.187]) by smtp.gmail.com with ESMTPSA id z63-20020a37b042000000b006f9e103260dsm7173419qke.91.2022.11.01.14.30.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 01 Nov 2022 14:30:38 -0700 (PDT) From: Patrick Palka To: gcc-patches@gcc.gnu.org Cc: libstdc++@gcc.gnu.org, jakub@redhat.com, Patrick Palka Subject: [PATCH] libstdc++: Fix ERANGE behavior for fallback FP std::from_chars Date: Tue, 1 Nov 2022 17:30:29 -0400 Message-Id: <20221101213029.940043-1-ppalka@redhat.com> X-Mailer: git-send-email 2.38.1.381.gc03801e19c MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset="US-ASCII"; x-default=true X-Spam-Status: No, score=-14.3 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_NONE,TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: The fallback implementation of floating-point std::from_chars for e.g. float80 just calls the C library's strtod family of functions. In case of overflow of the parsed result, 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 we can (and do) portably detect overflow, but we 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 too, and it will also return the nearest denormal number to the parsed result (including zero in case of true underflow). Since we can't be perfect here, this patch takes the best effort approach of assuming a high quality C library implementation that allows us to distinguish between a denormal parsed result and true underflow by inspecting the return value. Tested on x86_64-pc-linux-gnu, does this look OK for trunk? Dunno if we should backport this too. No test because we can't portably test this IIUC. libstdc++-v3/ChangeLog: * src/c++17/floating_from_chars.cc (from_chars_impl): In the ERANGE case, also check for a 0 return value before returning result_out_of_range, occurred, otherwise assume it's a denormal number. --- 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) { -- 2.38.1.381.gc03801e19c