File math-c++-compat.patch of Package glibc.10713

2017-10-17  Romain Naour  <romain.naour@gmail.com>  (tiny change)

	[BZ #22296]
	* math/math.h: Let signbit use the builtin in C++ mode with gcc
	< 6.x

2017-10-03  Gabriel F. T. Gomes  <gabriel@inconstante.eti.br>

	[BZ #22235]
	* 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.

2017-09-22  Gabriel F. T. Gomes  <gabriel@inconstante.eti.br>

	[BZ #22146]
	math/math.h: Let fpclassify use the builtin in C++ mode, even
	when optimazing for size.

2017-08-28  Gabriel F. T. Gomes  <gftg@linux.vnet.ibm.com>

	[BZ #21930]
	* math/math.h [defined __cplusplus && defined __SUPPORT_SNAN__]
	(iszero): New C++ implementation that does not use
	fpclassify/__MATH_TG/__builtin_types_compatible_p, when
	signaling nans are enabled, since __builtin_types_compatible_p
	is a C-only feature.

2017-08-24  Gabriel F. T. Gomes  <gftg@linux.vnet.ibm.com>

	* math/math.h [defined __cplusplus] (issignaling): In the long
	double case, call __issignalingl only if __NO_LONG_DOUBLE_MATH
	is not defined.  Call __issignaling, otherwise.

2017-08-22  Gabriel F. T. Gomes  <gftg@linux.vnet.ibm.com>

	* math/math.h [defined __cplusplus] (issignaling): Provide a C++
	definition for issignaling that does not rely on __MATH_TG,
	since __MATH_TG uses __builtin_types_compatible_p, which is only
	available in C mode.

2017-08-18  Gabriel F. T. Gomes  <gftg@linux.vnet.ibm.com>

	[BZ #21930]
	* math/math.h (isinf): Check if in C or C++ mode before using
	__builtin_types_compatible_p, since this is a C mode feature.

2017-08-18  Gabriel F. T. Gomes  <gftg@linux.vnet.ibm.com>

	* misc/sys/cdefs.h (__HAVE_GENERIC_SELECTION): Define to 0, if
	in C++ mode.

Index: glibc-2.26/math/math.h
===================================================================
--- glibc-2.26.orig/math/math.h
+++ glibc-2.26/math/math.h
@@ -402,7 +402,13 @@ enum
 
 /* Return number of classification appropriate for X.  */
 # if __GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__			      \
-     && !defined __OPTIMIZE_SIZE__
+     && (!defined __OPTIMIZE_SIZE__ || defined __cplusplus)
+     /* The check for __cplusplus allows the use of the builtin, even
+	when optimization for size is on.  This is provided for
+	libstdc++, only to let its configure test work when it is built
+	with -Os.  No further use of this definition of fpclassify is
+	expected in C++ mode, since libstdc++ provides its own version
+	of fpclassify in cmath (which undefines fpclassify).  */
 #  define fpclassify(x) __builtin_fpclassify (FP_NAN, FP_INFINITE,	      \
      FP_NORMAL, FP_SUBNORMAL, FP_ZERO, x)
 # else
@@ -412,6 +418,15 @@ 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.
+     The check for __cplusplus allows the use of the builtin instead of
+     __MATH_TG. This is provided for libstdc++, only to let its configure
+     test work. No further use of this definition of signbit is expected
+     in C++ mode, since libstdc++ provides its own version of signbit
+     in cmath (which undefines signbit). */
+#  define signbit(x) __builtin_signbitl (x)
 # elif __GNUC_PREREQ (4,0)
 #  define signbit(x) __MATH_TG ((x), __builtin_signbit, (x))
 # else
@@ -442,8 +457,12 @@ enum
 
 /* Return nonzero value if X is positive or negative infinity.  */
 # if __HAVE_DISTINCT_FLOAT128 && !__GNUC_PREREQ (7,0) \
-     && !defined __SUPPORT_SNAN__
-   /* __builtin_isinf_sign is broken for float128 only before GCC 7.0.  */
+     && !defined __SUPPORT_SNAN__ && !defined __cplusplus
+   /* Since __builtin_isinf_sign is broken for float128 before GCC 7.0,
+      use the helper function, __isinff128, with older compilers.  This is
+      only provided for C mode, because in C++ mode, GCC has no support
+      for __builtin_types_compatible_p (and when in C++ mode, this macro is
+      not used anyway, because libstdc++ headers undefine it).  */
 #  define isinf(x) \
     (__builtin_types_compatible_p (__typeof (x), _Float128) \
      ? __isinff128 (x) : __builtin_isinf_sign (x))
@@ -470,7 +489,32 @@ enum
 # include <bits/iscanonical.h>
 
 /* Return nonzero value if X is a signaling NaN.  */
-# define issignaling(x) __MATH_TG ((x), __issignaling, (x))
+# ifndef __cplusplus
+#  define issignaling(x) __MATH_TG ((x), __issignaling, (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 issignaling (float __val) { return __issignalingf (__val); }
+inline int issignaling (double __val) { return __issignaling (__val); }
+inline int
+issignaling (long double __val)
+{
+#  ifdef __NO_LONG_DOUBLE_MATH
+  return __issignaling (__val);
+#  else
+  return __issignalingl (__val);
+#  endif
+}
+#  if __HAVE_DISTINCT_FLOAT128
+inline int issignaling (_Float128 __val) { return __issignalingf128 (__val); }
+#  endif
+} /* extern C++ */
+# endif
 
 /* Return nonzero value if X is subnormal.  */
 # define issubnormal(x) (fpclassify (x) == FP_SUBNORMAL)
@@ -484,15 +528,40 @@ enum
 #  endif
 # else	/* __cplusplus */
 extern "C++" {
+#  ifdef __SUPPORT_SNAN__
+inline int
+iszero (float __val)
+{
+  return __fpclassifyf (__val) == FP_ZERO;
+}
+inline int
+iszero (double __val)
+{
+  return __fpclassify (__val) == FP_ZERO;
+}
+inline int
+iszero (long double __val)
+{
+#   ifdef __NO_LONG_DOUBLE_MATH
+  return __fpclassify (__val) == FP_ZERO;
+#   else
+  return __fpclassifyl (__val) == FP_ZERO;
+#   endif
+}
+#   if __HAVE_DISTINCT_FLOAT128
+inline int
+iszero (_Float128 __val)
+{
+  return __fpclassifyf128 (__val) == FP_ZERO;
+}
+#   endif
+#  else
 template <class __T> inline bool
 iszero (__T __val)
 {
-#  ifdef __SUPPORT_SNAN__
-  return fpclassify (__val) == FP_ZERO;
-#  else
   return __val == 0;
-#  endif
 }
+#  endif
 } /* extern C++ */
 # endif	/* __cplusplus */
 #endif /* Use IEC_60559_BFP_EXT.  */
Index: glibc-2.26/misc/sys/cdefs.h
===================================================================
--- glibc-2.26.orig/misc/sys/cdefs.h
+++ glibc-2.26/misc/sys/cdefs.h
@@ -464,17 +464,18 @@
 # define __glibc_macro_warning(msg)
 #endif
 
-/* Support for generic selection (ISO C11) is available in GCC since
-   version 4.9.  Previous versions do not provide generic selection,
-   even though they might set __STDC_VERSION__ to 201112L, when in
-   -std=c11 mode.  Thus, we must check for !defined __GNUC__ when
-   testing __STDC_VERSION__ for generic selection support.
+/* Generic selection (ISO C11) is a C-only feature, available in GCC
+   since version 4.9.  Previous versions do not provide generic
+   selection, even though they might set __STDC_VERSION__ to 201112L,
+   when in -std=c11 mode.  Thus, we must check for !defined __GNUC__
+   when testing __STDC_VERSION__ for generic selection support.
    On the other hand, Clang also defines __GNUC__, so a clang-specific
    check is required to enable the use of generic selection.  */
-#if __GNUC_PREREQ (4, 9) \
-    || __glibc_clang_has_extension (c_generic_selections) \
-    || (!defined __GNUC__ && defined __STDC_VERSION__ \
-	&& __STDC_VERSION__ >= 201112L)
+#if !defined __cplusplus \
+    && (__GNUC_PREREQ (4, 9) \
+	|| __glibc_clang_has_extension (c_generic_selections) \
+	|| (!defined __GNUC__ && defined __STDC_VERSION__ \
+	    && __STDC_VERSION__ >= 201112L))
 # define __HAVE_GENERIC_SELECTION 1
 #else
 # define __HAVE_GENERIC_SELECTION 0
Index: glibc-2.26/sysdeps/ieee754/ldbl-128ibm/bits/iscanonical.h
===================================================================
--- glibc-2.26.orig/sysdeps/ieee754/ldbl-128ibm/bits/iscanonical.h
+++ glibc-2.26/sysdeps/ieee754/ldbl-128ibm/bits/iscanonical.h
@@ -37,5 +37,22 @@ extern int __iscanonicall (long double _
    conversion, before being discarded; in IBM long double, there are
    encodings that are not consistently handled as corresponding to any
    particular value of the type, and we return 0 for those.  */
-# define iscanonical(x) __MATH_TG ((x), __iscanonical, (x))
-#endif
+# ifndef __cplusplus
+#  define iscanonical(x) __MATH_TG ((x), __iscanonical, (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 iscanonical (float __val) { return __iscanonicalf (__val); }
+inline int iscanonical (double __val) { return __iscanonical (__val); }
+inline int iscanonical (long double __val) { return __iscanonicall (__val); }
+#  if __HAVE_DISTINCT_FLOAT128
+inline int iscanonical (_Float128 __val) { return __iscanonicalf128 (__val); }
+#  endif
+}
+# endif /* __cplusplus */
+#endif /* __NO_LONG_DOUBLE_MATH */
Index: glibc-2.26/sysdeps/ieee754/ldbl-96/bits/iscanonical.h
===================================================================
--- glibc-2.26.orig/sysdeps/ieee754/ldbl-96/bits/iscanonical.h
+++ glibc-2.26/sysdeps/ieee754/ldbl-96/bits/iscanonical.h
@@ -34,4 +34,21 @@ extern int __iscanonicall (long double _
    conversion, before being discarded; in extended precision, there
    are encodings that are not consistently handled as corresponding to
    any particular value of the type, and we return 0 for those.  */
-#define iscanonical(x) __MATH_TG ((x), __iscanonical, (x))
+#ifndef __cplusplus
+# define iscanonical(x) __MATH_TG ((x), __iscanonical, (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 iscanonical (float __val) { return __iscanonicalf (__val); }
+inline int iscanonical (double __val) { return __iscanonical (__val); }
+inline int iscanonical (long double __val) { return __iscanonicall (__val); }
+# if __HAVE_DISTINCT_FLOAT128
+inline int iscanonical (_Float128 __val) { return __iscanonicalf128 (__val); }
+# endif
+}
+#endif /* __cplusplus */
openSUSE Build Service is sponsored by