This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[PATCH] Provide a C++ version of fpclassify that does not use __MATH_TG (bug 22146)
- From: "Gabriel F. T. Gomes" <gabriel at inconstante dot eti dot br>
- To: <libc-alpha at sourceware dot org>
- Date: Wed, 20 Sep 2017 12:09:31 -0300
- Subject: [PATCH] Provide a C++ version of fpclassify that does not use __MATH_TG (bug 22146)
- Authentication-results: sourceware.org; auth=none
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