Fortran: Use _Float128 rather than __float128 for c_float128 kind.

The GNU Fortran manual documents that the c_float128 kind corresponds
to __float128, but in fact the implementation uses float128_type_node,
which is _Float128.  Both refer to the 128-bit IEEE/ISO encoding, but
some targets including aarch64 only define _Float128 and not __float128,
and do not provide quadmath.h.  This caused errors in some test cases
referring to __float128.

This patch changes the documentation (including code comments) and
test cases to use _Float128 to match the implementation.

2021-09-16  Sandra Loosemore  <sandra@codesourcery.com>

gcc/fortran/

	* intrinsic.texi (ISO_C_BINDING): Change C_FLOAT128 to correspond
	to _Float128 rather than __float128.
	* iso-c-binding.def (c_float128): Update comments.
	* trans-intrinsic.c (gfc_builtin_decl_for_float_kind): Likewise.
	(build_round_expr): Likewise.
	(gfc_build_intrinsic_lib_fndcecls): Likewise.
	* trans-types.h (gfc_real16_is_float128): Likewise.

gcc/testsuite/
	* gfortran.dg/PR100914.c: Do not include quadmath.h.  Use
	_Float128 _Complex instead of __complex128.
	* gfortran.dg/PR100914.f90: Add -Wno-pedantic to suppress error
	about use of _Float128.
	* gfortran.dg/c-interop/typecodes-array-float128-c.c: Use
	_Float128 instead of __float128.
	* gfortran.dg/c-interop/typecodes-sanity-c.c: Likewise.
	* gfortran.dg/c-interop/typecodes-scalar-float128-c.c: Likewise.
	* lib/target-supports.exp
	(check_effective_target_fortran_real_c_float128): Update comments.

libgfortran/
	* ISO_Fortran_binding.h: Update comments.
	* runtime/ISO_Fortran_binding.c: Likewise.
This commit is contained in:
Sandra Loosemore 2021-09-17 08:20:51 -07:00
parent 2578a3870e
commit 00b1324f92
12 changed files with 24 additions and 25 deletions

View File

@ -15193,8 +15193,8 @@ In addition to the integer named constants required by the Fortran 2003
standard and @code{C_PTRDIFF_T} of TS 29113, GNU Fortran provides as an standard and @code{C_PTRDIFF_T} of TS 29113, GNU Fortran provides as an
extension named constants for the 128-bit integer types supported by the extension named constants for the 128-bit integer types supported by the
C compiler: @code{C_INT128_T, C_INT_LEAST128_T, C_INT_FAST128_T}. C compiler: @code{C_INT128_T, C_INT_LEAST128_T, C_INT_FAST128_T}.
Furthermore, if @code{__float128} is supported in C, the named constants Furthermore, if @code{_Float128} is supported in C, the named constants
@code{C_FLOAT128, C_FLOAT128_COMPLEX} are defined. @code{C_FLOAT128} and @code{C_FLOAT128_COMPLEX} are defined.
@multitable @columnfractions .15 .35 .35 .35 @multitable @columnfractions .15 .35 .35 .35
@headitem Fortran Type @tab Named constant @tab C type @tab Extension @headitem Fortran Type @tab Named constant @tab C type @tab Extension
@ -15225,11 +15225,11 @@ Furthermore, if @code{__float128} is supported in C, the named constants
@item @code{REAL} @tab @code{C_FLOAT} @tab @code{float} @item @code{REAL} @tab @code{C_FLOAT} @tab @code{float}
@item @code{REAL} @tab @code{C_DOUBLE} @tab @code{double} @item @code{REAL} @tab @code{C_DOUBLE} @tab @code{double}
@item @code{REAL} @tab @code{C_LONG_DOUBLE} @tab @code{long double} @item @code{REAL} @tab @code{C_LONG_DOUBLE} @tab @code{long double}
@item @code{REAL} @tab @code{C_FLOAT128} @tab @code{__float128} @tab Ext. @item @code{REAL} @tab @code{C_FLOAT128} @tab @code{_Float128} @tab Ext.
@item @code{COMPLEX}@tab @code{C_FLOAT_COMPLEX} @tab @code{float _Complex} @item @code{COMPLEX}@tab @code{C_FLOAT_COMPLEX} @tab @code{float _Complex}
@item @code{COMPLEX}@tab @code{C_DOUBLE_COMPLEX}@tab @code{double _Complex} @item @code{COMPLEX}@tab @code{C_DOUBLE_COMPLEX}@tab @code{double _Complex}
@item @code{COMPLEX}@tab @code{C_LONG_DOUBLE_COMPLEX}@tab @code{long double _Complex} @item @code{COMPLEX}@tab @code{C_LONG_DOUBLE_COMPLEX}@tab @code{long double _Complex}
@item @code{REAL} @tab @code{C_FLOAT128_COMPLEX} @tab @code{__float128 _Complex} @tab Ext. @item @code{COMPLEX}@tab @code{C_FLOAT128_COMPLEX} @tab @code{_Float128 _Complex} @tab Ext.
@item @code{LOGICAL}@tab @code{C_BOOL} @tab @code{_Bool} @item @code{LOGICAL}@tab @code{C_BOOL} @tab @code{_Bool}
@item @code{CHARACTER}@tab @code{C_CHAR} @tab @code{char} @item @code{CHARACTER}@tab @code{C_CHAR} @tab @code{char}
@end multitable @end multitable

View File

@ -116,7 +116,7 @@ NAMED_REALCST (ISOCBINDING_LONG_DOUBLE, "c_long_double", \
get_real_kind_from_node (long_double_type_node), GFC_STD_F2003) get_real_kind_from_node (long_double_type_node), GFC_STD_F2003)
/* GNU Extension. Note that the equivalence here is specifically to /* GNU Extension. Note that the equivalence here is specifically to
the IEEE 128-bit type __float128; if that does not map onto a type the IEEE 128-bit type _Float128; if that does not map onto a type
otherwise supported by the Fortran front end, get_real_kind_from_node otherwise supported by the Fortran front end, get_real_kind_from_node
will reject it as unsupported. */ will reject it as unsupported. */
NAMED_REALCST (ISOCBINDING_FLOAT128, "c_float128", \ NAMED_REALCST (ISOCBINDING_FLOAT128, "c_float128", \

View File

@ -175,7 +175,7 @@ gfc_builtin_decl_for_float_kind (enum built_in_function double_built_in,
if (gfc_real_kinds[i].c_float128) if (gfc_real_kinds[i].c_float128)
{ {
/* For __float128, the story is a bit different, because we return /* For _Float128, the story is a bit different, because we return
a decl to a library function rather than a built-in. */ a decl to a library function rather than a built-in. */
gfc_intrinsic_map_t *m; gfc_intrinsic_map_t *m;
for (m = gfc_intrinsic_map; m->double_built_in != double_built_in ; m++) for (m = gfc_intrinsic_map; m->double_built_in != double_built_in ; m++)
@ -387,7 +387,7 @@ build_round_expr (tree arg, tree restype)
resprec = TYPE_PRECISION (restype); resprec = TYPE_PRECISION (restype);
/* Depending on the type of the result, choose the int intrinsic (iround, /* Depending on the type of the result, choose the int intrinsic (iround,
available only as a builtin, therefore cannot use it for __float128), long available only as a builtin, therefore cannot use it for _Float128), long
int intrinsic (lround family) or long long intrinsic (llround). If we int intrinsic (lround family) or long long intrinsic (llround). If we
don't have an appropriate function that converts directly to the integer don't have an appropriate function that converts directly to the integer
type (such as kind == 16), just use ROUND, and then convert the result to type (such as kind == 16), just use ROUND, and then convert the result to
@ -689,7 +689,7 @@ gfc_build_intrinsic_lib_fndecls (void)
if (gfc_real16_is_float128) if (gfc_real16_is_float128)
{ {
/* If we have soft-float types, we create the decls for their /* If we have soft-float types, we create the decls for their
C99-like library functions. For now, we only handle __float128 C99-like library functions. For now, we only handle _Float128
q-suffixed functions. */ q-suffixed functions. */
tree type, complex_type, func_1, func_2, func_cabs, func_frexp; tree type, complex_type, func_1, func_2, func_cabs, func_frexp;

View File

@ -55,7 +55,7 @@ extern GTY(()) tree gfc_charlen_type_node;
/* The following flags give us information on the correspondence of /* The following flags give us information on the correspondence of
real (and complex) kinds with C floating-point types long double real (and complex) kinds with C floating-point types long double
and __float128. */ and _Float128. */
extern bool gfc_real16_is_float128; extern bool gfc_real16_is_float128;
enum gfc_packed { enum gfc_packed {

View File

@ -5,7 +5,6 @@
#include <stdbool.h> #include <stdbool.h>
#include <stdio.h> #include <stdio.h>
#include <math.h> #include <math.h>
#include <quadmath.h>
#include <ISO_Fortran_binding.h> #include <ISO_Fortran_binding.h>
@ -29,7 +28,7 @@
#define CMPLXL(x, y) ((long double complex)((long double)(x) + (long double complex)I * (long double)(y))) #define CMPLXL(x, y) ((long double complex)((long double)(x) + (long double complex)I * (long double)(y)))
#undef CMPLX #undef CMPLX
#define CMPLX(x, y) ((__complex128 )((double)(x) + (double complex)I * (double)(y))) #define CMPLX(x, y) ((_Float128 _Complex )((double)(x) + (double complex)I * (double)(y)))
#define N 11 #define N 11
#define M 7 #define M 7
@ -37,7 +36,7 @@
typedef float _Complex c_float_complex; typedef float _Complex c_float_complex;
typedef double _Complex c_double_complex; typedef double _Complex c_double_complex;
typedef long double _Complex c_long_double_complex; typedef long double _Complex c_long_double_complex;
typedef __complex128 c_float128_complex; typedef _Float128 _Complex c_float128_complex;
bool c_vrfy_c_float_complex (const CFI_cdesc_t *restrict); bool c_vrfy_c_float_complex (const CFI_cdesc_t *restrict);

View File

@ -2,6 +2,7 @@
! { dg-do run { xfail { { x86_64*-*-* i?86*-*-* } && longdouble128 } } } ! { dg-do run { xfail { { x86_64*-*-* i?86*-*-* } && longdouble128 } } }
! { dg-additional-sources PR100914.c } ! { dg-additional-sources PR100914.c }
! { dg-require-effective-target fortran_real_c_float128 } ! { dg-require-effective-target fortran_real_c_float128 }
! { dg-additional-options "-Wno-pedantic" }
! !
! Test the fix for PR100914 ! Test the fix for PR100914
! !

View File

@ -32,7 +32,7 @@ void
ctest (CFI_cdesc_t *arg_float128, ctest (CFI_cdesc_t *arg_float128,
CFI_cdesc_t *arg_complex128) CFI_cdesc_t *arg_complex128)
{ {
check (arg_float128, sizeof (__float128), CFI_type_float128); check (arg_float128, sizeof (_Float128), CFI_type_float128);
check (arg_complex128, sizeof (__float128) * 2, check (arg_complex128, sizeof (_Float128) * 2,
CFI_type_float128_Complex); CFI_type_float128_Complex);
} }

View File

@ -23,8 +23,7 @@ static struct tc_info tc_table[] =
{ {
/* Extension types. /* Extension types.
Note there is no portable C equivalent type for CFI_type_ucs4_char type Note there is no portable C equivalent type for CFI_type_ucs4_char type
(4-byte Unicode characters), and GCC rejects "__float128 _Complex", (4-byte Unicode characters), so this is kind of hacky... */
so this is kind of hacky... */
#if CFI_type_int128_t > 0 #if CFI_type_int128_t > 0
{ CFI_type_int128_t, "CFI_type_int128_t", { CFI_type_int128_t, "CFI_type_int128_t",
sizeof (__int128), 1 }, sizeof (__int128), 1 },
@ -38,9 +37,9 @@ static struct tc_info tc_table[] =
#endif #endif
#if CFI_type_float128 > 0 #if CFI_type_float128 > 0
{ CFI_type_float128, "CFI_type_float128", { CFI_type_float128, "CFI_type_float128",
sizeof (__float128), 1 }, sizeof (_Float128), 1 },
{ CFI_type_float128_Complex, "CFI_type_float128_Complex", { CFI_type_float128_Complex, "CFI_type_float128_Complex",
sizeof (__float128) * 2, 1 }, sizeof (_Float128 _Complex), 1 },
#endif #endif
#if CFI_type_cfunptr > 0 #if CFI_type_cfunptr > 0
{ CFI_type_cfunptr, "CFI_type_cfunptr", { CFI_type_cfunptr, "CFI_type_cfunptr",

View File

@ -31,8 +31,8 @@ void
ctest (CFI_cdesc_t *arg_float128, ctest (CFI_cdesc_t *arg_float128,
CFI_cdesc_t *arg_complex128) CFI_cdesc_t *arg_complex128)
{ {
check (arg_float128, sizeof (__float128), CFI_type_float128); check (arg_float128, sizeof (_Float128), CFI_type_float128);
check (arg_complex128, sizeof (__float128) * 2, check (arg_complex128, sizeof (_Float128) * 2,
CFI_type_float128_Complex); CFI_type_float128_Complex);
} }

View File

@ -1578,8 +1578,8 @@ proc check_effective_target_fortran_real_10 { } {
# Return 1 if the target supports Fortran real kind C_FLOAT128, # Return 1 if the target supports Fortran real kind C_FLOAT128,
# 0 otherwise. This differs from check_effective_target_fortran_real_16 # 0 otherwise. This differs from check_effective_target_fortran_real_16
# because __float128 has the additional requirement that it be the # because _Float128 has the additional requirement that it be the
# 128-bit IEEE encoding; even if __float128 is available in C, it may not # 128-bit IEEE encoding; even if _Float128 is available in C, it may not
# have a corresponding Fortran kind on targets (PowerPC) that use some # have a corresponding Fortran kind on targets (PowerPC) that use some
# other encoding for long double/TFmode/real(16). # other encoding for long double/TFmode/real(16).
proc check_effective_target_fortran_real_c_float128 { } { proc check_effective_target_fortran_real_c_float128 { } {

View File

@ -281,7 +281,7 @@ extern int CFI_setpointer (CFI_cdesc_t *, CFI_cdesc_t *, const CFI_index_t []);
#define CFI_type_long_double (CFI_type_Real + (10 << CFI_type_kind_shift)) #define CFI_type_long_double (CFI_type_Real + (10 << CFI_type_kind_shift))
#define CFI_type_long_double_Complex (CFI_type_Complex + (10 << CFI_type_kind_shift)) #define CFI_type_long_double_Complex (CFI_type_Complex + (10 << CFI_type_kind_shift))
/* This is the IEEE 128-bit encoding, same as float128. */ /* This is the IEEE 128-bit encoding, same as _Float128. */
#elif (__CFI_LDBL_MANT_DIG__ == 113 \ #elif (__CFI_LDBL_MANT_DIG__ == 113 \
&& __CFI_LDBL_MIN_EXP__ == -16381 \ && __CFI_LDBL_MIN_EXP__ == -16381 \
&& __CFI_LDBL_MAX_EXP__ == 16384) && __CFI_LDBL_MAX_EXP__ == 16384)
@ -303,7 +303,7 @@ extern int CFI_setpointer (CFI_cdesc_t *, CFI_cdesc_t *, const CFI_index_t []);
#error "Can't determine kind of long double" #error "Can't determine kind of long double"
#endif #endif
/* Similarly for __float128. This always refers to the IEEE encoding /* Similarly for _Float128. This always refers to the IEEE encoding
and not some other 128-bit representation, so if we already used and not some other 128-bit representation, so if we already used
kind 16 for a non-IEEE representation, this one must be unsupported kind 16 for a non-IEEE representation, this one must be unsupported
in Fortran even if it's available in C. */ in Fortran even if it's available in C. */

View File

@ -222,7 +222,7 @@ gfc_desc_to_cfi_desc (CFI_cdesc_t **d_ptr, const gfc_array_void *s)
elem_len and not the kind, we get into trouble with long double kinds elem_len and not the kind, we get into trouble with long double kinds
that do not correspond directly to the elem_len, specifically the that do not correspond directly to the elem_len, specifically the
kind 10 80-bit long double on x86 targets. On x86_64, this has size kind 10 80-bit long double on x86 targets. On x86_64, this has size
16 and cannot be differentiated from true __float128. Prefer the 16 and cannot be differentiated from true _Float128. Prefer the
standard long double type over the GNU extension in that case. */ standard long double type over the GNU extension in that case. */
if (d->type == CFI_type_Real && kind == sizeof (long double)) if (d->type == CFI_type_Real && kind == sizeof (long double))
d->type = CFI_type_long_double; d->type = CFI_type_long_double;