about summary refs log tree commit diff
path: root/math/test-math-iscanonical.cc
diff options
context:
space:
mode:
authorGabriel F. T. Gomes <gabriel@inconstante.eti.br>2017-10-02 14:46:35 -0300
committerGabriel F. T. Gomes <gabriel@inconstante.eti.br>2017-10-03 16:01:37 -0300
commitaa0235dfdebffe9b338deba51f3ba563ee9b433d (patch)
tree7ed57f11a759ad2c670a34b99207cb720030ef6a /math/test-math-iscanonical.cc
parenta1132b5e56fe8aaa148ebd249034181863857d60 (diff)
downloadglibc-aa0235dfdebffe9b338deba51f3ba563ee9b433d.tar.gz
glibc-aa0235dfdebffe9b338deba51f3ba563ee9b433d.tar.xz
glibc-aa0235dfdebffe9b338deba51f3ba563ee9b433d.zip
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.
Diffstat (limited to 'math/test-math-iscanonical.cc')
-rw-r--r--math/test-math-iscanonical.cc48
1 files changed, 48 insertions, 0 deletions
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>