This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[PATCH] Provide a C++ version of signbit that does not use __MATH_TG (bug 22296)
- From: Romain Naour <romain dot naour at gmail dot com>
- To: libc-alpha at sourceware dot org
- Cc: Romain Naour <romain dot naour at gmail dot com>, "Gabriel F . T . Gomes" <gftg at linux dot vnet dot ibm dot com>
- Date: Sun, 15 Oct 2017 21:36:52 +0200
- Subject: [PATCH] Provide a C++ version of signbit that does not use __MATH_TG (bug 22296)
- Authentication-results: sourceware.org; auth=none
The macro __MATH_TG contains the logic to select between long double and
_Float128, when these types are ABI-distinct. This logic relies on
__builtin_types_compatible_p, which is not available in C++ mode.
On the other hand, C++ function 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.
This is the same fix as for issignaling [1] but the issue appear
only with gcc < 6.x. Since GCC 6.0, __builtin_signbit is type-generic,
so signbit() is defined without __MATH_TG.
Tested for x86_64.
* math/math.h [defined __cplusplus] (signbit): Provide a C++
definition for signbit that does not rely on __MATH_TG,
since __MATH_TG uses __builtin_types_compatible_p, which is only
available in C mode.
[1] a16e8bc08edca84d507715c66d6cddbbc7ed3b62
Cc: Gabriel F. T. Gomes <gftg@linux.vnet.ibm.com>
---
---
ChangeLog | 8 ++++++++
math/math.h | 15 +++++++++++++++
2 files changed, 23 insertions(+)
diff --git a/ChangeLog b/ChangeLog
index 17fbe55..2fe5719 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2017-10-15 Romain Naour <romain.naour@gmail.com> (tiny change)
+
+ [BZ #22296]
+ * math/math.h [defined __cplusplus] (signbit): Provide a C++
+ definition for signbit that does not rely on __MATH_TG,
+ since __MATH_TG uses __builtin_types_compatible_p, which is only
+ available in C mode.
+
2017-10-15 H.J. Lu <hongjiu.lu@intel.com>
[BZ #22052]
diff --git a/math/math.h b/math/math.h
index faa24817..2c94cdf 100644
--- a/math/math.h
+++ b/math/math.h
@@ -448,6 +448,21 @@ enum
/* Return nonzero value if sign of X is negative. */
# if __GNUC_PREREQ (6,0)
# define signbit(x) __builtin_signbit (x)
+# elif defined __cplusplus
+ /* 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 signbit (float __val) { return __signbitf (__val); }
+inline int signbit (double __val) { return __signbit (__val); }
+inline int signbit (long double __val) { return __signbitl (__val); }
+# if __HAVE_DISTINCT_FLOAT128
+inline int signbit (_Float128 __val) { return __signbitf128 (__val); }
+# endif
+} /* extern C++ */
# elif __GNUC_PREREQ (4,0)
# define signbit(x) __MATH_TG ((x), __builtin_signbit, (x))
# else
--
2.9.5