math.h: Do use __MATH_TG_BUILTIN_CLASSIFY for C++

Message ID 20251229151201.2453737-1-adhemerval.zanella@linaro.org (mailing list archive)
State Superseded
Headers
Series math.h: Do use __MATH_TG_BUILTIN_CLASSIFY for C++ |

Checks

Context Check Description
redhat-pt-bot/TryBot-apply_patch success Patch applied to master at the time it was sent
redhat-pt-bot/TryBot-32bit success Build for i686

Commit Message

Adhemerval Zanella Dec. 29, 2025, 3:12 p.m. UTC
  The __MATH_TG_BUILTIN_CLASSIFY macro can not be used in C++ mode due
it might use __builtin_types_compatible_p, which is a C-only builtin.

Checked with bmg targetting x86_64-linux-gnu and on x86_64-linux-gnu
and aarch64 with gcc-15 and clang-18.
---
 math/math.h | 43 ++++++++++++++++++++++++++-----------------
 1 file changed, 26 insertions(+), 17 deletions(-)
  

Comments

H.J. Lu Dec. 29, 2025, 10:41 p.m. UTC | #1
On Mon, Dec 29, 2025 at 11:12 PM Adhemerval Zanella
<adhemerval.zanella@linaro.org> wrote:
>
> The __MATH_TG_BUILTIN_CLASSIFY macro can not be used in C++ mode due
> it might use __builtin_types_compatible_p, which is a C-only builtin.
>
> Checked with bmg targetting x86_64-linux-gnu and on x86_64-linux-gnu
> and aarch64 with gcc-15 and clang-18.
> ---
>  math/math.h | 43 ++++++++++++++++++++++++++-----------------
>  1 file changed, 26 insertions(+), 17 deletions(-)
>
> diff --git a/math/math.h b/math/math.h
> index 96b64379f7..49489293fc 100644
> --- a/math/math.h
> +++ b/math/math.h
> @@ -1173,21 +1173,25 @@ enum
>
>  /* Return number of classification appropriate for X.  */
>  # if ((__GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__)                     \
> -      || __glibc_clang_prereq (2,8))                                         \
> -     && (!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)                                                              \
> -  __MATH_TG_BUILTIN_CLASSIFY ((x),                                           \
> -                             __builtin_fpclassify, (FP_NAN, FP_INFINITE,     \
> -                                                    FP_NORMAL, FP_SUBNORMAL, \
> -                                                    FP_ZERO, x),             \
> -                             fpclassify, (x),                                \
> -                             __FP_BUILTIN_FPCLASSIFY_DENORMAL)
> +       || __glibc_clang_prereq (2,8))                                        \
> +     && !defined __cplusplus
> +  /* The __MATH_TG_BUILTIN_CLASSIFY macro can not be used in C++ mode due
> +     it might use __builtin_types_compatible_p, which is C-only builtin.  */
> +#  define fpclassify(x)                                                       \
> +  __MATH_TG_BUILTIN_CLASSIFY ((x),                                            \
> +                              __builtin_fpclassify, (FP_NAN, FP_INFINITE,     \
> +                                                     FP_NORMAL, FP_SUBNORMAL, \
> +                                                     FP_ZERO, x),             \
> +                              fpclassify, (x),                                \
> +                              __FP_BUILTIN_FPCLASSIFY_DENORMAL)
> +# elif defined __cplusplus
> +   /* The check for __cplusplus allows the use of the builtin, even
> +      when optimization for size is on.  This is provided for
> +      libstdc++ and 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
>  #  define fpclassify(x) __MATH_TG ((x), __fpclassify, (x))
>  # endif
> @@ -1247,12 +1251,17 @@ enum
>  #  define isinf(x) \
>      (__builtin_types_compatible_p (__typeof (x), _Float128) \
>       ? __isinff128 (x) : __builtin_isinf_sign (x))
> -# elif (__GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__) \
> -       || __glibc_clang_prereq (3,7)
> +  /* The __MATH_TG_BUILTIN_CLASSIFY macro can not be used in C++ mode due
> +     it might use __builtin_types_compatible_p, which is C-only builtin.  */
> +# elif ((__GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__) \
> +        || __glibc_clang_prereq (3,7)) \
> +     && !defined __cplusplus
>  #  define isinf(x) __MATH_TG_BUILTIN_CLASSIFY ((x),                          \
>                                                __builtin_isinf_sign, (x),     \
>                                                isinf, (x),                    \
>                                                __FP_BUILTIN_ISINF_SIGN_DENORMAL)
> +# elif defined __cplusplus
> +#  define isinf(x) __builtin_isinf_sign (x)
>  # else
>  #  define isinf(x) __MATH_TG ((x), __isinf, (x))
>  # endif
> --
> 2.43.0
>

Please add a C++ test for this change.

--
H.J.
  
H.J. Lu Dec. 30, 2025, 6:34 a.m. UTC | #2
On Tue, Dec 30, 2025 at 6:41 AM H.J. Lu <hjl.tools@gmail.com> wrote:
>
> On Mon, Dec 29, 2025 at 11:12 PM Adhemerval Zanella
> <adhemerval.zanella@linaro.org> wrote:
> >
> > The __MATH_TG_BUILTIN_CLASSIFY macro can not be used in C++ mode due
> > it might use __builtin_types_compatible_p, which is a C-only builtin.
> >
> > Checked with bmg targetting x86_64-linux-gnu and on x86_64-linux-gnu
> > and aarch64 with gcc-15 and clang-18.
> > ---
> >  math/math.h | 43 ++++++++++++++++++++++++++-----------------
> >  1 file changed, 26 insertions(+), 17 deletions(-)
> >
> > diff --git a/math/math.h b/math/math.h
> > index 96b64379f7..49489293fc 100644
> > --- a/math/math.h
> > +++ b/math/math.h
> > @@ -1173,21 +1173,25 @@ enum
> >
> >  /* Return number of classification appropriate for X.  */
> >  # if ((__GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__)                     \
> > -      || __glibc_clang_prereq (2,8))                                         \
> > -     && (!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)                                                              \
> > -  __MATH_TG_BUILTIN_CLASSIFY ((x),                                           \
> > -                             __builtin_fpclassify, (FP_NAN, FP_INFINITE,     \
> > -                                                    FP_NORMAL, FP_SUBNORMAL, \
> > -                                                    FP_ZERO, x),             \
> > -                             fpclassify, (x),                                \
> > -                             __FP_BUILTIN_FPCLASSIFY_DENORMAL)
> > +       || __glibc_clang_prereq (2,8))                                        \
> > +     && !defined __cplusplus
> > +  /* The __MATH_TG_BUILTIN_CLASSIFY macro can not be used in C++ mode due
> > +     it might use __builtin_types_compatible_p, which is C-only builtin.  */
> > +#  define fpclassify(x)                                                       \
> > +  __MATH_TG_BUILTIN_CLASSIFY ((x),                                            \
> > +                              __builtin_fpclassify, (FP_NAN, FP_INFINITE,     \
> > +                                                     FP_NORMAL, FP_SUBNORMAL, \
> > +                                                     FP_ZERO, x),             \
> > +                              fpclassify, (x),                                \
> > +                              __FP_BUILTIN_FPCLASSIFY_DENORMAL)
> > +# elif defined __cplusplus
> > +   /* The check for __cplusplus allows the use of the builtin, even
> > +      when optimization for size is on.  This is provided for
> > +      libstdc++ and 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
> >  #  define fpclassify(x) __MATH_TG ((x), __fpclassify, (x))
> >  # endif
> > @@ -1247,12 +1251,17 @@ enum
> >  #  define isinf(x) \
> >      (__builtin_types_compatible_p (__typeof (x), _Float128) \
> >       ? __isinff128 (x) : __builtin_isinf_sign (x))
> > -# elif (__GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__) \
> > -       || __glibc_clang_prereq (3,7)
> > +  /* The __MATH_TG_BUILTIN_CLASSIFY macro can not be used in C++ mode due
> > +     it might use __builtin_types_compatible_p, which is C-only builtin.  */
> > +# elif ((__GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__) \
> > +        || __glibc_clang_prereq (3,7)) \
> > +     && !defined __cplusplus
> >  #  define isinf(x) __MATH_TG_BUILTIN_CLASSIFY ((x),                          \
> >                                                __builtin_isinf_sign, (x),     \
> >                                                isinf, (x),                    \
> >                                                __FP_BUILTIN_ISINF_SIGN_DENORMAL)
> > +# elif defined __cplusplus
> > +#  define isinf(x) __builtin_isinf_sign (x)
> >  # else
> >  #  define isinf(x) __MATH_TG ((x), __isinf, (x))
> >  # endif
> > --
> > 2.43.0
> >
>
> Please add a C++ test for this change.
>
> --
> H.J.

Something like this.
  
H.J. Lu Dec. 30, 2025, 6:47 a.m. UTC | #3
On Tue, Dec 30, 2025 at 2:34 PM H.J. Lu <hjl.tools@gmail.com> wrote:
>
> On Tue, Dec 30, 2025 at 6:41 AM H.J. Lu <hjl.tools@gmail.com> wrote:
> >
> > On Mon, Dec 29, 2025 at 11:12 PM Adhemerval Zanella
> > <adhemerval.zanella@linaro.org> wrote:
> > >
> > > The __MATH_TG_BUILTIN_CLASSIFY macro can not be used in C++ mode due
> > > it might use __builtin_types_compatible_p, which is a C-only builtin.
> > >
> > > Checked with bmg targetting x86_64-linux-gnu and on x86_64-linux-gnu
> > > and aarch64 with gcc-15 and clang-18.
> > > ---
> > >  math/math.h | 43 ++++++++++++++++++++++++++-----------------
> > >  1 file changed, 26 insertions(+), 17 deletions(-)
> > >
> > > diff --git a/math/math.h b/math/math.h
> > > index 96b64379f7..49489293fc 100644
> > > --- a/math/math.h
> > > +++ b/math/math.h
> > > @@ -1173,21 +1173,25 @@ enum
> > >
> > >  /* Return number of classification appropriate for X.  */
> > >  # if ((__GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__)                     \
> > > -      || __glibc_clang_prereq (2,8))                                         \
> > > -     && (!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)                                                              \
> > > -  __MATH_TG_BUILTIN_CLASSIFY ((x),                                           \
> > > -                             __builtin_fpclassify, (FP_NAN, FP_INFINITE,     \
> > > -                                                    FP_NORMAL, FP_SUBNORMAL, \
> > > -                                                    FP_ZERO, x),             \
> > > -                             fpclassify, (x),                                \
> > > -                             __FP_BUILTIN_FPCLASSIFY_DENORMAL)
> > > +       || __glibc_clang_prereq (2,8))                                        \
> > > +     && !defined __cplusplus
> > > +  /* The __MATH_TG_BUILTIN_CLASSIFY macro can not be used in C++ mode due
> > > +     it might use __builtin_types_compatible_p, which is C-only builtin.  */
> > > +#  define fpclassify(x)                                                       \
> > > +  __MATH_TG_BUILTIN_CLASSIFY ((x),                                            \
> > > +                              __builtin_fpclassify, (FP_NAN, FP_INFINITE,     \
> > > +                                                     FP_NORMAL, FP_SUBNORMAL, \
> > > +                                                     FP_ZERO, x),             \
> > > +                              fpclassify, (x),                                \
> > > +                              __FP_BUILTIN_FPCLASSIFY_DENORMAL)
> > > +# elif defined __cplusplus
> > > +   /* The check for __cplusplus allows the use of the builtin, even
> > > +      when optimization for size is on.  This is provided for
> > > +      libstdc++ and 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
> > >  #  define fpclassify(x) __MATH_TG ((x), __fpclassify, (x))
> > >  # endif
> > > @@ -1247,12 +1251,17 @@ enum
> > >  #  define isinf(x) \
> > >      (__builtin_types_compatible_p (__typeof (x), _Float128) \
> > >       ? __isinff128 (x) : __builtin_isinf_sign (x))
> > > -# elif (__GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__) \
> > > -       || __glibc_clang_prereq (3,7)
> > > +  /* The __MATH_TG_BUILTIN_CLASSIFY macro can not be used in C++ mode due
> > > +     it might use __builtin_types_compatible_p, which is C-only builtin.  */
> > > +# elif ((__GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__) \
> > > +        || __glibc_clang_prereq (3,7)) \
> > > +     && !defined __cplusplus
> > >  #  define isinf(x) __MATH_TG_BUILTIN_CLASSIFY ((x),                          \
> > >                                                __builtin_isinf_sign, (x),     \
> > >                                                isinf, (x),                    \
> > >                                                __FP_BUILTIN_ISINF_SIGN_DENORMAL)
> > > +# elif defined __cplusplus
> > > +#  define isinf(x) __builtin_isinf_sign (x)
> > >  # else
> > >  #  define isinf(x) __MATH_TG ((x), __isinf, (x))
> > >  # endif
> > > --
> > > 2.43.0
> > >
> >
> > Please add a C++ test for this change.
> >
> > --
> > H.J.
>
> Something like this.
>
> --
> H.J.

We should also add generic C++ fpclassify tests.
  
Florian Weimer Dec. 30, 2025, 10:01 a.m. UTC | #4
* Adhemerval Zanella:

> @@ -1247,12 +1251,17 @@ enum
>  #  define isinf(x) \
>      (__builtin_types_compatible_p (__typeof (x), _Float128) \
>       ? __isinff128 (x) : __builtin_isinf_sign (x))
> -# elif (__GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__) \
> -       || __glibc_clang_prereq (3,7)
> +  /* The __MATH_TG_BUILTIN_CLASSIFY macro can not be used in C++ mode due
> +     it might use __builtin_types_compatible_p, which is C-only builtin.  */
> +# elif ((__GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__) \
> +        || __glibc_clang_prereq (3,7)) \
> +     && !defined __cplusplus
>  #  define isinf(x) __MATH_TG_BUILTIN_CLASSIFY ((x),			      \

… not be used in C++ mode [because] it might use …

I agree with H.J.  Without a test case, it's hard to see what this is
about.
  

Patch

diff --git a/math/math.h b/math/math.h
index 96b64379f7..49489293fc 100644
--- a/math/math.h
+++ b/math/math.h
@@ -1173,21 +1173,25 @@  enum
 
 /* Return number of classification appropriate for X.  */
 # if ((__GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__)		      \
-      || __glibc_clang_prereq (2,8))					      \
-     && (!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)							      \
-  __MATH_TG_BUILTIN_CLASSIFY ((x),					      \
-			      __builtin_fpclassify, (FP_NAN, FP_INFINITE,     \
-						     FP_NORMAL, FP_SUBNORMAL, \
-						     FP_ZERO, x),	      \
-			      fpclassify, (x),				      \
-			      __FP_BUILTIN_FPCLASSIFY_DENORMAL)
+       || __glibc_clang_prereq (2,8))					      \
+     && !defined __cplusplus
+  /* The __MATH_TG_BUILTIN_CLASSIFY macro can not be used in C++ mode due
+     it might use __builtin_types_compatible_p, which is C-only builtin.  */
+#  define fpclassify(x)                                                       \
+  __MATH_TG_BUILTIN_CLASSIFY ((x),                                            \
+                              __builtin_fpclassify, (FP_NAN, FP_INFINITE,     \
+                                                     FP_NORMAL, FP_SUBNORMAL, \
+                                                     FP_ZERO, x),             \
+                              fpclassify, (x),                                \
+                              __FP_BUILTIN_FPCLASSIFY_DENORMAL)
+# elif defined __cplusplus
+   /* The check for __cplusplus allows the use of the builtin, even
+      when optimization for size is on.  This is provided for
+      libstdc++ and 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
 #  define fpclassify(x) __MATH_TG ((x), __fpclassify, (x))
 # endif
@@ -1247,12 +1251,17 @@  enum
 #  define isinf(x) \
     (__builtin_types_compatible_p (__typeof (x), _Float128) \
      ? __isinff128 (x) : __builtin_isinf_sign (x))
-# elif (__GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__) \
-       || __glibc_clang_prereq (3,7)
+  /* The __MATH_TG_BUILTIN_CLASSIFY macro can not be used in C++ mode due
+     it might use __builtin_types_compatible_p, which is C-only builtin.  */
+# elif ((__GNUC_PREREQ (4,4) && !defined __SUPPORT_SNAN__) \
+        || __glibc_clang_prereq (3,7)) \
+     && !defined __cplusplus
 #  define isinf(x) __MATH_TG_BUILTIN_CLASSIFY ((x),			      \
 					       __builtin_isinf_sign, (x),     \
 					       isinf, (x),		      \
 					       __FP_BUILTIN_ISINF_SIGN_DENORMAL)
+# elif defined __cplusplus
+#  define isinf(x) __builtin_isinf_sign (x)
 # else
 #  define isinf(x) __MATH_TG ((x), __isinf, (x))
 # endif