diff options
-rw-r--r-- | ChangeLog | 21 | ||||
-rw-r--r-- | sysdeps/arm/fix-fp-int-convert-overflow.h | 2 | ||||
-rw-r--r-- | sysdeps/generic/fix-fp-int-convert-overflow.h | 2 | ||||
-rw-r--r-- | sysdeps/ieee754/ldbl-128/s_llrintl.c | 7 | ||||
-rw-r--r-- | sysdeps/ieee754/ldbl-128/s_llroundl.c | 11 | ||||
-rw-r--r-- | sysdeps/ieee754/ldbl-128/s_lrintl.c | 7 | ||||
-rw-r--r-- | sysdeps/ieee754/ldbl-128/s_lroundl.c | 11 | ||||
-rw-r--r-- | sysdeps/mips/mips32/fpu/fix-fp-int-convert-overflow.h | 2 | ||||
-rw-r--r-- | sysdeps/s390/fix-fp-int-convert-overflow.h | 33 |
9 files changed, 92 insertions, 4 deletions
@@ -1,3 +1,24 @@ +2016-01-15 Stefan Liebler <stli@linux.vnet.ibm.com> + + [BZ #19486] + * sysdeps/s390/fix-fp-int-convert-overflow.h: New File. + * sysdeps/generic/fix-fp-int-convert-overflow.h + (FIX_LDBL_LONG_CONVERT_OVERFLOW, + FIX_LDBL_LLONG_CONVERT_OVERFLOW): New define. + * sysdeps/arm/fix-fp-int-convert-overflow.h: Likewise. + * sysdeps/mips/mips32/fpu/fix-fp-int-convert-overflow.h: + Likewise. + * sysdeps/ieee754/ldbl-128/s_lrintl.c (__lrintl): + Avoid conversions to long int where inexact exceptions + could be raised. + * sysdeps/ieee754/ldbl-128/s_lroundl.c (__lroundl): + Likewise. + * sysdeps/ieee754/ldbl-128/s_llrintl.c (__llrintl): + Avoid conversions to long long int where inexact exceptions + could be raised. + * sysdeps/ieee754/ldbl-128/s_llroundl.c (__llroundl): + Likewise. + 2016-01-17 Mike Frysinger <vapier@gentoo.org> * configure.ac: Rewrite error comment and use AC_MSG_ERROR. diff --git a/sysdeps/arm/fix-fp-int-convert-overflow.h b/sysdeps/arm/fix-fp-int-convert-overflow.h index fcc2199..c5ec50a 100644 --- a/sysdeps/arm/fix-fp-int-convert-overflow.h +++ b/sysdeps/arm/fix-fp-int-convert-overflow.h @@ -25,8 +25,10 @@ see <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59412>). */ #define FIX_FLT_LLONG_CONVERT_OVERFLOW 1 #define FIX_DBL_LLONG_CONVERT_OVERFLOW 1 +#define FIX_LDBL_LLONG_CONVERT_OVERFLOW 0 #define FIX_FLT_LONG_CONVERT_OVERFLOW 0 #define FIX_DBL_LONG_CONVERT_OVERFLOW 0 +#define FIX_LDBL_LONG_CONVERT_OVERFLOW 0 #endif /* fix-fp-int-convert-overflow.h */ diff --git a/sysdeps/generic/fix-fp-int-convert-overflow.h b/sysdeps/generic/fix-fp-int-convert-overflow.h index 73884a6..fb68114 100644 --- a/sysdeps/generic/fix-fp-int-convert-overflow.h +++ b/sysdeps/generic/fix-fp-int-convert-overflow.h @@ -27,5 +27,7 @@ #define FIX_FLT_LLONG_CONVERT_OVERFLOW 0 #define FIX_DBL_LONG_CONVERT_OVERFLOW 0 #define FIX_DBL_LLONG_CONVERT_OVERFLOW 0 +#define FIX_LDBL_LONG_CONVERT_OVERFLOW 0 +#define FIX_LDBL_LLONG_CONVERT_OVERFLOW 0 #endif /* fix-fp-int-convert-overflow.h */ diff --git a/sysdeps/ieee754/ldbl-128/s_llrintl.c b/sysdeps/ieee754/ldbl-128/s_llrintl.c index 445cde5..84fc576 100644 --- a/sysdeps/ieee754/ldbl-128/s_llrintl.c +++ b/sysdeps/ieee754/ldbl-128/s_llrintl.c @@ -24,6 +24,7 @@ #include <math.h> #include <math_private.h> +#include <fix-fp-int-convert-overflow.h> static const long double two112[2] = { @@ -91,6 +92,12 @@ __llrintl (long double x) feraiseexcept (t == LLONG_MIN ? FE_INEXACT : FE_INVALID); return LLONG_MIN; } + else if (FIX_LDBL_LLONG_CONVERT_OVERFLOW && x != (long double) LLONG_MIN) + { + feraiseexcept (FE_INVALID); + return sx == 0 ? LLONG_MAX : LLONG_MIN; + } + #endif return (long long int) x; } diff --git a/sysdeps/ieee754/ldbl-128/s_llroundl.c b/sysdeps/ieee754/ldbl-128/s_llroundl.c index e5dd145..bfc81cc 100644 --- a/sysdeps/ieee754/ldbl-128/s_llroundl.c +++ b/sysdeps/ieee754/ldbl-128/s_llroundl.c @@ -23,7 +23,7 @@ #include <math.h> #include <math_private.h> - +#include <fix-fp-int-convert-overflow.h> long long int __llroundl (long double x) @@ -78,7 +78,14 @@ __llroundl (long double x) FE_INVALID must be raised and the return value is unspecified. */ #ifdef FE_INVALID - if (x <= (long double) LLONG_MIN - 0.5L) + if (FIX_LDBL_LLONG_CONVERT_OVERFLOW + && !(sign == -1 && x > (long double) LLONG_MIN - 0.5L)) + { + feraiseexcept (FE_INVALID); + return sign == 1 ? LLONG_MAX : LLONG_MIN; + } + else if (!FIX_LDBL_LLONG_CONVERT_OVERFLOW + && x <= (long double) LLONG_MIN - 0.5L) { /* If truncation produces LLONG_MIN, the cast will not raise the exception, but may raise "inexact". */ diff --git a/sysdeps/ieee754/ldbl-128/s_lrintl.c b/sysdeps/ieee754/ldbl-128/s_lrintl.c index ff4780a..23f828f 100644 --- a/sysdeps/ieee754/ldbl-128/s_lrintl.c +++ b/sysdeps/ieee754/ldbl-128/s_lrintl.c @@ -24,6 +24,7 @@ #include <math.h> #include <math_private.h> +#include <fix-fp-int-convert-overflow.h> static const long double two112[2] = { @@ -120,6 +121,12 @@ __lrintl (long double x) feraiseexcept (t == LONG_MIN ? FE_INEXACT : FE_INVALID); return LONG_MIN; } + else if (FIX_LDBL_LONG_CONVERT_OVERFLOW && x != (long double) LONG_MIN) + { + feraiseexcept (FE_INVALID); + return sx == 0 ? LONG_MAX : LONG_MIN; + } + #endif return (long int) x; } diff --git a/sysdeps/ieee754/ldbl-128/s_lroundl.c b/sysdeps/ieee754/ldbl-128/s_lroundl.c index 34d2264..f032625 100644 --- a/sysdeps/ieee754/ldbl-128/s_lroundl.c +++ b/sysdeps/ieee754/ldbl-128/s_lroundl.c @@ -23,7 +23,7 @@ #include <math.h> #include <math_private.h> - +#include <fix-fp-int-convert-overflow.h> long int __lroundl (long double x) @@ -87,7 +87,14 @@ __lroundl (long double x) FE_INVALID must be raised and the return value is unspecified. */ #ifdef FE_INVALID - if (x <= (long double) LONG_MIN - 0.5L) + if (FIX_LDBL_LONG_CONVERT_OVERFLOW + && !(sign == -1 && x > (long double) LONG_MIN - 0.5L)) + { + feraiseexcept (FE_INVALID); + return sign == 1 ? LONG_MAX : LONG_MIN; + } + else if (!FIX_LDBL_LONG_CONVERT_OVERFLOW + && x <= (long double) LONG_MIN - 0.5L) { /* If truncation produces LONG_MIN, the cast will not raise the exception, but may raise "inexact". */ diff --git a/sysdeps/mips/mips32/fpu/fix-fp-int-convert-overflow.h b/sysdeps/mips/mips32/fpu/fix-fp-int-convert-overflow.h index fb2ec69..b9f4aea 100644 --- a/sysdeps/mips/mips32/fpu/fix-fp-int-convert-overflow.h +++ b/sysdeps/mips/mips32/fpu/fix-fp-int-convert-overflow.h @@ -25,6 +25,7 @@ see <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59412>). */ #define FIX_FLT_LLONG_CONVERT_OVERFLOW 1 #define FIX_DBL_LLONG_CONVERT_OVERFLOW 1 +#define FIX_LDBL_LLONG_CONVERT_OVERFLOW 0 /* As of GCC 5 and binutils 2.25, for MIPS I GCC generates calls to assembler macros for conversions from floating point to integer @@ -32,5 +33,6 @@ lose exceptions. */ #define FIX_FLT_LONG_CONVERT_OVERFLOW (__mips == 1) #define FIX_DBL_LONG_CONVERT_OVERFLOW (__mips == 1) +#define FIX_LDBL_LONG_CONVERT_OVERFLOW 0 #endif /* fix-fp-int-convert-overflow.h */ diff --git a/sysdeps/s390/fix-fp-int-convert-overflow.h b/sysdeps/s390/fix-fp-int-convert-overflow.h new file mode 100644 index 0000000..61279ed --- /dev/null +++ b/sysdeps/s390/fix-fp-int-convert-overflow.h @@ -0,0 +1,33 @@ +/* Fix for conversion of floating point to integer overflow. S390 version. + Copyright (C) 2016 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#ifndef FIX_FP_INT_CONVERT_OVERFLOW_H +#define FIX_FP_INT_CONVERT_OVERFLOW_H 1 + +/* GCC emits "convert to fixed" instructions for casting floating point values + to integer values. These instructions raise invalid and inexact exceptions + if the floating point value exceeds the integer type ranges. */ +#define FIX_FLT_LLONG_CONVERT_OVERFLOW 1 +#define FIX_DBL_LLONG_CONVERT_OVERFLOW 1 +#define FIX_LDBL_LLONG_CONVERT_OVERFLOW 1 + +#define FIX_FLT_LONG_CONVERT_OVERFLOW 1 +#define FIX_DBL_LONG_CONVERT_OVERFLOW 1 +#define FIX_LDBL_LONG_CONVERT_OVERFLOW 1 + +#endif /* fix-fp-int-convert-overflow.h */ |