This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Provide a C++ version of fpclassify that does not use __MATH_TG (bug 22146)


When optimization for size is on (-Os), fpclassify does not use the
type-generic __builtin_fpclassify builtin, instead it uses __MATH_TG.
However, __MATH_TG uses __builtin_types_compatible_p, which is not
available in C++ mode.

This patch adds a C++ version of fpclassify that does not rely on
__MATH_TG nor on the aforementioned builtins.  It uses C++ overloading
capabilities to distinguish between the floating-point types.

Tested for powerpc64le and x86_64.

	[BZ #22146]
	math/math.h: Provide a C++ version of fpclassify that does not
	rely on __MATH_TG.
---
 math/math.h | 37 ++++++++++++++++++++++++++++++++++++-
 1 file changed, 36 insertions(+), 1 deletion(-)

diff --git a/math/math.h b/math/math.h
index 6c2ad97fb8..63871596ae 100644
--- a/math/math.h
+++ b/math/math.h
@@ -435,8 +435,43 @@ enum
      && !defined __OPTIMIZE_SIZE__
 #  define fpclassify(x) __builtin_fpclassify (FP_NAN, FP_INFINITE,	      \
      FP_NORMAL, FP_SUBNORMAL, FP_ZERO, x)
-# else
+# elif !defined __cplusplus
 #  define fpclassify(x) __MATH_TG ((x), __fpclassify, (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
+fpclassify (float __val)
+{
+  return __fpclassifyf (__val);
+}
+inline int
+fpclassify (double __val)
+{
+  return __fpclassify (__val);
+}
+inline int
+fpclassify (long double __val)
+{
+#  ifdef __NO_LONG_DOUBLE_MATH
+  return __fpclassify (__val);
+#  else
+  return __fpclassifyl (__val);
+#  endif
+}
+#  if __HAVE_DISTINCT_FLOAT128
+inline int
+fpclassify (_Float128 __val)
+{
+  return __fpclassifyf128 (__val);
+}
+#  endif
+} /* extern C++ */
 # endif
 
 /* Return nonzero value if sign of X is negative.  */
-- 
2.13.5


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]