[PATCH v2] math.h: Do use __MATH_TG_BUILTIN_CLASSIFY for C++
Adhemerval Zanella Netto
adhemerval.zanella@linaro.org
Wed Dec 31 11:09:38 GMT 2025
On 31/12/25 02:26, H.J. Lu wrote:
> On Wed, Dec 31, 2025 at 6:56 AM H.J. Lu <hjl.tools@gmail.com> wrote:
>>
>> On Wed, Dec 31, 2025 at 1:25 AM Adhemerval Zanella
>> <adhemerval.zanella@linaro.org> wrote:
>>>
>>> The __MATH_TG_BUILTIN_CLASSIFY macro can not be used in C++
>>> mode because it might use __builtin_types_compatible_p, which
>>> is a C-only builtin.
>>
>> The subject says "math.h: Do use __MATH_TG_BUILTIN_CLASSIFY for C++".
>>
>>> The C++ version uses the built-in; using a different scheme,
>>> such as function overloading (like iszero), breaks libstdc++,
>>> which expects isinf to be implemented as a macro. The x86
>>> test-builtin-denormal.c test has been adjusted to include the
>>> relevant gcc/llvm bug information.
>>>
>>> Checked with bmg targeting x86_64-linux-gnu and on
>>> x86_64-linux-gnu and aarch64 with gcc-15 and clang-18.
>>> ---
>>> include/array_length.h | 4 +
>>> math/Makefile | 4 +
>>> math/math.h | 38 ++---
>>> math/test-math-fpclassify.cc | 149 +++++++++++++++++++
>>> math/test-math-isinf.cc | 145 ++++++++++++++++++
>>> scripts/sysd-rules.awk | 28 +++-
>>> sysdeps/x86/fpu/Makefile | 5 +
>>> sysdeps/x86/fpu/test-builtin-denormal-cxx.cc | 1 +
>>> sysdeps/x86/fpu/test-builtin-denormal.c | 10 +-
>>> 9 files changed, 363 insertions(+), 21 deletions(-)
>>> create mode 100644 math/test-math-fpclassify.cc
>>> create mode 100644 math/test-math-isinf.cc
>>> create mode 100644 sysdeps/x86/fpu/test-builtin-denormal-cxx.cc
>>>
>>> diff --git a/include/array_length.h b/include/array_length.h
>>> index 2a4f09fd37..2f5ab7b219 100644
>>> --- a/include/array_length.h
>>> +++ b/include/array_length.h
>>> @@ -21,6 +21,9 @@
>>>
>>> /* array_length (VAR) is the number of elements in the array VAR. VAR
>>> must evaluate to an array, not a pointer. */
>>> +#ifdef __cplusplus
>>> +#define array_length(var) (sizeof (var) / sizeof ((var)[0]))
>>> +#else
>>> #define array_length(var) \
>>> (sizeof (var) / sizeof ((var)[0]) \
>>> + 0 * sizeof (struct { \
>>> @@ -28,6 +31,7 @@
>>> (__typeof (var), __typeof (&(var)[0])), \
>>> "argument must be an array"); \
>>> }))
>>> +#endif
>>>
>>> /* array_end (VAR) is a pointer one past the end of the array VAR.
>>> VAR must evaluate to an array, not a pointer. */
>>> diff --git a/math/Makefile b/math/Makefile
>>> index 8fe2540ce0..fa9193e75b 100644
>>> --- a/math/Makefile
>>> +++ b/math/Makefile
>>> @@ -620,8 +620,10 @@ tests-static += \
>>> ifneq (,$(CXX))
>>> tests += \
>>> test-math-cxx11 \
>>> + test-math-fpclassify \
>>> test-math-iscanonical \
>>> test-math-iseqsig \
>>> + test-math-isinf \
>>> test-math-isinff \
>>> test-math-issignaling \
>>> test-math-iszero \
>>> @@ -1151,10 +1153,12 @@ CFLAGS-test-signgam-ullong-init-static.c += -std=c99
>>>
>>> CFLAGS-test-math-cxx11.cc += -std=c++11
>>>
>>> +CFLAGS-test-math-isinf.cc += -std=gnu++11
>>> CFLAGS-test-math-isinff.cc += -std=gnu++11
>>> CFLAGS-test-math-iszero.cc += -std=gnu++11
>>> CFLAGS-test-math-issignaling.cc += -std=gnu++11
>>> CFLAGS-test-math-iscanonical.cc += -std=gnu++11
>>> +CFLAGS-test-math-fpclassify.cc += -std=gnu++11
>>>
>>> CFLAGS-test-iszero-excess-precision.c += -fexcess-precision=standard
>>> CFLAGS-test-iseqsig-excess-precision.c += -fexcess-precision=standard
>>> diff --git a/math/math.h b/math/math.h
>>> index 96b64379f7..05f46b7116 100644
>>> --- a/math/math.h
>>> +++ b/math/math.h
>>> @@ -1173,21 +1173,20 @@ 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 because
>
> Should we provide a C++ __MATH_TG_BUILTIN_CLASSIFY?
>
>>> + 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
>>> +# 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 +1246,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 because
>>> + 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
>>> diff --git a/math/test-math-fpclassify.cc b/math/test-math-fpclassify.cc
>>> new file mode 100644
>>> index 0000000000..f8dbf4fe7d
>>> --- /dev/null
>>> +++ b/math/test-math-fpclassify.cc
>>> @@ -0,0 +1,149 @@
>>> +/* Test for the C++ implementation of fpclassify.
>>> + Copyright (C) 2025 Free Software Foundation, Inc.
>>> + This file is part of the GNU C Library.
>>> +
>>> + The GNU C Library is free software; you can redistribute it and/or
>>> + modify it under the terms of the GNU Lesser General Public
>>> + License as published by the Free Software Foundation; either
>>> + version 2.1 of the License, or (at your option) any later version.
>>> +
>>> + The GNU C Library is distributed in the hope that it will be useful,
>>> + but WITHOUT ANY WARRANTY; without even the implied warranty of
>>> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
>>> + Lesser General Public License for more details.
>>> +
>>> + You should have received a copy of the GNU Lesser General Public
>>> + License along with the GNU C Library; if not, see
>>> + <https://www.gnu.org/licenses/>. */
>>> +
>>> +#define _GNU_SOURCE 1
>>> +#include <math.h>
>>> +#include <stdio.h>
>>> +#include <limits>
>>> +
>>> +#include <support/check.h>
>>> +
>>> +/* Support for _Float128 in std::numeric_limits is limited.
>>> + Include ieee754_float128.h and use the bitfields in the union
>>> + ieee854_float128.ieee_nan to build corner-case inputs. */
>>> +#if __HAVE_DISTINCT_FLOAT128
>>> +# include <ieee754_float128.h>
>>> +#endif
>>> +
>>> +template <class T>
>>> +static void
>>> +check_type ()
>>> +{
>>> + typedef std::numeric_limits<T> limits;
>>> + TEST_COMPARE (fpclassify (T{}), FP_ZERO);
>>> + TEST_COMPARE (fpclassify (T{0}), FP_ZERO);
>>> + TEST_COMPARE (fpclassify (T{-0.0}), FP_ZERO);
>>> + TEST_COMPARE (fpclassify (T{1}), FP_NORMAL);
>>> + TEST_COMPARE (fpclassify (T{-1}), FP_NORMAL);
>>> + TEST_COMPARE (fpclassify (limits::min ()), FP_NORMAL);
>>> + TEST_COMPARE (fpclassify (-limits::min ()), FP_NORMAL);
>>> + TEST_COMPARE (fpclassify (limits::max ()), FP_NORMAL);
>>> + TEST_COMPARE (fpclassify (-limits::max ()), FP_NORMAL);
>>> + if (limits::has_infinity)
>>> + {
>>> + TEST_COMPARE (fpclassify (limits::infinity ()), FP_INFINITE);
>>> + TEST_COMPARE (fpclassify (-limits::infinity ()), FP_INFINITE);
>>> + }
>>> + TEST_COMPARE (fpclassify (limits::epsilon ()), FP_NORMAL);
>>> + TEST_COMPARE (fpclassify (-limits::epsilon ()), FP_NORMAL);
>>> + if (limits::has_quiet_NaN)
>>> + TEST_COMPARE (fpclassify (limits::quiet_NaN ()), FP_NAN);
>>> + if (limits::has_signaling_NaN)
>>> + TEST_COMPARE (fpclassify (limits::signaling_NaN ()), FP_NAN);
>>> + if (limits::has_signaling_NaN)
>>> + TEST_COMPARE (fpclassify (limits::signaling_NaN ()), FP_NAN);
>>> + TEST_COMPARE (fpclassify (limits::denorm_min ()),
>>> + std::numeric_limits<T>::has_denorm == std::denorm_absent
>>> + ? FP_NORMAL : FP_SUBNORMAL);
>>> + TEST_COMPARE (fpclassify (-limits::denorm_min ()),
>>> + std::numeric_limits<T>::has_denorm == std::denorm_absent
>>> + ? FP_NORMAL : FP_SUBNORMAL);
>>> +}
>>> +
>>> +#if __HAVE_DISTINCT_FLOAT128
>>> +static void
>>> +check_float128 ()
>>> +{
>>> + ieee854_float128 q;
>>> +
>>> + q.d = 0.0Q;
>>> + TEST_COMPARE (fpclassify (q.d), FP_ZERO);
>>> + q.d = -0.0Q;
>>> + TEST_COMPARE (fpclassify (q.d), FP_ZERO);
>>> + q.d = 1.0Q;
>>> + TEST_COMPARE (fpclassify (q.d), FP_NORMAL);
>>> + q.d = -1.0Q;
>>> + TEST_COMPARE (fpclassify (q.d), FP_NORMAL);
>>> +
>>> + /* Normal min. */
>>> + q.ieee.negative = 0;
>>> + q.ieee.exponent = 0x0001;
>>> + q.ieee.mantissa0 = 0x0000;
>>> + q.ieee.mantissa1 = 0x00000000;
>>> + q.ieee.mantissa2 = 0x00000000;
>>> + q.ieee.mantissa3 = 0x00000000;
>>> + TEST_COMPARE (fpclassify (q.d), FP_NORMAL);
>>> + q.ieee.negative = 1;
>>> + TEST_COMPARE (fpclassify (q.d), FP_NORMAL);
>>> +
>>> + /* Normal max. */
>>> + q.ieee.negative = 0;
>>> + q.ieee.exponent = 0x7FFE;
>>> + q.ieee.mantissa0 = 0xFFFF;
>>> + q.ieee.mantissa1 = 0xFFFFFFFF;
>>> + q.ieee.mantissa2 = 0xFFFFFFFF;
>>> + q.ieee.mantissa3 = 0xFFFFFFFF;
>>> + TEST_COMPARE (fpclassify (q.d), FP_NORMAL);
>>> + q.ieee.negative = 1;
>>> + TEST_COMPARE (fpclassify (q.d), FP_NORMAL);
>>> +
>>> + /* Infinity. */
>>> + q.ieee.negative = 0;
>>> + q.ieee.exponent = 0x7FFF;
>>> + q.ieee.mantissa0 = 0x0000;
>>> + q.ieee.mantissa1 = 0x00000000;
>>> + q.ieee.mantissa2 = 0x00000000;
>>> + q.ieee.mantissa3 = 0x00000000;
>>> + TEST_COMPARE (fpclassify (q.d), FP_INFINITE);
>>> +
>>> + /* Quiet NaN. */
>>> + q.ieee_nan.quiet_nan = 1;
>>> + q.ieee_nan.mantissa0 = 0x0000;
>>> + TEST_COMPARE (fpclassify (q.d), FP_NAN);
>>> +
>>> + /* Signaling NaN. */
>>> + q.ieee_nan.quiet_nan = 0;
>>> + q.ieee_nan.mantissa0 = 0x4000;
>>> + TEST_COMPARE (fpclassify (q.d), FP_NAN);
>>> +
>>> + /* Denormal min. */
>>> + q.ieee.negative = 0;
>>> + q.ieee.exponent = 0x0000;
>>> + q.ieee.mantissa0 = 0x0000;
>>> + q.ieee.mantissa1 = 0x00000000;
>>> + q.ieee.mantissa2 = 0x00000000;
>>> + q.ieee.mantissa3 = 0x00000001;
>>> + TEST_COMPARE (fpclassify (q.d), FP_SUBNORMAL);
>>> + q.ieee.negative = 1;
>>> + TEST_COMPARE (fpclassify (q.d), FP_SUBNORMAL);
>>> +}
>>> +#endif
>>> +
>>> +static int
>>> +do_test (void)
>>> +{
>>> + check_type<float> ();
>>> + check_type<double> ();
>>> + check_type<long double> ();
>>> +#if __HAVE_DISTINCT_FLOAT128
>>> + check_float128 ();
>>> +#endif
>>> + return 0;
>>> +}
>>> +
>>> +#include <support/test-driver.c>
>>> diff --git a/math/test-math-isinf.cc b/math/test-math-isinf.cc
>>> new file mode 100644
>>> index 0000000000..4cdc146583
>>> --- /dev/null
>>> +++ b/math/test-math-isinf.cc
>>> @@ -0,0 +1,145 @@
>>> +/* Test for the C++ implementation of isinf.
>>> + Copyright (C) 2025 Free Software Foundation, Inc.
>>> + This file is part of the GNU C Library.
>>> +
>>> + The GNU C Library is free software; you can redistribute it and/or
>>> + modify it under the terms of the GNU Lesser General Public
>>> + License as published by the Free Software Foundation; either
>>> + version 2.1 of the License, or (at your option) any later version.
>>> +
>>> + The GNU C Library is distributed in the hope that it will be useful,
>>> + but WITHOUT ANY WARRANTY; without even the implied warranty of
>>> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
>>> + Lesser General Public License for more details.
>>> +
>>> + You should have received a copy of the GNU Lesser General Public
>>> + License along with the GNU C Library; if not, see
>>> + <https://www.gnu.org/licenses/>. */
>>> +
>>> +#define _GNU_SOURCE 1
>>> +#include <math.h>
>>> +#include <stdio.h>
>>> +#include <limits>
>>> +
>>> +#include <support/check.h>
>>> +
>>> +/* Support for _Float128 in std::numeric_limits is limited.
>>> + Include ieee754_float128.h and use the bitfields in the union
>>> + ieee854_float128.ieee_nan to build corner-case inputs. */
>>> +#if __HAVE_DISTINCT_FLOAT128
>>> +# include <ieee754_float128.h>
>>> +#endif
>>> +
>>> +template <class T>
>>> +static void
>>> +check_type ()
>>> +{
>>> + typedef std::numeric_limits<T> limits;
>>> + TEST_COMPARE (isinf (T{}), 0);
>>> + TEST_COMPARE (isinf (T{0}), 0);
>>> + TEST_COMPARE (isinf (T{-0.0}), 0);
>>> + TEST_COMPARE (isinf (T{1}), 0);
>>> + TEST_COMPARE (isinf (T{-1}), 0);
>>> + TEST_COMPARE (isinf (limits::min ()), 0);
>>> + TEST_COMPARE (isinf (-limits::min ()), 0);
>>> + TEST_COMPARE (isinf (limits::max ()), 0);
>>> + TEST_COMPARE (isinf (-limits::max ()), 0);
>>> + if (limits::has_infinity)
>>> + {
>>> + TEST_COMPARE (isinf (limits::infinity ()), 1);
>>> + TEST_COMPARE (isinf (-limits::infinity ()), -1);
>>> + }
>>> + TEST_COMPARE (isinf (limits::epsilon ()), 0);
>>> + TEST_COMPARE (isinf (-limits::epsilon ()), 0);
>>> + if (limits::has_quiet_NaN)
>>> + TEST_COMPARE (isinf (limits::quiet_NaN ()), 0);
>>> + if (limits::has_signaling_NaN)
>>> + TEST_COMPARE (isinf (limits::signaling_NaN ()), 0);
>>> + if (limits::has_signaling_NaN)
>>> + TEST_COMPARE (isinf (limits::signaling_NaN ()), 0);
>>> + TEST_COMPARE (isinf (limits::denorm_min ()), 0);
>>> + TEST_COMPARE (isinf (-limits::denorm_min ()), 0);
>>> +}
>>> +
>>> +#if __HAVE_DISTINCT_FLOAT128
>>> +static void
>>> +check_float128 ()
>>> +{
>>> + ieee854_float128 q;
>>> +
>>> + q.d = 0.0Q;
>>> + TEST_COMPARE (isinf (q.d), 0);
>>> + q.d = -0.0Q;
>>> + TEST_COMPARE (isinf (q.d), 0);
>>> + q.d = 1.0Q;
>>> + TEST_COMPARE (isinf (q.d), 0);
>>> + q.d = -1.0Q;
>>> + TEST_COMPARE (isinf (q.d), 0);
>>> +
>>> + /* Normal min. */
>>> + q.ieee.negative = 0;
>>> + q.ieee.exponent = 0x0001;
>>> + q.ieee.mantissa0 = 0x0000;
>>> + q.ieee.mantissa1 = 0x00000000;
>>> + q.ieee.mantissa2 = 0x00000000;
>>> + q.ieee.mantissa3 = 0x00000000;
>>> + TEST_COMPARE (isinf (q.d), 0);
>>> + q.ieee.negative = 1;
>>> + TEST_COMPARE (isinf (q.d), 0);
>>> +
>>> + /* Normal max. */
>>> + q.ieee.negative = 0;
>>> + q.ieee.exponent = 0x7FFE;
>>> + q.ieee.mantissa0 = 0xFFFF;
>>> + q.ieee.mantissa1 = 0xFFFFFFFF;
>>> + q.ieee.mantissa2 = 0xFFFFFFFF;
>>> + q.ieee.mantissa3 = 0xFFFFFFFF;
>>> + TEST_COMPARE (isinf (q.d), 0);
>>> + q.ieee.negative = 1;
>>> + TEST_COMPARE (isinf (q.d), 0);
>>> +
>>> + /* Infinity. */
>>> + q.ieee.negative = 0;
>>> + q.ieee.exponent = 0x7FFF;
>>> + q.ieee.mantissa0 = 0x0000;
>>> + q.ieee.mantissa1 = 0x00000000;
>>> + q.ieee.mantissa2 = 0x00000000;
>>> + q.ieee.mantissa3 = 0x00000000;
>>> + TEST_COMPARE (isinf (q.d), 1);
>>> +
>>> + /* Quiet NaN. */
>>> + q.ieee_nan.quiet_nan = 1;
>>> + q.ieee_nan.mantissa0 = 0x0000;
>>> + TEST_COMPARE (isinf (q.d), 0);
>>> +
>>> + /* Signaling NaN. */
>>> + q.ieee_nan.quiet_nan = 0;
>>> + q.ieee_nan.mantissa0 = 0x4000;
>>> + TEST_COMPARE (isinf (q.d), 0);
>>> +
>>> + /* Denormal min. */
>>> + q.ieee.negative = 0;
>>> + q.ieee.exponent = 0x0000;
>>> + q.ieee.mantissa0 = 0x0000;
>>> + q.ieee.mantissa1 = 0x00000000;
>>> + q.ieee.mantissa2 = 0x00000000;
>>> + q.ieee.mantissa3 = 0x00000001;
>>> + TEST_COMPARE (isinf (q.d), 0);
>>> + q.ieee.negative = 1;
>>> + TEST_COMPARE (isinf (q.d), 0);
>>> +}
>>> +#endif
>>> +
>>> +static int
>>> +do_test (void)
>>> +{
>>> + check_type<float> ();
>>> + check_type<double> ();
>>> + check_type<long double> ();
>>> +#if __HAVE_DISTINCT_FLOAT128
>>> + check_float128 ();
>>> +#endif
>>> + return 0;
>>> +}
>>> +
>>> +#include <support/test-driver.c>
>>> diff --git a/scripts/sysd-rules.awk b/scripts/sysd-rules.awk
>>> index c82e8fd607..cdc892b397 100644
>>> --- a/scripts/sysd-rules.awk
>>> +++ b/scripts/sysd-rules.awk
>>> @@ -35,6 +35,7 @@ BEGIN {
>>>
>>> for (sysdir_idx = 1; sysdir_idx <= nsysdirs; ++sysdir_idx) {
>>> dir = sysdirs[sysdir_idx];
>>> + sysdep_dir = dir
>>> if (dir !~ /^\//) dir = "$(..)" dir;
>>> asm_rules = 1;
>>> for (i = 1; i <= ninhibit_asm; ++i) {
>>> @@ -43,6 +44,20 @@ BEGIN {
>>> break;
>>> }
>>> }
>>> + # Check if there are any *.S files.
>>> + if (asm_rules == 1 && system("ls " sysdep_dir "/*.S > /dev/null 2>&1") != 0) {
>>> + asm_rules = 0;
>>> + }
>>> + # Check if there are any *.c files.
>>> + c_rules = 1
>>> + if (system("ls " sysdep_dir "/*.c > /dev/null 2>&1") != 0) {
>>> + c_rules = 0;
>>> + }
>>> + # Check if there are any *.cc files.
>>> + cc_rules = 1
>>> + if (system("ls " sysdep_dir "/*.cc > /dev/null 2>&1") != 0) {
>>> + cc_rules = 0;
>>> + }
>>> for (suffix_idx = 1; suffix_idx <= nsuffixes; ++suffix_idx) {
>>> o = suffixes[suffix_idx];
>>> for (pattern_idx = 1; pattern_idx <= npatterns; ++pattern_idx) {
>>> @@ -66,9 +81,16 @@ BEGIN {
>>> print target, dep, "$(before-compile)";
>>> print "\t$(compile-command.S)" command_suffix;
>>> }
>>> - dep = dir "/" dep_pattern ".c";
>>> - print target, dep, "$(before-compile)";
>>> - print "\t$(compile-command.c)" command_suffix;
>>> + if (c_rules) {
>>> + dep = dir "/" dep_pattern ".c";
>>> + print target, dep, "$(before-compile)";
>>> + print "\t$(compile-command.c)" command_suffix;
>>> + }
>>> + if (cc_rules) {
>>> + dep = dir "/" dep_pattern ".cc";
>>> + print target, dep, "$(before-compile)";
>>> + print "\t$(compile-command.cc)" command_suffix;
>>> + }
>>> }
>>> }
>>> print "$(inst_includedir)/%.h:", dir "/%.h", "$(+force)";
>>> diff --git a/sysdeps/x86/fpu/Makefile b/sysdeps/x86/fpu/Makefile
>>> index 8566d3c80f..cb0879dd5f 100644
>>> --- a/sysdeps/x86/fpu/Makefile
>>> +++ b/sysdeps/x86/fpu/Makefile
>>> @@ -11,6 +11,11 @@ tests += \
>>> test-fenv-x87 \
>>> test-flt-eval-method-sse \
>>> # tests
>>> +ifneq (,$(CXX))
>>> +tests += \
>>> + test-builtin-denormal-cxx \
>>> +# tests
>>> +endif
>>> ifeq ($(have-test-cc-cflags-mfpmath-387),yes)
>>> tests += test-flt-eval-method-387
>>> endif
>>> diff --git a/sysdeps/x86/fpu/test-builtin-denormal-cxx.cc b/sysdeps/x86/fpu/test-builtin-denormal-cxx.cc
>>> new file mode 100644
>>> index 0000000000..0b7e8e8728
>>> --- /dev/null
>>> +++ b/sysdeps/x86/fpu/test-builtin-denormal-cxx.cc
>>> @@ -0,0 +1 @@
>>> +#include "test-builtin-denormal.c"
>>> diff --git a/sysdeps/x86/fpu/test-builtin-denormal.c b/sysdeps/x86/fpu/test-builtin-denormal.c
>>> index bddcd59387..789f1e3535 100644
>>> --- a/sysdeps/x86/fpu/test-builtin-denormal.c
>>> +++ b/sysdeps/x86/fpu/test-builtin-denormal.c
>>> @@ -40,15 +40,23 @@ static const ieee_long_double_shape_type inputs[] = {
>>> static int
>>> do_test (void)
>>> {
>>> - for (int i = 0; i < array_length (inputs); i++)
>>> + for (unsigned int i = 0; i < array_length (inputs); i++)
>>> {
>>> TEST_COMPARE (feclearexcept (FE_INVALID), 0);
>>> TEST_COMPARE (fpclassify (inputs[i].value), FP_NAN);
>>> +#ifndef __cplusplus
>>> + /* C++ uses the builtin, which does not trigger FE_INVALID for
>>> + pseudo-numbers (GCC BZ 123161 and LLVM issue 172533. */
>>> TEST_COMPARE (fetestexcept (FE_INVALID), 0);
>>
>> Shouldn't the C++ builtin be disabled?
>
> We should add a C++ test and make it XFAIL.
Alright, I will change it.
>
>>
>>> +#endif
>>>
>>> TEST_COMPARE (feclearexcept (FE_INVALID), 0);
>>> TEST_COMPARE (isinf (inputs[i].value), 0);
>>> +#ifndef __cplusplus
>>> + /* C++ uses the builtin, which does not trigger FE_INVALID for
>>> + pseudo-numbers (GCC BZ 123173 and LLVM issue 172651. */
>>> TEST_COMPARE (fetestexcept (FE_INVALID), 0);
>>> +#endif
>>> }
>>>
>>> return 0;
>>> --
>>> 2.43.0
>>>
>>
>>
>> --
>> H.J.
>
>
>
More information about the Libc-alpha
mailing list