All, The attach patch maps REAL128 from iso_fortran_env to the REAL kind type with widest precision. Prior to this patch, REAL128 is mapped to the first REAL kind type with a matching storage size of 128 bits. On x86_64-*-freebsd both REAL(10) and REAL(16) occupy 16 bytes, but REAL(10) is mapped to REAL128. This may surprise users that assume REAL128 is mapped to an IEEE754-2008 128-bit floating point entity with 113 bits of precision. OK to commit?
2017-02-07 Steven G. Kargl <ka...@gcc.gnu.org> * trans-types.c (gfc_get_int_kind_from_width_isofortranen): Choose REAL type with the widest precision if two (or more) have the same storage size. -- Steve 20161221 https://www.youtube.com/watch?v=IbCHE-hONow
Index: gcc/fortran/trans-types.c =================================================================== --- gcc/fortran/trans-types.c (revision 245068) +++ gcc/fortran/trans-types.c (working copy) @@ -234,27 +234,42 @@ gfc_get_int_kind_from_width_isofortranen return -1; } -/* Get the kind number corresponding to a real of given storage size, - following the required return values for ISO_FORTRAN_ENV REAL* constants: - -2 is returned if we support a kind of larger size, -1 otherwise. */ + +/* Get the kind number corresponding to a real of a given storage size. + If two real's have the same storage size, then choose the real with + the largest precision. If a kind type is unavailable and a real + exists with wider storage, then return -2; otherwise, return -1. */ + int gfc_get_real_kind_from_width_isofortranenv (int size) { - int i; + int digits, i, kind; size /= 8; + kind = -1; + digits = 0; + /* Look for a kind with matching storage size. */ for (i = 0; gfc_real_kinds[i].kind != 0; i++) if (int_size_in_bytes (gfc_get_real_type (gfc_real_kinds[i].kind)) == size) - return gfc_real_kinds[i].kind; + { + if (gfc_real_kinds[i].digits > digits) + { + digits = gfc_real_kinds[i].digits; + kind = gfc_real_kinds[i].kind; + } + } + + if (kind != -1) + return kind; /* Look for a kind with larger storage size. */ for (i = 0; gfc_real_kinds[i].kind != 0; i++) if (int_size_in_bytes (gfc_get_real_type (gfc_real_kinds[i].kind)) > size) - return -2; + kind = -2; - return -1; + return kind; }