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 signbit that does not use __MATH_TG (bug 22296)


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


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