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:
parent
2578a3870e
commit
00b1324f92
|
@ -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
|
||||||
|
|
|
@ -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", \
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
!
|
!
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 { } {
|
||||||
|
|
|
@ -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. */
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue