From patchwork Sat Mar 29 16:21:23 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joseph Myers X-Patchwork-Id: 344 Return-Path: X-Original-To: siddhesh@wilcox.dreamhost.com Delivered-To: siddhesh@wilcox.dreamhost.com Received: from homiemail-mx20.g.dreamhost.com (mx2.sub5.homie.mail.dreamhost.com [208.113.200.128]) by wilcox.dreamhost.com (Postfix) with ESMTP id 6E7D43604CA for ; Sat, 29 Mar 2014 09:21:36 -0700 (PDT) Received: by homiemail-mx20.g.dreamhost.com (Postfix, from userid 14307373) id 0221640C93617; Sat, 29 Mar 2014 09:21:35 -0700 (PDT) X-Original-To: glibc@patchwork.siddhesh.in Delivered-To: x14307373@homiemail-mx20.g.dreamhost.com Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by homiemail-mx20.g.dreamhost.com (Postfix) with ESMTPS id D0BB640C7B716 for ; Sat, 29 Mar 2014 09:21:35 -0700 (PDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:date:from:to:subject:message-id:mime-version :content-type; q=dns; s=default; b=bzEZhTkV86Dk7kCwUf5958uNPtrfG e6U1nvLGCLtQurzpVxSUavzpfmbTyrWN5jxLeuu0XgpzG+1fOpwK8vawIkwt4mBr rC3EeUBUWNNtJvExSPm8kGMbSqfO93/wQ1YvXT7IxxnBsjsFxhFTDv8IoYBpNc7Y 2aelx/iGdffLmA= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:date:from:to:subject:message-id:mime-version :content-type; s=default; bh=sBg4hDkCroekJbLg7pY+cyAunjY=; b=u9F jkWjKPOWyyqRm/uja5v0c9yF3k8oWblfT7TEMLrjRiBUjCXREM/T4pz3a87+s/0A w0HEHaknmvaT/dFaNZTpFGWVtj8zHmfjlzn8x0E9A0WQFrl8Shlg3i6HwkEEDRge oHNIbYc9v2fyLZ44hVEvElTBfMzWkJujKqtFphYE= Received: (qmail 22978 invoked by alias); 29 Mar 2014 16:21:33 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 22966 invoked by uid 89); 29 Mar 2014 16:21:32 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.0 required=5.0 tests=AWL, BAYES_00 autolearn=ham version=3.3.2 X-HELO: relay1.mentorg.com Date: Sat, 29 Mar 2014 16:21:23 +0000 From: "Joseph S. Myers" To: Subject: Fix scalb spurious "invalid" exceptions (bug 16770) Message-ID: MIME-Version: 1.0 X-DH-Original-To: glibc@patchwork.siddhesh.in This patch fixes bug 16770, spurious "invalid" exceptions from scalb when testing whether the second argument is an integer, by inserting appropriate range checks to determine whether a cast to int is safe. (Note that invalid_fn is a function that handles both nonintegers and large integers, distinguishing them reliably using functions such as __rint; note also that there are no issues with scalb needing to avoid spurious "inexact" exceptions - it's an old-POSIX XSI function, not a standard C function bound to an IEEE 754 operation - although the return value is still fully determined.) Tested x86_64 and x86. 2014-03-29 Joseph Myers [BZ #16770] * math/e_scalb.c (__ieee754_scalb): Check second argument is not too large before casting to int. * math/e_scalbf.c (__ieee754_scalbf): Likewise. * math/e_scalbl.c (__ieee754_scalbl): Likewise. * math/libm-test.inc (scalb_test_data): Add more tests. diff --git a/math/e_scalb.c b/math/e_scalb.c index bddedfa..146d49e 100644 --- a/math/e_scalb.c +++ b/math/e_scalb.c @@ -50,7 +50,7 @@ __ieee754_scalb (double x, double fn) return x; return x / -fn; } - if (__glibc_unlikely ((double) (int) fn != fn)) + if (__glibc_unlikely (fabs (fn) >= 0x1p31 || (double) (int) fn != fn)) return invalid_fn (x, fn); return __scalbn (x, (int) fn); diff --git a/math/e_scalbf.c b/math/e_scalbf.c index 319752c..3f2e853 100644 --- a/math/e_scalbf.c +++ b/math/e_scalbf.c @@ -50,7 +50,7 @@ __ieee754_scalbf (float x, float fn) return x; return x / -fn; } - if (__glibc_unlikely ((float) (int) fn != fn)) + if (__glibc_unlikely (fabsf (fn) >= 0x1p31f || (float) (int) fn != fn)) return invalid_fn (x, fn); return __scalbnf (x, (int) fn); diff --git a/math/e_scalbl.c b/math/e_scalbl.c index 5815a0d..739db7a 100644 --- a/math/e_scalbl.c +++ b/math/e_scalbl.c @@ -50,7 +50,7 @@ __ieee754_scalbl (long double x, long double fn) return x; return x / -fn; } - if (__glibc_unlikely ((long double) (int) fn != fn)) + if (__glibc_unlikely (fabsl (fn) >= 0x1p31L || (long double) (int) fn != fn)) return invalid_fn (x, fn); return __scalbnl (x, (int) fn); diff --git a/math/libm-test.inc b/math/libm-test.inc index cefcb96..0eff34a 100644 --- a/math/libm-test.inc +++ b/math/libm-test.inc @@ -9134,6 +9134,23 @@ static const struct test_ff_f_data scalb_test_data[] = TEST_ff_f (scalb, plus_infty, qnan_value, qnan_value, NO_INEXACT_EXCEPTION), TEST_ff_f (scalb, qnan_value, qnan_value, qnan_value, NO_INEXACT_EXCEPTION), + TEST_ff_f (scalb, max_value, max_value, plus_oflow, OVERFLOW_EXCEPTION), + TEST_ff_f (scalb, max_value, -max_value, plus_uflow, UNDERFLOW_EXCEPTION), + TEST_ff_f (scalb, 1, max_value, plus_oflow, OVERFLOW_EXCEPTION), + TEST_ff_f (scalb, 1, -max_value, plus_uflow, UNDERFLOW_EXCEPTION), + TEST_ff_f (scalb, min_value, max_value, plus_oflow, OVERFLOW_EXCEPTION), + TEST_ff_f (scalb, min_value, -max_value, plus_uflow, UNDERFLOW_EXCEPTION), + TEST_ff_f (scalb, min_subnorm_value, max_value, plus_oflow, OVERFLOW_EXCEPTION), + TEST_ff_f (scalb, min_subnorm_value, -max_value, plus_uflow, UNDERFLOW_EXCEPTION), + TEST_ff_f (scalb, -max_value, max_value, minus_oflow, OVERFLOW_EXCEPTION), + TEST_ff_f (scalb, -max_value, -max_value, minus_uflow, UNDERFLOW_EXCEPTION), + TEST_ff_f (scalb, -1, max_value, minus_oflow, OVERFLOW_EXCEPTION), + TEST_ff_f (scalb, -1, -max_value, minus_uflow, UNDERFLOW_EXCEPTION), + TEST_ff_f (scalb, -min_value, max_value, minus_oflow, OVERFLOW_EXCEPTION), + TEST_ff_f (scalb, -min_value, -max_value, minus_uflow, UNDERFLOW_EXCEPTION), + TEST_ff_f (scalb, -min_subnorm_value, max_value, minus_oflow, OVERFLOW_EXCEPTION), + TEST_ff_f (scalb, -min_subnorm_value, -max_value, minus_uflow, UNDERFLOW_EXCEPTION), + TEST_ff_f (scalb, 0.8L, 4, 12.8L), TEST_ff_f (scalb, -0.854375L, 5, -27.34L), };