aboutsummaryrefslogtreecommitdiff
path: root/gcc/c
diff options
context:
space:
mode:
authorJoseph Myers <joseph@codesourcery.com>2023-01-06 19:31:26 +0000
committerJoseph Myers <joseph@codesourcery.com>2023-01-06 19:31:26 +0000
commit5b68fb47bd24abc2e6a65e5617f586d1c1b81d4e (patch)
treed5951144716ceb901447d8ef2d4449cab1f991c3 /gcc/c
parentf3707a55acb980fbcd412ceb980b5621decb4dc0 (diff)
downloadgcc-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.cc42
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;