diff options
author | Joseph Myers <joseph@codesourcery.com> | 2023-01-06 19:31:26 +0000 |
---|---|---|
committer | Joseph Myers <joseph@codesourcery.com> | 2023-01-06 19:31:26 +0000 |
commit | 5b68fb47bd24abc2e6a65e5617f586d1c1b81d4e (patch) | |
tree | d5951144716ceb901447d8ef2d4449cab1f991c3 /gcc/c | |
parent | f3707a55acb980fbcd412ceb980b5621decb4dc0 (diff) | |
download | gcc-5b68fb47bd24abc2e6a65e5617f586d1c1b81d4e.zip gcc-5b68fb47bd24abc2e6a65e5617f586d1c1b81d4e.tar.gz gcc-5b68fb47bd24abc2e6a65e5617f586d1c1b81d4e.tar.bz2 |
c: C2x semantics for __builtin_tgmath
__builtin_tgmath implements <tgmath.h> semantics for integer generic
arguments that handle cases involving _FloatN / _FloatNx types as
specified in TS 18661-3 plus some defect fixes.
C2x has further changes to the semantics for <tgmath.h> macros with
such types, which should also be considered defect fixes (although
handled through the integration of TS 18661-3 in C2x rather than
through an issue tracking process). Specifically, the rules were
changed because of problems raised with using the macros with the
evaluation format types such as float_t and _Float32_t: the older
version of the rules didn't allow passing _FloatN / _FloatNx types to
the narrowing macros returning float or double, or passing float /
double / long double to the narrowing macros returning _FloatN /
_FloatNx, which was a problem with the evaluation format types which
could be either kind of type depending on the value of
FLT_EVAL_METHOD.
Thus the new rules allow cases of mixing types which were not allowed
before - which is not itself a problem for __builtin_tgmath - and, as
part of the changes, the handling of integer arguments was also
changed: if there is any _FloatNx generic argument, integer generic
arguments are treated as _Float32x (not double), while the rule about
treating integer arguments to narrowing macros returning _FloatN or
_FloatNx as _Float64 not double was removed (no longer needed now
double is a valid argument to such macros).
Implement the changes for __builtin_tgmath. (The changes also added a
rule that if any argument is _DecimalNx, integer arguments are treated
as _Decimal64x, but GCC doesn't support _DecimalNx types so nothing is
done about that.)
I have a corresponding glibc patch to update glibc test expectations
for C2x and also ensure that appropriate semantics are followed when
GCC 7 through 12 are used with <tgmath.h> (avoiding __builtin_tgmath
in cases where it doesn't match the C2x semantics).
Bootstrapped with no regressions for x86_64-pc-linux-gnu.
gcc/
* doc/extend.texi (__builtin_tgmath): Do not restate standard rule
for handling real integer types.
gcc/c/
* c-parser.cc (c_parser_postfix_expression): Handle integer
generic arguments to functions passed to __builtin_tgmath as
_Float32x if any argument has _FloatNx or _Complex _FloatNx type.
Do not handle integer arguments to some narrowing functions as
_Float64.
gcc/testsuite/
* gcc.dg/builtin-tgmath-3.c: Update expectations and add more
tests.
Diffstat (limited to 'gcc/c')
-rw-r--r-- | gcc/c/c-parser.cc | 42 |
1 files changed, 20 insertions, 22 deletions
diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc index 7d6960f..3a59980 100644 --- a/gcc/c/c-parser.cc +++ b/gcc/c/c-parser.cc @@ -10276,16 +10276,17 @@ c_parser_postfix_expression (c_parser *parser) types are treated as _Decimal64 if any type-generic argument is decimal, or if the only alternatives for type-generic arguments are of decimal types, and are - otherwise treated as double (or _Complex double for - complex integer types, or _Float64 or _Complex _Float64 - if all the return types are the same _FloatN or - _FloatNx type). After that adjustment, types are - combined following the usual arithmetic conversions. - If the function only accepts complex arguments, a - complex type is produced. */ + otherwise treated as _Float32x (or _Complex _Float32x + for complex integer types) if any type-generic argument + has _FloatNx type, otherwise as double (or _Complex + double for complex integer types). After that + adjustment, types are combined following the usual + arithmetic conversions. If the function only accepts + complex arguments, a complex type is produced. */ bool arg_complex = all_complex; bool arg_binary = all_binary; bool arg_int_decimal = all_decimal; + bool arg_int_floatnx = false; for (unsigned int j = 1; j <= nargs; j++) { if (parm_kind[j] == tgmath_fixed) @@ -10380,20 +10381,17 @@ c_parser_postfix_expression (c_parser *parser) goto out; } } + tree rtype = TYPE_MAIN_VARIANT (type); + if (TREE_CODE (rtype) == COMPLEX_TYPE) + rtype = TREE_TYPE (rtype); + if (SCALAR_FLOAT_TYPE_P (rtype)) + for (unsigned int j = 0; j < NUM_FLOATNX_TYPES; j++) + if (rtype == FLOATNX_TYPE_NODE (j)) + { + arg_int_floatnx = true; + break; + } } - /* For a macro rounding its result to a narrower type, map - integer types to _Float64 not double if the return type - is a _FloatN or _FloatNx type. */ - bool arg_int_float64 = false; - if (parm_kind[0] == tgmath_fixed - && SCALAR_FLOAT_TYPE_P (parm_first[0]) - && float64_type_node != NULL_TREE) - for (unsigned int j = 0; j < NUM_FLOATN_NX_TYPES; j++) - if (parm_first[0] == FLOATN_TYPE_NODE (j)) - { - arg_int_float64 = true; - break; - } tree arg_real = NULL_TREE; for (unsigned int j = 1; j <= nargs; j++) { @@ -10406,8 +10404,8 @@ c_parser_postfix_expression (c_parser *parser) if (INTEGRAL_TYPE_P (type)) type = (arg_int_decimal ? dfloat64_type_node - : arg_int_float64 - ? float64_type_node + : arg_int_floatnx + ? float32x_type_node : double_type_node); if (arg_real == NULL_TREE) arg_real = type; |