void-packages/srcpkgs/glibc/patches/glibc-upstream-45.patch
2017-10-10 15:39:48 +00:00

250 lines
10 KiB
Diff
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

From 3b10c5d2abb0392d5ecfd865e2eb911ac109e36f Mon Sep 17 00:00:00 2001
From: "Gabriel F. T. Gomes" <gabriel@inconstante.eti.br>
Date: Mon, 2 Oct 2017 14:46:35 -0300
Subject: [PATCH 45] Add C++ versions of iscanonical for ldbl-96 and
ldbl-128ibm (bug 22235)
All representations of floating-point numbers in types with IEC 60559
binary exchange format are canonical. On the other hand, types with IEC
60559 extended formats, such as those implemented under ldbl-96 and
ldbl-128ibm, contain representations that are not canonical.
TS 18661-1 introduced the type-generic macro iscanonical, which returns
whether a floating-point value is canonical or not. In Glibc, this
type-generic macro is implemented using the macro __MATH_TG, which, when
support for float128 is enabled, relies on __builtin_types_compatible_p
to select between floating-point types. However, this use of
iscanonical breaks C++ applications, because the builtin is only
available in C mode.
This patch provides a C++ implementation of iscanonical that relies on
function overloading, rather than builtins, to select between
floating-point types.
Unlike the C++ implementations for iszero and issignaling, this
implementation ignores __NO_LONG_DOUBLE_MATH. The double type always
matches IEC 60559 double format, which is always canonical. Thus, when
double and long double are the same (__NO_LONG_DOUBLE_MATH), iscanonical
always returns 1 and is not implemented with __MATH_TG.
Tested for powerpc64, powerpc64le and x86_64.
[BZ #22235]
* math/math.h: Trivial fix for unbalanced parentheses in comment.
* math/Makefile [CXX] (tests): Add test-math-iscanonical.cc.
(CFLAGS-test-math-iscanonical.cc): New variable.
* math/test-math-iscanonical.cc: New file.
* sysdeps/ieee754/ldbl-96/bits/iscanonical.h (iscanonical):
Provide a C++ implementation based on function overloading,
rather than using __MATH_TG, which uses C-only builtins.
* sysdeps/ieee754/ldbl-128ibm/bits/iscanonical.h (iscanonical):
Likewise.
* sysdeps/powerpc/powerpc64le/Makefile
(CFLAGS-test-math-iscanonical.cc): New variable.
(cherry picked from commit aa0235dfdebffe9b338deba51f3ba563ee9b433d)
---
ChangeLog | 15 ++++++++
NEWS | 1 +
math/Makefile | 4 ++-
math/math.h | 2 +-
math/test-math-iscanonical.cc | 48 ++++++++++++++++++++++++++
sysdeps/ieee754/ldbl-128ibm/bits/iscanonical.h | 21 +++++++++--
sysdeps/ieee754/ldbl-96/bits/iscanonical.h | 19 +++++++++-
sysdeps/powerpc/powerpc64le/Makefile | 1 +
8 files changed, 106 insertions(+), 5 deletions(-)
create mode 100644 math/test-math-iscanonical.cc
diff --git a/ChangeLog b/ChangeLog
index cc763ac065..fea4fd0cd6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2017-10-03 Gabriel F. T. Gomes <gabriel@inconstante.eti.br>
+
+ [BZ #22235]
+ * math/math.h: Trivial fix for unbalanced parentheses in comment.
+ * math/Makefile [CXX] (tests): Add test-math-iscanonical.cc.
+ (CFLAGS-test-math-iscanonical.cc): New variable.
+ * math/test-math-iscanonical.cc: New file.
+ * sysdeps/ieee754/ldbl-96/bits/iscanonical.h (iscanonical):
+ Provide a C++ implementation based on function overloading,
+ rather than using __MATH_TG, which uses C-only builtins.
+ * sysdeps/ieee754/ldbl-128ibm/bits/iscanonical.h (iscanonical):
+ Likewise.
+ * sysdeps/powerpc/powerpc64le/Makefile
+ (CFLAGS-test-math-iscanonical.cc): New variable.
+
2017-08-22 Joseph Myers <joseph@codesourcery.com>
[BZ #21987]
diff --git a/NEWS b/NEWS
index 8e468c0369..5b05edeb4f 100644
--- a/NEWS
+++ b/NEWS
@@ -35,6 +35,7 @@ The following bugs are resolved with this release:
[22096] resolv: __resolv_conf_attach must not free passed conf object
[22146] Let fpclassify use the builtin when optimizing for size in C++ mode
[22225] math: nearbyint arithmetic moved before feholdexcept
+ [22235] Add C++ versions of iscanonical for ldbl-96 and ldbl-128ibm
Version 2.26
diff --git a/math/Makefile b/math/Makefile
index 0130fcf38b..2c17c68eda 100644
--- a/math/Makefile
+++ b/math/Makefile
@@ -203,7 +203,8 @@ tests-static = test-fpucw-static test-fpucw-ieee-static \
test-signgam-ullong-static test-signgam-ullong-init-static
ifneq (,$(CXX))
-tests += test-math-isinff test-math-iszero test-math-issignaling
+tests += test-math-isinff test-math-iszero test-math-issignaling \
+ test-math-iscanonical
endif
ifneq (no,$(PERL))
@@ -351,6 +352,7 @@ CFLAGS-test-signgam-ullong-init-static.c = -std=c99
CFLAGS-test-math-isinff.cc = -std=gnu++11
CFLAGS-test-math-iszero.cc = -std=gnu++11
CFLAGS-test-math-issignaling.cc = -std=gnu++11
+CFLAGS-test-math-iscanonical.cc = -std=gnu++11
CFLAGS-test-iszero-excess-precision.c = -fexcess-precision=standard
CFLAGS-test-iseqsig-excess-precision.c = -fexcess-precision=standard
diff --git a/math/math.h b/math/math.h
index f9348ec3ea..2b216c6da1 100644
--- a/math/math.h
+++ b/math/math.h
@@ -488,7 +488,7 @@ enum
other hand, overloading provides the means to distinguish between
the floating-point types. The overloading resolution will match
the correct parameter (regardless of type qualifiers (i.e.: const
- and volatile). */
+ and volatile)). */
extern "C++" {
inline int issignaling (float __val) { return __issignalingf (__val); }
inline int issignaling (double __val) { return __issignaling (__val); }
diff --git a/math/test-math-iscanonical.cc b/math/test-math-iscanonical.cc
new file mode 100644
index 0000000000..aba68acb4f
--- /dev/null
+++ b/math/test-math-iscanonical.cc
@@ -0,0 +1,48 @@
+/* Test for the C++ implementation of iscanonical.
+ Copyright (C) 2017 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/>. */
+
+#define _GNU_SOURCE 1
+#include <math.h>
+#include <stdio.h>
+
+static bool errors;
+
+template <class T>
+static void
+check_type ()
+{
+ T val = 0;
+
+ /* Check if iscanonical is available in C++ mode (bug 22235). */
+ if (iscanonical (val) == 0)
+ errors++;
+}
+
+static int
+do_test (void)
+{
+ check_type<float> ();
+ check_type<double> ();
+ check_type<long double> ();
+#if __HAVE_DISTINCT_FLOAT128
+ check_type<_Float128> ();
+#endif
+ return errors;
+}
+
+#include <support/test-driver.c>
diff --git a/sysdeps/ieee754/ldbl-128ibm/bits/iscanonical.h b/sysdeps/ieee754/ldbl-128ibm/bits/iscanonical.h
index 7ddb368d26..f756857c03 100644
--- a/sysdeps/ieee754/ldbl-128ibm/bits/iscanonical.h
+++ b/sysdeps/ieee754/ldbl-128ibm/bits/iscanonical.h
@@ -37,5 +37,22 @@ extern int __iscanonicall (long double __x)
conversion, before being discarded; in IBM long double, there are
encodings that are not consistently handled as corresponding to any
particular value of the type, and we return 0 for those. */
-# define iscanonical(x) __MATH_TG ((x), __iscanonical, (x))
-#endif
+# ifndef __cplusplus
+# define iscanonical(x) __MATH_TG ((x), __iscanonical, (x))
+# else
+/* In C++ mode, __MATH_TG cannot be used, because it relies on
+ __builtin_types_compatible_p, which is a C-only builtin. On the
+ other hand, overloading provides the means to distinguish between
+ the floating-point types. The overloading resolution will match
+ the correct parameter (regardless of type qualifiers (i.e.: const
+ and volatile)). */
+extern "C++" {
+inline int iscanonical (float __val) { return __iscanonicalf (__val); }
+inline int iscanonical (double __val) { return __iscanonical (__val); }
+inline int iscanonical (long double __val) { return __iscanonicall (__val); }
+# if __HAVE_DISTINCT_FLOAT128
+inline int iscanonical (_Float128 __val) { return __iscanonicalf128 (__val); }
+# endif
+}
+# endif /* __cplusplus */
+#endif /* __NO_LONG_DOUBLE_MATH */
diff --git a/sysdeps/ieee754/ldbl-96/bits/iscanonical.h b/sysdeps/ieee754/ldbl-96/bits/iscanonical.h
index 4a4f4ad024..cfa36a0c2a 100644
--- a/sysdeps/ieee754/ldbl-96/bits/iscanonical.h
+++ b/sysdeps/ieee754/ldbl-96/bits/iscanonical.h
@@ -34,4 +34,21 @@ extern int __iscanonicall (long double __x)
conversion, before being discarded; in extended precision, there
are encodings that are not consistently handled as corresponding to
any particular value of the type, and we return 0 for those. */
-#define iscanonical(x) __MATH_TG ((x), __iscanonical, (x))
+#ifndef __cplusplus
+# define iscanonical(x) __MATH_TG ((x), __iscanonical, (x))
+#else
+/* In C++ mode, __MATH_TG cannot be used, because it relies on
+ __builtin_types_compatible_p, which is a C-only builtin. On the
+ other hand, overloading provides the means to distinguish between
+ the floating-point types. The overloading resolution will match
+ the correct parameter (regardless of type qualifiers (i.e.: const
+ and volatile)). */
+extern "C++" {
+inline int iscanonical (float __val) { return __iscanonicalf (__val); }
+inline int iscanonical (double __val) { return __iscanonical (__val); }
+inline int iscanonical (long double __val) { return __iscanonicall (__val); }
+# if __HAVE_DISTINCT_FLOAT128
+inline int iscanonical (_Float128 __val) { return __iscanonicalf128 (__val); }
+# endif
+}
+#endif /* __cplusplus */
diff --git a/sysdeps/powerpc/powerpc64le/Makefile b/sysdeps/powerpc/powerpc64le/Makefile
index dea2290736..cf2dbfb673 100644
--- a/sysdeps/powerpc/powerpc64le/Makefile
+++ b/sysdeps/powerpc/powerpc64le/Makefile
@@ -16,6 +16,7 @@ $(foreach suf,$(all-object-suffixes),%f128_r$(suf)): CFLAGS += -mfloat128
$(foreach suf,$(all-object-suffixes),$(objpfx)test-float128%$(suf)): CFLAGS += -mfloat128
$(foreach suf,$(all-object-suffixes),$(objpfx)test-ifloat128%$(suf)): CFLAGS += -mfloat128
CFLAGS-libm-test-support-float128.c += -mfloat128
+CFLAGS-test-math-iscanonical.cc += -mfloat128
CFLAGS-test-math-issignaling.cc += -mfloat128
CFLAGS-test-math-iszero.cc += -mfloat128
$(objpfx)test-float128% $(objpfx)test-ifloat128% $(objpfx)test-math-iszero: \