[WIP] fortran: Accept "15" modules for compatibility [PR118337]

Message ID Z35JEqZTdCQzwMB6@tucnak
State New
Headers
Series [WIP] fortran: Accept "15" modules for compatibility [PR118337] |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gcc_build--master-aarch64 fail Patch failed to apply

Commit Message

Jakub Jelinek Jan. 8, 2025, 9:44 a.m. UTC
  Hi!

Based on the comments in the PR, I've tried to write a patch which would
try to keep backwards compatibility with the GCC 11-14 *.mod files.

Testcase was
module a
  use, intrinsic :: iso_c_binding
end module a
module b
  use, intrinsic :: iso_fortran_env
end module b
and zcat a.mod; zcat b.mod
Without this patch there are changes all around in the numbers
because various new entries have been added in the middle.
With this patch, there are still some changes:
1) __vtype___iso_c_binding_C_funptr and
   __vtype___iso_c_binding_C_ptr have added RECURSIVE in GCC 15 compared to
   14
2) __copy___iso_c_binding_C_funptr used to be 94 and now is 98,
   __copy___iso_c_binding_C_ptr 97 -> 101 and src/dst also changed
3) __vtype_iso_fortran_env_Event_type and __vtype_iso_fortran_env_Lock_type
   and __vtype_iso_fortran_env_Team_type also have RECURSIVE added
4) logical_kinds 59 -> 63, numeric_storage_size 60 -> 64, etc.
So, I really don't know if it is feasible to ensure backwards compatibility.

Plus how we would actually test whether we are able to accept the older
modules in newer compilers.

2025-01-08  Jakub Jelinek  <jakub@redhat.com>

	PR fortran/118337
	* module.cc (COMPAT_MOD_VERSIONS): Define.
	(gfc_use_module): Accept also COMPAT_MOD_VERSIONS for compatibility.
	* iso-c-binding.def: Reorder entries so that the GCC 14 ones come
	before the ones new in GCC 15.
	* iso-fortran-env.def: Likewise.


	Jakub
  

Comments

Richard Biener Jan. 8, 2025, 9:47 a.m. UTC | #1
On Wed, Jan 8, 2025 at 10:45 AM Jakub Jelinek <jakub@redhat.com> wrote:
>
> Hi!
>
> Based on the comments in the PR, I've tried to write a patch which would
> try to keep backwards compatibility with the GCC 11-14 *.mod files.
>
> Testcase was
> module a
>   use, intrinsic :: iso_c_binding
> end module a
> module b
>   use, intrinsic :: iso_fortran_env
> end module b
> and zcat a.mod; zcat b.mod
> Without this patch there are changes all around in the numbers
> because various new entries have been added in the middle.
> With this patch, there are still some changes:
> 1) __vtype___iso_c_binding_C_funptr and
>    __vtype___iso_c_binding_C_ptr have added RECURSIVE in GCC 15 compared to
>    14
> 2) __copy___iso_c_binding_C_funptr used to be 94 and now is 98,
>    __copy___iso_c_binding_C_ptr 97 -> 101 and src/dst also changed
> 3) __vtype_iso_fortran_env_Event_type and __vtype_iso_fortran_env_Lock_type
>    and __vtype_iso_fortran_env_Team_type also have RECURSIVE added
> 4) logical_kinds 59 -> 63, numeric_storage_size 60 -> 64, etc.
> So, I really don't know if it is feasible to ensure backwards compatibility.
>
> Plus how we would actually test whether we are able to accept the older
> modules in newer compilers.

I wonder if we can somehow add some test coverage?  Are .mod files
target independent and thus can we include them in the testsuite?

Richard.

> 2025-01-08  Jakub Jelinek  <jakub@redhat.com>
>
>         PR fortran/118337
>         * module.cc (COMPAT_MOD_VERSIONS): Define.
>         (gfc_use_module): Accept also COMPAT_MOD_VERSIONS for compatibility.
>         * iso-c-binding.def: Reorder entries so that the GCC 14 ones come
>         before the ones new in GCC 15.
>         * iso-fortran-env.def: Likewise.
>
> --- gcc/fortran/module.cc.jj    2025-01-08 10:05:39.308786981 +0100
> +++ gcc/fortran/module.cc       2025-01-08 10:18:14.234222227 +0100
> @@ -85,6 +85,8 @@ along with GCC; see the file COPYING3.
>  /* Don't put any single quote (') in MOD_VERSION, if you want it to be
>     recognized.  */
>  #define MOD_VERSION "16"
> +/* Older mod versions we can still parse.  */
> +#define COMPAT_MOD_VERSIONS { "15" }
>
>
>  /* Structure that describes a position within a module file.  */
> @@ -7451,10 +7453,23 @@ gfc_use_module (gfc_use_list *module)
>                          " module file", module_fullpath);
>        if (start == 3)
>         {
> +         bool fatal = false;
>           if (strcmp (atom_name, " version") != 0
>               || module_char () != ' '
> -             || parse_atom () != ATOM_STRING
> -             || strcmp (atom_string, MOD_VERSION))
> +             || parse_atom () != ATOM_STRING)
> +           fatal = true;
> +         else if (strcmp (atom_string, MOD_VERSION))
> +           {
> +             static const char *compat_mod_versions[] = COMPAT_MOD_VERSIONS;
> +             fatal = true;
> +             for (unsigned i = 0; i < ARRAY_SIZE (compat_mod_versions); ++i)
> +               if (!strcmp (atom_string, compat_mod_versions[i]))
> +                 {
> +                   fatal = false;
> +                   break;
> +                 }
> +           }
> +         if (fatal)
>             gfc_fatal_error ("Cannot read module file %qs opened at %C,"
>                              " because it was created by a different"
>                              " version of GNU Fortran", module_fullpath);
> --- gcc/fortran/iso-c-binding.def.jj    2025-01-02 11:47:31.894198887 +0100
> +++ gcc/fortran/iso-c-binding.def       2025-01-08 10:09:12.454799919 +0100
> @@ -17,7 +17,8 @@ along with GCC; see the file COPYING3.
>  <http://www.gnu.org/licenses/>.  */
>
>  /* This file contains the definition of the types provided by the
> -   Fortran 2003 ISO_C_BINDING intrinsic module.  */
> +   Fortran 2003 ISO_C_BINDING intrinsic module.  The ordering of
> +   the entries matters for the *.mod backwards compatibility.  */
>
>  #ifndef NAMED_INTCST
>  # define NAMED_INTCST(a,b,c,d)
> @@ -112,62 +113,6 @@ NAMED_INTCST (ISOCBINDING_INT_FAST64_T,
>  NAMED_INTCST (ISOCBINDING_INT_FAST128_T, "c_int_fast128_t",
>               get_int_kind_from_width (128), GFC_STD_GNU)
>
> -/* UNSIGNED.  */
> -NAMED_UINTCST (ISOCBINDING_UINT, "c_unsigned", gfc_c_uint_kind, \
> -              GFC_STD_UNSIGNED)
> -NAMED_UINTCST (ISOCBINDING_USHORT, "c_unsigned_short", \
> -              get_unsigned_kind_from_node (short_unsigned_type_node), \
> -              GFC_STD_UNSIGNED)
> -NAMED_UINTCST (ISOCBINDING_UCHAR, "c_unsigned_char", \
> -              get_unsigned_kind_from_node (unsigned_char_type_node), \
> -              GFC_STD_UNSIGNED)
> -NAMED_UINTCST (ISOCBINDING_ULONG, "c_unsigned_long", \
> -              get_unsigned_kind_from_node (long_unsigned_type_node), \
> -              GFC_STD_UNSIGNED)
> -NAMED_UINTCST (ISOCBINDING_ULONGLONG, "c_unsigned_long_long", \
> -              get_unsigned_kind_from_node (long_long_unsigned_type_node), \
> -              GFC_STD_UNSIGNED)
> -NAMED_UINTCST (ISOCBINDING_UINTMAX_T, "c_uintmax_t", \
> -              get_uint_kind_from_name (UINTMAX_TYPE), GFC_STD_UNSIGNED)
> -NAMED_UINTCST (ISOCBINDING_UINT8_T, "c_uint8_t", \
> -              get_uint_kind_from_name (UINT8_TYPE), GFC_STD_UNSIGNED)
> -NAMED_UINTCST (ISOCBINDING_UINT16_T, "c_uint16_t", \
> -              get_uint_kind_from_name (UINT16_TYPE), GFC_STD_UNSIGNED)
> -NAMED_UINTCST (ISOCBINDING_UINT32_T, "c_uint32_t", \
> -              get_uint_kind_from_name (UINT32_TYPE), GFC_STD_UNSIGNED)
> -NAMED_UINTCST (ISOCBINDING_UINT64_T, "c_uint64_t", \
> -              get_uint_kind_from_name (UINT64_TYPE), GFC_STD_UNSIGNED)
> -NAMED_UINTCST (ISOCBINDING_UINT128_T, "c_uint128_t", \
> -              get_uint_kind_from_width (128), GFC_STD_UNSIGNED)
> -NAMED_UINTCST (ISOCBINDING_UINT_LEAST8_T, "c_uint_least8_t", \
> -              get_uint_kind_from_name (UINT_LEAST8_TYPE), \
> -              GFC_STD_UNSIGNED)
> -NAMED_UINTCST (ISOCBINDING_UINT_LEAST16_T, "c_uint_least16_t", \
> -              get_uint_kind_from_name (UINT_LEAST16_TYPE), \
> -              GFC_STD_UNSIGNED)
> -NAMED_UINTCST (ISOCBINDING_UINT_LEAST32_T, "c_uint_least32_t", \
> -              get_uint_kind_from_name (UINT_LEAST32_TYPE),\
> -              GFC_STD_UNSIGNED)
> -NAMED_UINTCST (ISOCBINDING_UINT_LEAST64_T, "c_uint_least64_t", \
> -              get_uint_kind_from_name (UINT_LEAST64_TYPE),\
> -              GFC_STD_UNSIGNED)
> -NAMED_UINTCST (ISOCBINDING_UINT_LEAST128_T, "c_uint_least128_t", \
> -              get_uint_kind_from_width (128), GFC_STD_UNSIGNED)
> -NAMED_UINTCST (ISOCBINDING_UINT_FAST8_T, "c_uint_fast8_t", \
> -              get_uint_kind_from_name (UINT_FAST8_TYPE), \
> -              GFC_STD_UNSIGNED)
> -NAMED_UINTCST (ISOCBINDING_UINT_FAST16_T, "c_uint_fast16_t", \
> -              get_uint_kind_from_name (UINT_FAST16_TYPE), \
> -              GFC_STD_UNSIGNED)
> -NAMED_UINTCST (ISOCBINDING_UINT_FAST32_T, "c_uint_fast32_t", \
> -              get_uint_kind_from_name (UINT_FAST32_TYPE),\
> -              GFC_STD_UNSIGNED)
> -NAMED_UINTCST (ISOCBINDING_UINT_FAST64_T, "c_uint_fast64_t", \
> -              get_uint_kind_from_name (UINT_FAST64_TYPE),\
> -              GFC_STD_UNSIGNED)
> -NAMED_UINTCST (ISOCBINDING_UINT_FAST128_T, "c_uint_fast128_t", \
> -              get_uint_kind_from_width (128), GFC_STD_UNSIGNED)
> -
>  NAMED_REALCST (ISOCBINDING_FLOAT, "c_float", \
>                 get_real_kind_from_node (float_type_node), GFC_STD_F2003)
>  NAMED_REALCST (ISOCBINDING_DOUBLE, "c_double", \
> @@ -259,6 +204,62 @@ NAMED_FUNCTION (ISOCBINDING_C_SIZEOF, "c
>  NAMED_FUNCTION (ISOCBINDING_F_C_STRING, "f_c_string", \
>                  GFC_ISYM_F_C_STRING, GFC_STD_F2023)
>
> +/* UNSIGNED.  */
> +NAMED_UINTCST (ISOCBINDING_UINT, "c_unsigned", gfc_c_uint_kind, \
> +              GFC_STD_UNSIGNED)
> +NAMED_UINTCST (ISOCBINDING_USHORT, "c_unsigned_short", \
> +              get_unsigned_kind_from_node (short_unsigned_type_node), \
> +              GFC_STD_UNSIGNED)
> +NAMED_UINTCST (ISOCBINDING_UCHAR, "c_unsigned_char", \
> +              get_unsigned_kind_from_node (unsigned_char_type_node), \
> +              GFC_STD_UNSIGNED)
> +NAMED_UINTCST (ISOCBINDING_ULONG, "c_unsigned_long", \
> +              get_unsigned_kind_from_node (long_unsigned_type_node), \
> +              GFC_STD_UNSIGNED)
> +NAMED_UINTCST (ISOCBINDING_ULONGLONG, "c_unsigned_long_long", \
> +              get_unsigned_kind_from_node (long_long_unsigned_type_node), \
> +              GFC_STD_UNSIGNED)
> +NAMED_UINTCST (ISOCBINDING_UINTMAX_T, "c_uintmax_t", \
> +              get_uint_kind_from_name (UINTMAX_TYPE), GFC_STD_UNSIGNED)
> +NAMED_UINTCST (ISOCBINDING_UINT8_T, "c_uint8_t", \
> +              get_uint_kind_from_name (UINT8_TYPE), GFC_STD_UNSIGNED)
> +NAMED_UINTCST (ISOCBINDING_UINT16_T, "c_uint16_t", \
> +              get_uint_kind_from_name (UINT16_TYPE), GFC_STD_UNSIGNED)
> +NAMED_UINTCST (ISOCBINDING_UINT32_T, "c_uint32_t", \
> +              get_uint_kind_from_name (UINT32_TYPE), GFC_STD_UNSIGNED)
> +NAMED_UINTCST (ISOCBINDING_UINT64_T, "c_uint64_t", \
> +              get_uint_kind_from_name (UINT64_TYPE), GFC_STD_UNSIGNED)
> +NAMED_UINTCST (ISOCBINDING_UINT128_T, "c_uint128_t", \
> +              get_uint_kind_from_width (128), GFC_STD_UNSIGNED)
> +NAMED_UINTCST (ISOCBINDING_UINT_LEAST8_T, "c_uint_least8_t", \
> +              get_uint_kind_from_name (UINT_LEAST8_TYPE), \
> +              GFC_STD_UNSIGNED)
> +NAMED_UINTCST (ISOCBINDING_UINT_LEAST16_T, "c_uint_least16_t", \
> +              get_uint_kind_from_name (UINT_LEAST16_TYPE), \
> +              GFC_STD_UNSIGNED)
> +NAMED_UINTCST (ISOCBINDING_UINT_LEAST32_T, "c_uint_least32_t", \
> +              get_uint_kind_from_name (UINT_LEAST32_TYPE),\
> +              GFC_STD_UNSIGNED)
> +NAMED_UINTCST (ISOCBINDING_UINT_LEAST64_T, "c_uint_least64_t", \
> +              get_uint_kind_from_name (UINT_LEAST64_TYPE),\
> +              GFC_STD_UNSIGNED)
> +NAMED_UINTCST (ISOCBINDING_UINT_LEAST128_T, "c_uint_least128_t", \
> +              get_uint_kind_from_width (128), GFC_STD_UNSIGNED)
> +NAMED_UINTCST (ISOCBINDING_UINT_FAST8_T, "c_uint_fast8_t", \
> +              get_uint_kind_from_name (UINT_FAST8_TYPE), \
> +              GFC_STD_UNSIGNED)
> +NAMED_UINTCST (ISOCBINDING_UINT_FAST16_T, "c_uint_fast16_t", \
> +              get_uint_kind_from_name (UINT_FAST16_TYPE), \
> +              GFC_STD_UNSIGNED)
> +NAMED_UINTCST (ISOCBINDING_UINT_FAST32_T, "c_uint_fast32_t", \
> +              get_uint_kind_from_name (UINT_FAST32_TYPE),\
> +              GFC_STD_UNSIGNED)
> +NAMED_UINTCST (ISOCBINDING_UINT_FAST64_T, "c_uint_fast64_t", \
> +              get_uint_kind_from_name (UINT_FAST64_TYPE),\
> +              GFC_STD_UNSIGNED)
> +NAMED_UINTCST (ISOCBINDING_UINT_FAST128_T, "c_uint_fast128_t", \
> +              get_uint_kind_from_width (128), GFC_STD_UNSIGNED)
> +
>  #undef NAMED_INTCST
>  #undef NAMED_UINTCST
>  #undef NAMED_REALCST
> --- gcc/fortran/iso-fortran-env.def.jj  2025-01-02 11:47:32.137195494 +0100
> +++ gcc/fortran/iso-fortran-env.def     2025-01-08 10:11:44.946667057 +0100
> @@ -17,7 +17,8 @@ along with GCC; see the file COPYING3.
>  <http://www.gnu.org/licenses/>.  */
>
>  /* This file contains the definition of the named integer constants provided
> -   by the Fortran 2003 ISO_FORTRAN_ENV intrinsic module.  */
> +   by the Fortran 2003 ISO_FORTRAN_ENV intrinsic module.  The ordering of
> +   the entries matters for the *.mod backwards compatibility.  */
>
>  #ifndef NAMED_INTCST
>  # define NAMED_INTCST(a,b,c,d)
> @@ -72,20 +73,10 @@ NAMED_INTCST (ISOFORTRANENV_IOSTAT_EOR,
>  NAMED_INTCST (ISOFORTRANENV_IOSTAT_INQUIRE_INTERNAL_UNIT, \
>                "iostat_inquire_internal_unit", LIBERROR_INQUIRE_INTERNAL_UNIT, \
>                GFC_STD_F2008)
> -NAMED_INTCST (ISOFORTRANENV_LOGICAL8, "logical8", \
> -              gfc_get_int_kind_from_width_isofortranenv (8), GFC_STD_F2023)
> -NAMED_INTCST (ISOFORTRANENV_LOGICAL16, "logical16", \
> -              gfc_get_int_kind_from_width_isofortranenv (16), GFC_STD_F2023)
> -NAMED_INTCST (ISOFORTRANENV_LOGICAL32, "logical32", \
> -              gfc_get_int_kind_from_width_isofortranenv (32), GFC_STD_F2023)
> -NAMED_INTCST (ISOFORTRANENV_LOGICAL64, "logical64", \
> -              gfc_get_int_kind_from_width_isofortranenv (64), GFC_STD_F2023)
>  NAMED_INTCST (ISOFORTRANENV_NUMERIC_STORAGE_SIZE, "numeric_storage_size", \
>                gfc_numeric_storage_size, GFC_STD_F2003)
>  NAMED_INTCST (ISOFORTRANENV_OUTPUT_UNIT, "output_unit", GFC_STDOUT_UNIT_NUMBER, \
>                GFC_STD_F2003)
> -NAMED_INTCST (ISOFORTRANENV_REAL16, "real16", \
> -              gfc_get_real_kind_from_width_isofortranenv (16), GFC_STD_F2023)
>  NAMED_INTCST (ISOFORTRANENV_REAL32, "real32", \
>                gfc_get_real_kind_from_width_isofortranenv (32), GFC_STD_F2008)
>  NAMED_INTCST (ISOFORTRANENV_REAL64, "real64", \
> @@ -103,14 +94,7 @@ NAMED_INTCST (ISOFORTRANENV_FILE_STAT_FA
>                GFC_STAT_FAILED_IMAGE, GFC_STD_F2018)
>  NAMED_INTCST (ISOFORTRANENV_FILE_STAT_UNLOCKED, "stat_unlocked", \
>                GFC_STAT_UNLOCKED, GFC_STD_F2008)
> -NAMED_UINTCST (ISOFORTRANENV_UINT8, "uint8", \
> -              gfc_get_uint_kind_from_width_isofortranenv (8), GFC_STD_UNSIGNED)
> -NAMED_UINTCST (ISOFORTRANENV_UINT16, "uint16", \
> -              gfc_get_uint_kind_from_width_isofortranenv (16), GFC_STD_UNSIGNED)
> -NAMED_UINTCST (ISOFORTRANENV_UINT32, "uint32", \
> -              gfc_get_uint_kind_from_width_isofortranenv (32), GFC_STD_UNSIGNED)
> -NAMED_UINTCST (ISOFORTRANENV_UINT64, "uint64", \
> -              gfc_get_uint_kind_from_width_isofortranenv (64), GFC_STD_UNSIGNED)
> +
>
>  /* The arguments to NAMED_KINDARRAY are:
>       -- an internal name
> @@ -154,6 +138,26 @@ NAMED_DERIVED_TYPE (ISOFORTRAN_TEAM_TYPE
>                     ? get_int_kind_from_node (ptr_type_node)
>                     : gfc_default_integer_kind, GFC_STD_F2018)
>
> +NAMED_INTCST (ISOFORTRANENV_LOGICAL8, "logical8", \
> +              gfc_get_int_kind_from_width_isofortranenv (8), GFC_STD_F2023)
> +NAMED_INTCST (ISOFORTRANENV_LOGICAL16, "logical16", \
> +              gfc_get_int_kind_from_width_isofortranenv (16), GFC_STD_F2023)
> +NAMED_INTCST (ISOFORTRANENV_LOGICAL32, "logical32", \
> +              gfc_get_int_kind_from_width_isofortranenv (32), GFC_STD_F2023)
> +NAMED_INTCST (ISOFORTRANENV_LOGICAL64, "logical64", \
> +              gfc_get_int_kind_from_width_isofortranenv (64), GFC_STD_F2023)
> +NAMED_INTCST (ISOFORTRANENV_REAL16, "real16", \
> +              gfc_get_real_kind_from_width_isofortranenv (16), GFC_STD_F2023)
> +
> +NAMED_UINTCST (ISOFORTRANENV_UINT8, "uint8", \
> +              gfc_get_uint_kind_from_width_isofortranenv (8), GFC_STD_UNSIGNED)
> +NAMED_UINTCST (ISOFORTRANENV_UINT16, "uint16", \
> +              gfc_get_uint_kind_from_width_isofortranenv (16), GFC_STD_UNSIGNED)
> +NAMED_UINTCST (ISOFORTRANENV_UINT32, "uint32", \
> +              gfc_get_uint_kind_from_width_isofortranenv (32), GFC_STD_UNSIGNED)
> +NAMED_UINTCST (ISOFORTRANENV_UINT64, "uint64", \
> +              gfc_get_uint_kind_from_width_isofortranenv (64), GFC_STD_UNSIGNED)
> +
>  #undef NAMED_INTCST
>  #undef NAMED_UINTCST
>  #undef NAMED_KINDARRAY
>
>         Jakub
>
  
Jakub Jelinek Jan. 8, 2025, 9:53 a.m. UTC | #2
On Wed, Jan 08, 2025 at 10:47:39AM +0100, Richard Biener wrote:
> I wonder if we can somehow add some test coverage?  Are .mod files
> target independent and thus can we include them in the testsuite?

They are, but they are compressed and having binary data in the testsuite
is a problem.  But perhaps we could have there some *.moduncompressed
files (text files) and compress them before use.

Though, we'd need to first deal with the incompatibilities I wrote about
if it is possible at all.

	Jakub
  
Andre Vehreschild Jan. 8, 2025, 10:34 a.m. UTC | #3
Hi Jakub,

marking the vtypes as recursive is odd, but should not be taken as any
incompatibility marker. Pre version 15 gfortran does not check the recursive
attr on types. So whether it is set or not, is of no concern to gfortran <= 14.
The pr that motivated the change
is: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116669

The flag is used now to indicate, that a type can (indirectly) reference
itself. Not having the marker lead to endless recursion during construction of
copy or deallocate operations on an object of the type.

About the other changes I can say nothing.

Besides that, your WIP patch looks good to me.

Regards,
	Andre

On Wed, 8 Jan 2025 10:44:50 +0100
Jakub Jelinek <jakub@redhat.com> wrote:

> Hi!
>
> Based on the comments in the PR, I've tried to write a patch which would
> try to keep backwards compatibility with the GCC 11-14 *.mod files.
>
> Testcase was
> module a
>   use, intrinsic :: iso_c_binding
> end module a
> module b
>   use, intrinsic :: iso_fortran_env
> end module b
> and zcat a.mod; zcat b.mod
> Without this patch there are changes all around in the numbers
> because various new entries have been added in the middle.
> With this patch, there are still some changes:
> 1) __vtype___iso_c_binding_C_funptr and
>    __vtype___iso_c_binding_C_ptr have added RECURSIVE in GCC 15 compared to
>    14
> 2) __copy___iso_c_binding_C_funptr used to be 94 and now is 98,
>    __copy___iso_c_binding_C_ptr 97 -> 101 and src/dst also changed
> 3) __vtype_iso_fortran_env_Event_type and __vtype_iso_fortran_env_Lock_type
>    and __vtype_iso_fortran_env_Team_type also have RECURSIVE added
> 4) logical_kinds 59 -> 63, numeric_storage_size 60 -> 64, etc.
> So, I really don't know if it is feasible to ensure backwards compatibility.
>
> Plus how we would actually test whether we are able to accept the older
> modules in newer compilers.
>
> 2025-01-08  Jakub Jelinek  <jakub@redhat.com>
>
> 	PR fortran/118337
> 	* module.cc (COMPAT_MOD_VERSIONS): Define.
> 	(gfc_use_module): Accept also COMPAT_MOD_VERSIONS for compatibility.
> 	* iso-c-binding.def: Reorder entries so that the GCC 14 ones come
> 	before the ones new in GCC 15.
> 	* iso-fortran-env.def: Likewise.
>
> --- gcc/fortran/module.cc.jj	2025-01-08 10:05:39.308786981 +0100
> +++ gcc/fortran/module.cc	2025-01-08 10:18:14.234222227 +0100
> @@ -85,6 +85,8 @@ along with GCC; see the file COPYING3.
>  /* Don't put any single quote (') in MOD_VERSION, if you want it to be
>     recognized.  */
>  #define MOD_VERSION "16"
> +/* Older mod versions we can still parse.  */
> +#define COMPAT_MOD_VERSIONS { "15" }
>
>
>  /* Structure that describes a position within a module file.  */
> @@ -7451,10 +7453,23 @@ gfc_use_module (gfc_use_list *module)
>  			 " module file", module_fullpath);
>        if (start == 3)
>  	{
> +	  bool fatal = false;
>  	  if (strcmp (atom_name, " version") != 0
>  	      || module_char () != ' '
> -	      || parse_atom () != ATOM_STRING
> -	      || strcmp (atom_string, MOD_VERSION))
> +	      || parse_atom () != ATOM_STRING)
> +	    fatal = true;
> +	  else if (strcmp (atom_string, MOD_VERSION))
> +	    {
> +	      static const char *compat_mod_versions[] = COMPAT_MOD_VERSIONS;
> +	      fatal = true;
> +	      for (unsigned i = 0; i < ARRAY_SIZE (compat_mod_versions); ++i)
> +		if (!strcmp (atom_string, compat_mod_versions[i]))
> +		  {
> +		    fatal = false;
> +		    break;
> +		  }
> +	    }
> +	  if (fatal)
>  	    gfc_fatal_error ("Cannot read module file %qs opened at %C,"
>  			     " because it was created by a different"
>  			     " version of GNU Fortran", module_fullpath);
> --- gcc/fortran/iso-c-binding.def.jj	2025-01-02 11:47:31.894198887
> +0100 +++ gcc/fortran/iso-c-binding.def	2025-01-08 10:09:12.454799919
> +0100 @@ -17,7 +17,8 @@ along with GCC; see the file COPYING3.
>  <http://www.gnu.org/licenses/>.  */
>
>  /* This file contains the definition of the types provided by the
> -   Fortran 2003 ISO_C_BINDING intrinsic module.  */
> +   Fortran 2003 ISO_C_BINDING intrinsic module.  The ordering of
> +   the entries matters for the *.mod backwards compatibility.  */
>
>  #ifndef NAMED_INTCST
>  # define NAMED_INTCST(a,b,c,d)
> @@ -112,62 +113,6 @@ NAMED_INTCST (ISOCBINDING_INT_FAST64_T,
>  NAMED_INTCST (ISOCBINDING_INT_FAST128_T, "c_int_fast128_t",
>  	      get_int_kind_from_width (128), GFC_STD_GNU)
>
> -/* UNSIGNED.  */
> -NAMED_UINTCST (ISOCBINDING_UINT, "c_unsigned", gfc_c_uint_kind, \
> -	       GFC_STD_UNSIGNED)
> -NAMED_UINTCST (ISOCBINDING_USHORT, "c_unsigned_short", \
> -	       get_unsigned_kind_from_node (short_unsigned_type_node), \
> -	       GFC_STD_UNSIGNED)
> -NAMED_UINTCST (ISOCBINDING_UCHAR, "c_unsigned_char", \
> -	       get_unsigned_kind_from_node (unsigned_char_type_node), \
> -	       GFC_STD_UNSIGNED)
> -NAMED_UINTCST (ISOCBINDING_ULONG, "c_unsigned_long", \
> -	       get_unsigned_kind_from_node (long_unsigned_type_node), \
> -	       GFC_STD_UNSIGNED)
> -NAMED_UINTCST (ISOCBINDING_ULONGLONG, "c_unsigned_long_long", \
> -	       get_unsigned_kind_from_node (long_long_unsigned_type_node), \
> -	       GFC_STD_UNSIGNED)
> -NAMED_UINTCST (ISOCBINDING_UINTMAX_T, "c_uintmax_t", \
> -	       get_uint_kind_from_name (UINTMAX_TYPE), GFC_STD_UNSIGNED)
> -NAMED_UINTCST (ISOCBINDING_UINT8_T, "c_uint8_t", \
> -	       get_uint_kind_from_name (UINT8_TYPE), GFC_STD_UNSIGNED)
> -NAMED_UINTCST (ISOCBINDING_UINT16_T, "c_uint16_t", \
> -	       get_uint_kind_from_name (UINT16_TYPE), GFC_STD_UNSIGNED)
> -NAMED_UINTCST (ISOCBINDING_UINT32_T, "c_uint32_t", \
> -	       get_uint_kind_from_name (UINT32_TYPE), GFC_STD_UNSIGNED)
> -NAMED_UINTCST (ISOCBINDING_UINT64_T, "c_uint64_t", \
> -	       get_uint_kind_from_name (UINT64_TYPE), GFC_STD_UNSIGNED)
> -NAMED_UINTCST (ISOCBINDING_UINT128_T, "c_uint128_t", \
> -	       get_uint_kind_from_width (128), GFC_STD_UNSIGNED)
> -NAMED_UINTCST (ISOCBINDING_UINT_LEAST8_T, "c_uint_least8_t", \
> -	       get_uint_kind_from_name (UINT_LEAST8_TYPE), \
> -	       GFC_STD_UNSIGNED)
> -NAMED_UINTCST (ISOCBINDING_UINT_LEAST16_T, "c_uint_least16_t", \
> -	       get_uint_kind_from_name (UINT_LEAST16_TYPE), \
> -	       GFC_STD_UNSIGNED)
> -NAMED_UINTCST (ISOCBINDING_UINT_LEAST32_T, "c_uint_least32_t", \
> -	       get_uint_kind_from_name (UINT_LEAST32_TYPE),\
> -	       GFC_STD_UNSIGNED)
> -NAMED_UINTCST (ISOCBINDING_UINT_LEAST64_T, "c_uint_least64_t", \
> -	       get_uint_kind_from_name (UINT_LEAST64_TYPE),\
> -	       GFC_STD_UNSIGNED)
> -NAMED_UINTCST (ISOCBINDING_UINT_LEAST128_T, "c_uint_least128_t", \
> -	       get_uint_kind_from_width (128), GFC_STD_UNSIGNED)
> -NAMED_UINTCST (ISOCBINDING_UINT_FAST8_T, "c_uint_fast8_t", \
> -	       get_uint_kind_from_name (UINT_FAST8_TYPE), \
> -	       GFC_STD_UNSIGNED)
> -NAMED_UINTCST (ISOCBINDING_UINT_FAST16_T, "c_uint_fast16_t", \
> -	       get_uint_kind_from_name (UINT_FAST16_TYPE), \
> -	       GFC_STD_UNSIGNED)
> -NAMED_UINTCST (ISOCBINDING_UINT_FAST32_T, "c_uint_fast32_t", \
> -	       get_uint_kind_from_name (UINT_FAST32_TYPE),\
> -	       GFC_STD_UNSIGNED)
> -NAMED_UINTCST (ISOCBINDING_UINT_FAST64_T, "c_uint_fast64_t", \
> -	       get_uint_kind_from_name (UINT_FAST64_TYPE),\
> -	       GFC_STD_UNSIGNED)
> -NAMED_UINTCST (ISOCBINDING_UINT_FAST128_T, "c_uint_fast128_t", \
> -	       get_uint_kind_from_width (128), GFC_STD_UNSIGNED)
> -
>  NAMED_REALCST (ISOCBINDING_FLOAT, "c_float", \
>                 get_real_kind_from_node (float_type_node), GFC_STD_F2003)
>  NAMED_REALCST (ISOCBINDING_DOUBLE, "c_double", \
> @@ -259,6 +204,62 @@ NAMED_FUNCTION (ISOCBINDING_C_SIZEOF, "c
>  NAMED_FUNCTION (ISOCBINDING_F_C_STRING, "f_c_string", \
>                  GFC_ISYM_F_C_STRING, GFC_STD_F2023)
>
> +/* UNSIGNED.  */
> +NAMED_UINTCST (ISOCBINDING_UINT, "c_unsigned", gfc_c_uint_kind, \
> +	       GFC_STD_UNSIGNED)
> +NAMED_UINTCST (ISOCBINDING_USHORT, "c_unsigned_short", \
> +	       get_unsigned_kind_from_node (short_unsigned_type_node), \
> +	       GFC_STD_UNSIGNED)
> +NAMED_UINTCST (ISOCBINDING_UCHAR, "c_unsigned_char", \
> +	       get_unsigned_kind_from_node (unsigned_char_type_node), \
> +	       GFC_STD_UNSIGNED)
> +NAMED_UINTCST (ISOCBINDING_ULONG, "c_unsigned_long", \
> +	       get_unsigned_kind_from_node (long_unsigned_type_node), \
> +	       GFC_STD_UNSIGNED)
> +NAMED_UINTCST (ISOCBINDING_ULONGLONG, "c_unsigned_long_long", \
> +	       get_unsigned_kind_from_node (long_long_unsigned_type_node), \
> +	       GFC_STD_UNSIGNED)
> +NAMED_UINTCST (ISOCBINDING_UINTMAX_T, "c_uintmax_t", \
> +	       get_uint_kind_from_name (UINTMAX_TYPE), GFC_STD_UNSIGNED)
> +NAMED_UINTCST (ISOCBINDING_UINT8_T, "c_uint8_t", \
> +	       get_uint_kind_from_name (UINT8_TYPE), GFC_STD_UNSIGNED)
> +NAMED_UINTCST (ISOCBINDING_UINT16_T, "c_uint16_t", \
> +	       get_uint_kind_from_name (UINT16_TYPE), GFC_STD_UNSIGNED)
> +NAMED_UINTCST (ISOCBINDING_UINT32_T, "c_uint32_t", \
> +	       get_uint_kind_from_name (UINT32_TYPE), GFC_STD_UNSIGNED)
> +NAMED_UINTCST (ISOCBINDING_UINT64_T, "c_uint64_t", \
> +	       get_uint_kind_from_name (UINT64_TYPE), GFC_STD_UNSIGNED)
> +NAMED_UINTCST (ISOCBINDING_UINT128_T, "c_uint128_t", \
> +	       get_uint_kind_from_width (128), GFC_STD_UNSIGNED)
> +NAMED_UINTCST (ISOCBINDING_UINT_LEAST8_T, "c_uint_least8_t", \
> +	       get_uint_kind_from_name (UINT_LEAST8_TYPE), \
> +	       GFC_STD_UNSIGNED)
> +NAMED_UINTCST (ISOCBINDING_UINT_LEAST16_T, "c_uint_least16_t", \
> +	       get_uint_kind_from_name (UINT_LEAST16_TYPE), \
> +	       GFC_STD_UNSIGNED)
> +NAMED_UINTCST (ISOCBINDING_UINT_LEAST32_T, "c_uint_least32_t", \
> +	       get_uint_kind_from_name (UINT_LEAST32_TYPE),\
> +	       GFC_STD_UNSIGNED)
> +NAMED_UINTCST (ISOCBINDING_UINT_LEAST64_T, "c_uint_least64_t", \
> +	       get_uint_kind_from_name (UINT_LEAST64_TYPE),\
> +	       GFC_STD_UNSIGNED)
> +NAMED_UINTCST (ISOCBINDING_UINT_LEAST128_T, "c_uint_least128_t", \
> +	       get_uint_kind_from_width (128), GFC_STD_UNSIGNED)
> +NAMED_UINTCST (ISOCBINDING_UINT_FAST8_T, "c_uint_fast8_t", \
> +	       get_uint_kind_from_name (UINT_FAST8_TYPE), \
> +	       GFC_STD_UNSIGNED)
> +NAMED_UINTCST (ISOCBINDING_UINT_FAST16_T, "c_uint_fast16_t", \
> +	       get_uint_kind_from_name (UINT_FAST16_TYPE), \
> +	       GFC_STD_UNSIGNED)
> +NAMED_UINTCST (ISOCBINDING_UINT_FAST32_T, "c_uint_fast32_t", \
> +	       get_uint_kind_from_name (UINT_FAST32_TYPE),\
> +	       GFC_STD_UNSIGNED)
> +NAMED_UINTCST (ISOCBINDING_UINT_FAST64_T, "c_uint_fast64_t", \
> +	       get_uint_kind_from_name (UINT_FAST64_TYPE),\
> +	       GFC_STD_UNSIGNED)
> +NAMED_UINTCST (ISOCBINDING_UINT_FAST128_T, "c_uint_fast128_t", \
> +	       get_uint_kind_from_width (128), GFC_STD_UNSIGNED)
> +
>  #undef NAMED_INTCST
>  #undef NAMED_UINTCST
>  #undef NAMED_REALCST
> --- gcc/fortran/iso-fortran-env.def.jj	2025-01-02 11:47:32.137195494
> +0100 +++ gcc/fortran/iso-fortran-env.def	2025-01-08
> 10:11:44.946667057 +0100 @@ -17,7 +17,8 @@ along with GCC; see the file
> COPYING3. <http://www.gnu.org/licenses/>.  */
>
>  /* This file contains the definition of the named integer constants provided
> -   by the Fortran 2003 ISO_FORTRAN_ENV intrinsic module.  */
> +   by the Fortran 2003 ISO_FORTRAN_ENV intrinsic module.  The ordering of
> +   the entries matters for the *.mod backwards compatibility.  */
>
>  #ifndef NAMED_INTCST
>  # define NAMED_INTCST(a,b,c,d)
> @@ -72,20 +73,10 @@ NAMED_INTCST (ISOFORTRANENV_IOSTAT_EOR,
>  NAMED_INTCST (ISOFORTRANENV_IOSTAT_INQUIRE_INTERNAL_UNIT, \
>                "iostat_inquire_internal_unit",
> LIBERROR_INQUIRE_INTERNAL_UNIT, \ GFC_STD_F2008)
> -NAMED_INTCST (ISOFORTRANENV_LOGICAL8, "logical8", \
> -              gfc_get_int_kind_from_width_isofortranenv (8), GFC_STD_F2023)
> -NAMED_INTCST (ISOFORTRANENV_LOGICAL16, "logical16", \
> -              gfc_get_int_kind_from_width_isofortranenv (16), GFC_STD_F2023)
> -NAMED_INTCST (ISOFORTRANENV_LOGICAL32, "logical32", \
> -              gfc_get_int_kind_from_width_isofortranenv (32), GFC_STD_F2023)
> -NAMED_INTCST (ISOFORTRANENV_LOGICAL64, "logical64", \
> -              gfc_get_int_kind_from_width_isofortranenv (64), GFC_STD_F2023)
>  NAMED_INTCST (ISOFORTRANENV_NUMERIC_STORAGE_SIZE, "numeric_storage_size", \
>                gfc_numeric_storage_size, GFC_STD_F2003)
>  NAMED_INTCST (ISOFORTRANENV_OUTPUT_UNIT, "output_unit",
> GFC_STDOUT_UNIT_NUMBER, \ GFC_STD_F2003)
> -NAMED_INTCST (ISOFORTRANENV_REAL16, "real16", \
> -              gfc_get_real_kind_from_width_isofortranenv (16), GFC_STD_F2023)
>  NAMED_INTCST (ISOFORTRANENV_REAL32, "real32", \
>                gfc_get_real_kind_from_width_isofortranenv (32), GFC_STD_F2008)
>  NAMED_INTCST (ISOFORTRANENV_REAL64, "real64", \
> @@ -103,14 +94,7 @@ NAMED_INTCST (ISOFORTRANENV_FILE_STAT_FA
>                GFC_STAT_FAILED_IMAGE, GFC_STD_F2018)
>  NAMED_INTCST (ISOFORTRANENV_FILE_STAT_UNLOCKED, "stat_unlocked", \
>                GFC_STAT_UNLOCKED, GFC_STD_F2008)
> -NAMED_UINTCST (ISOFORTRANENV_UINT8, "uint8", \
> -	       gfc_get_uint_kind_from_width_isofortranenv (8),
> GFC_STD_UNSIGNED) -NAMED_UINTCST (ISOFORTRANENV_UINT16, "uint16", \
> -	       gfc_get_uint_kind_from_width_isofortranenv (16),
> GFC_STD_UNSIGNED) -NAMED_UINTCST (ISOFORTRANENV_UINT32, "uint32", \
> -	       gfc_get_uint_kind_from_width_isofortranenv (32),
> GFC_STD_UNSIGNED) -NAMED_UINTCST (ISOFORTRANENV_UINT64, "uint64", \
> -	       gfc_get_uint_kind_from_width_isofortranenv (64),
> GFC_STD_UNSIGNED) +
>
>  /* The arguments to NAMED_KINDARRAY are:
>       -- an internal name
> @@ -154,6 +138,26 @@ NAMED_DERIVED_TYPE (ISOFORTRAN_TEAM_TYPE
>  		    ? get_int_kind_from_node (ptr_type_node)
>  		    : gfc_default_integer_kind, GFC_STD_F2018)
>
> +NAMED_INTCST (ISOFORTRANENV_LOGICAL8, "logical8", \
> +              gfc_get_int_kind_from_width_isofortranenv (8), GFC_STD_F2023)
> +NAMED_INTCST (ISOFORTRANENV_LOGICAL16, "logical16", \
> +              gfc_get_int_kind_from_width_isofortranenv (16), GFC_STD_F2023)
> +NAMED_INTCST (ISOFORTRANENV_LOGICAL32, "logical32", \
> +              gfc_get_int_kind_from_width_isofortranenv (32), GFC_STD_F2023)
> +NAMED_INTCST (ISOFORTRANENV_LOGICAL64, "logical64", \
> +              gfc_get_int_kind_from_width_isofortranenv (64), GFC_STD_F2023)
> +NAMED_INTCST (ISOFORTRANENV_REAL16, "real16", \
> +              gfc_get_real_kind_from_width_isofortranenv (16), GFC_STD_F2023)
> +
> +NAMED_UINTCST (ISOFORTRANENV_UINT8, "uint8", \
> +	       gfc_get_uint_kind_from_width_isofortranenv (8),
> GFC_STD_UNSIGNED) +NAMED_UINTCST (ISOFORTRANENV_UINT16, "uint16", \
> +	       gfc_get_uint_kind_from_width_isofortranenv (16),
> GFC_STD_UNSIGNED) +NAMED_UINTCST (ISOFORTRANENV_UINT32, "uint32", \
> +	       gfc_get_uint_kind_from_width_isofortranenv (32),
> GFC_STD_UNSIGNED) +NAMED_UINTCST (ISOFORTRANENV_UINT64, "uint64", \
> +	       gfc_get_uint_kind_from_width_isofortranenv (64),
> GFC_STD_UNSIGNED) +
>  #undef NAMED_INTCST
>  #undef NAMED_UINTCST
>  #undef NAMED_KINDARRAY
>
> 	Jakub
>


--
Andre Vehreschild * Email: vehre ad gmx dot de
  
Jakub Jelinek Jan. 8, 2025, 10:42 a.m. UTC | #4
On Wed, Jan 08, 2025 at 11:34:35AM +0100, Andre Vehreschild wrote:
> marking the vtypes as recursive is odd, but should not be taken as any
> incompatibility marker. Pre version 15 gfortran does not check the recursive
> attr on types. So whether it is set or not, is of no concern to gfortran <= 14.
> The pr that motivated the change
> is: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116669

Thanks.

> The flag is used now to indicate, that a type can (indirectly) reference
> itself. Not having the marker lead to endless recursion during construction of
> copy or deallocate operations on an object of the type.
> 
> About the other changes I can say nothing.

The full list of changes with the posted patches is
(first a.mod, then b.mod, 14 -> 15) below.
I have no idea what adds those __copy_* elts etc. and whether they could be
forced to be in the middle rather than at the end and what is an ABI break
and what is not.

--- /tmp/1	2025-01-08 10:29:17.620943636 +0100
+++ /tmp/3	2025-01-08 10:24:17.139146386 +0100
@@ -1,4 +1,4 @@
-GFORTRAN module version '15' created from a.f90
+GFORTRAN module version '16' created from a.f90
 (() () () () () () () () () () () () () () () () () () () () () () () ()
 () () ())
 
@@ -38,10 +38,10 @@ DERIVED ()) 0 0 () () 0 () () () 0 0)
 UNKNOWN-PROC UNKNOWN IMPLICIT-SAVE 0 0 TARGET VTAB) () (DERIVED 12 0 0 0
 DERIVED ()) 0 0 () () 0 () () () 0 0)
 10 '__vtype___iso_c_binding_C_funptr' 'a' '' 1 ((DERIVED UNKNOWN-INTENT
-UNKNOWN-PROC UNKNOWN UNKNOWN 0 0 VTYPE) ((13 '_hash' (INTEGER 4 0 0 0
-INTEGER ()) () () () (UNKNOWN-FL UNKNOWN-INTENT UNKNOWN-PROC UNKNOWN
-UNKNOWN 0 0) PRIVATE (CONSTANT (INTEGER 4 0 0 0 INTEGER ()) 0 '0' ())) (
-14 '_size' (INTEGER 8 0 0 0 INTEGER ()) () () () (UNKNOWN-FL
+UNKNOWN-PROC UNKNOWN UNKNOWN 0 0 RECURSIVE VTYPE) ((13 '_hash' (INTEGER
+4 0 0 0 INTEGER ()) () () () (UNKNOWN-FL UNKNOWN-INTENT UNKNOWN-PROC
+UNKNOWN UNKNOWN 0 0) PRIVATE (CONSTANT (INTEGER 4 0 0 0 INTEGER ()) 0 '0'
+())) (14 '_size' (INTEGER 8 0 0 0 INTEGER ()) () () () (UNKNOWN-FL
 UNKNOWN-INTENT UNKNOWN-PROC UNKNOWN UNKNOWN 0 0) PRIVATE) (15 '_extends'
 (DERIVED 10 0 0 0 DERIVED ()) () () () (UNKNOWN-FL UNKNOWN-INTENT
 UNKNOWN-PROC UNKNOWN UNKNOWN 0 0 POINTER) PRIVATE) (16 '_def_init' (
@@ -59,10 +59,10 @@ UNKNOWN-PROC UNKNOWN UNKNOWN 0 0 SUBROUT
 UNKNOWN-ACCESS OVERRIDABLE PASS SPECIFIC PPC '' 0))) UNKNOWN-ACCESS (
 UNKNOWN 0 0 0 0 UNKNOWN ()) 0 0 () () 0 () () () 0 0 0)
 12 '__vtype___iso_c_binding_C_ptr' 'a' '' 1 ((DERIVED UNKNOWN-INTENT
-UNKNOWN-PROC UNKNOWN UNKNOWN 0 0 VTYPE) ((21 '_hash' (INTEGER 4 0 0 0
-INTEGER ()) () () () (UNKNOWN-FL UNKNOWN-INTENT UNKNOWN-PROC UNKNOWN
-UNKNOWN 0 0) PRIVATE (CONSTANT (INTEGER 4 0 0 0 INTEGER ()) 0 '0' ())) (
-22 '_size' (INTEGER 8 0 0 0 INTEGER ()) () () () (UNKNOWN-FL
+UNKNOWN-PROC UNKNOWN UNKNOWN 0 0 RECURSIVE VTYPE) ((21 '_hash' (INTEGER
+4 0 0 0 INTEGER ()) () () () (UNKNOWN-FL UNKNOWN-INTENT UNKNOWN-PROC
+UNKNOWN UNKNOWN 0 0) PRIVATE (CONSTANT (INTEGER 4 0 0 0 INTEGER ()) 0 '0'
+())) (22 '_size' (INTEGER 8 0 0 0 INTEGER ()) () () () (UNKNOWN-FL
 UNKNOWN-INTENT UNKNOWN-PROC UNKNOWN UNKNOWN 0 0) PRIVATE) (23 '_extends'
 (DERIVED 12 0 0 0 DERIVED ()) () () () (UNKNOWN-FL UNKNOWN-INTENT
 UNKNOWN-PROC UNKNOWN UNKNOWN 0 0 POINTER) PRIVATE) (24 '_def_init' (
@@ -295,13 +295,16 @@ UNKNOWN-PROC UNKNOWN UNKNOWN 0 0 IS_C_IN
 0 1 1 CHARACTER ((CONSTANT (INTEGER 8 0 0 0 INTEGER ()) 0 '1' ()))) 0 0
 () (CONSTANT (CHARACTER 1 0 1 1 UNKNOWN (())) 0 1 '\U0000000b' ()) () 0
 () () () 2 41)
-18 '__copy___iso_c_binding_C_funptr' 'a' '' 94 ((PROCEDURE
+94 'f_c_string' '__iso_c_binding' '' 1 ((PROCEDURE UNKNOWN-INTENT
+UNKNOWN-PROC DECL UNKNOWN 0 0 INTRINSIC FUNCTION PURE) () (CHARACTER 1 0
+0 0 CHARACTER ()) 95 0 (96 97) () 0 () () () 2 52)
+18 '__copy___iso_c_binding_C_funptr' 'a' '' 98 ((PROCEDURE
 UNKNOWN-INTENT UNKNOWN-PROC DECL UNKNOWN 0 0 ARTIFICIAL SUBROUTINE
-ELEMENTAL PURE ALWAYS_EXPLICIT) () (UNKNOWN 0 0 0 0 UNKNOWN ()) 0 0 (95
-96) () 0 () () () 0 0)
-26 '__copy___iso_c_binding_C_ptr' 'a' '' 97 ((PROCEDURE UNKNOWN-INTENT
+ELEMENTAL PURE ALWAYS_EXPLICIT) () (UNKNOWN 0 0 0 0 UNKNOWN ()) 0 0 (99
+100) () 0 () () () 0 0)
+26 '__copy___iso_c_binding_C_ptr' 'a' '' 101 ((PROCEDURE UNKNOWN-INTENT
 UNKNOWN-PROC DECL UNKNOWN 0 0 ARTIFICIAL SUBROUTINE ELEMENTAL PURE
-ALWAYS_EXPLICIT) () (UNKNOWN 0 0 0 0 UNKNOWN ()) 0 0 (98 99) () 0 () ()
+ALWAYS_EXPLICIT) () (UNKNOWN 0 0 0 0 UNKNOWN ()) 0 0 (102 103) () 0 () ()
 () 0 0)
 33 'c_ptr_1' '' '' 32 ((VARIABLE IN UNKNOWN-PROC UNKNOWN UNKNOWN 0 0
 DUMMY) () (VOID 0 0 0 0 VOID ()) 0 0 () () 0 () () () 0 0)
@@ -319,16 +322,21 @@ OPTIONAL DUMMY) () (INTEGER 4 0 0 0 INTE
 () (UNKNOWN 0 0 0 0 UNKNOWN ()) 0 0 () () 0 () () () 0 0)
 92 'x' '' '' 91 ((VARIABLE IN UNKNOWN-PROC UNKNOWN UNKNOWN 0 0 DUMMY) ()
 (UNKNOWN 0 0 0 0 UNKNOWN ()) 0 0 () () 0 () () () 0 0)
-95 'src' '' '' 94 ((VARIABLE IN UNKNOWN-PROC UNKNOWN UNKNOWN 0 0
+96 'string' '' '' 95 ((VARIABLE IN UNKNOWN-PROC UNKNOWN UNKNOWN 0 0
+DUMMY) () (CHARACTER 1 0 0 0 CHARACTER (())) 0 0 () () 0 () () () 0 0)
+97 'asis' '' '' 95 ((VARIABLE IN UNKNOWN-PROC UNKNOWN UNKNOWN 0 0
+OPTIONAL DUMMY) () (CHARACTER 1 0 0 0 CHARACTER (())) 0 0 () () 0 () ()
+() 0 0)
+99 'src' '' '' 98 ((VARIABLE IN UNKNOWN-PROC UNKNOWN UNKNOWN 0 0
 ARTIFICIAL DUMMY) () (DERIVED 2 0 0 0 DERIVED ()) 0 0 () () 0 () () () 0
 0)
-96 'dst' '' '' 94 ((VARIABLE INOUT UNKNOWN-PROC UNKNOWN UNKNOWN 0 0
+100 'dst' '' '' 98 ((VARIABLE INOUT UNKNOWN-PROC UNKNOWN UNKNOWN 0 0
 ARTIFICIAL DUMMY) () (DERIVED 2 0 0 0 DERIVED ()) 0 0 () () 0 () () () 0
 0)
-98 'src' '' '' 97 ((VARIABLE IN UNKNOWN-PROC UNKNOWN UNKNOWN 0 0
+102 'src' '' '' 101 ((VARIABLE IN UNKNOWN-PROC UNKNOWN UNKNOWN 0 0
 ARTIFICIAL DUMMY) () (DERIVED 3 0 0 0 DERIVED ()) 0 0 () () 0 () () () 0
 0)
-99 'dst' '' '' 97 ((VARIABLE INOUT UNKNOWN-PROC UNKNOWN UNKNOWN 0 0
+103 'dst' '' '' 101 ((VARIABLE INOUT UNKNOWN-PROC UNKNOWN UNKNOWN 0 0
 ARTIFICIAL DUMMY) () (DERIVED 3 0 0 0 DERIVED ()) 0 0 () () 0 () () () 0
 0)
 )
@@ -351,4 +359,4 @@ ARTIFICIAL DUMMY) () (DERIVED 3 0 0 0 DE
 'c_long_double' 0 78 'c_long_double_complex' 0 79 'c_long_long' 0 80
 'c_new_line' 0 81 'c_null_char' 0 82 'c_null_funptr' 0 83 'c_null_ptr' 0
 84 'c_ptr' 0 85 'c_ptrdiff_t' 0 86 'c_short' 0 87 'c_signed_char' 0 88
-'c_size_t' 0 89 'c_sizeof' 0 90 'c_vertical_tab' 0 93)
+'c_size_t' 0 89 'c_sizeof' 0 90 'c_vertical_tab' 0 93 'f_c_string' 0 94)
--- /tmp/2	2025-01-08 10:23:51.237508661 +0100
+++ /tmp/4	2025-01-08 10:24:14.930177279 +0100
@@ -1,4 +1,4 @@
-GFORTRAN module version '15' created from a.f90
+GFORTRAN module version '16' created from a.f90
 (() () () () () () () () () () () () () () () () () () () () () () () ()
 () () ())
 
@@ -41,10 +41,10 @@ DERIVED ()) 0 0 () () 0 () () () 0 0)
 UNKNOWN-PROC UNKNOWN IMPLICIT-SAVE 0 0 TARGET VTAB) () (DERIVED 13 0 0 0
 DERIVED ()) 0 0 () () 0 () () () 0 0)
 9 '__vtype_iso_fortran_env_Event_type' 'b' '' 1 ((DERIVED UNKNOWN-INTENT
-UNKNOWN-PROC UNKNOWN UNKNOWN 0 0 VTYPE) ((14 '_hash' (INTEGER 4 0 0 0
-INTEGER ()) () () () (UNKNOWN-FL UNKNOWN-INTENT UNKNOWN-PROC UNKNOWN
-UNKNOWN 0 0) PRIVATE (CONSTANT (INTEGER 4 0 0 0 INTEGER ()) 0 '0' ())) (
-15 '_size' (INTEGER 8 0 0 0 INTEGER ()) () () () (UNKNOWN-FL
+UNKNOWN-PROC UNKNOWN UNKNOWN 0 0 RECURSIVE VTYPE) ((14 '_hash' (INTEGER
+4 0 0 0 INTEGER ()) () () () (UNKNOWN-FL UNKNOWN-INTENT UNKNOWN-PROC
+UNKNOWN UNKNOWN 0 0) PRIVATE (CONSTANT (INTEGER 4 0 0 0 INTEGER ()) 0 '0'
+())) (15 '_size' (INTEGER 8 0 0 0 INTEGER ()) () () () (UNKNOWN-FL
 UNKNOWN-INTENT UNKNOWN-PROC UNKNOWN UNKNOWN 0 0) PRIVATE) (16 '_extends'
 (DERIVED 9 0 0 0 DERIVED ()) () () () (UNKNOWN-FL UNKNOWN-INTENT
 UNKNOWN-PROC UNKNOWN UNKNOWN 0 0 POINTER) PRIVATE) (17 '_def_init' (
@@ -62,10 +62,10 @@ UNKNOWN-PROC UNKNOWN UNKNOWN 0 0 SUBROUT
 UNKNOWN-ACCESS OVERRIDABLE PASS SPECIFIC PPC '' 0))) UNKNOWN-ACCESS (
 UNKNOWN 0 0 0 0 UNKNOWN ()) 0 0 () () 0 () () () 0 0 0)
 11 '__vtype_iso_fortran_env_Lock_type' 'b' '' 1 ((DERIVED UNKNOWN-INTENT
-UNKNOWN-PROC UNKNOWN UNKNOWN 0 0 VTYPE) ((22 '_hash' (INTEGER 4 0 0 0
-INTEGER ()) () () () (UNKNOWN-FL UNKNOWN-INTENT UNKNOWN-PROC UNKNOWN
-UNKNOWN 0 0) PRIVATE (CONSTANT (INTEGER 4 0 0 0 INTEGER ()) 0 '0' ())) (
-23 '_size' (INTEGER 8 0 0 0 INTEGER ()) () () () (UNKNOWN-FL
+UNKNOWN-PROC UNKNOWN UNKNOWN 0 0 RECURSIVE VTYPE) ((22 '_hash' (INTEGER
+4 0 0 0 INTEGER ()) () () () (UNKNOWN-FL UNKNOWN-INTENT UNKNOWN-PROC
+UNKNOWN UNKNOWN 0 0) PRIVATE (CONSTANT (INTEGER 4 0 0 0 INTEGER ()) 0 '0'
+())) (23 '_size' (INTEGER 8 0 0 0 INTEGER ()) () () () (UNKNOWN-FL
 UNKNOWN-INTENT UNKNOWN-PROC UNKNOWN UNKNOWN 0 0) PRIVATE) (24 '_extends'
 (DERIVED 11 0 0 0 DERIVED ()) () () () (UNKNOWN-FL UNKNOWN-INTENT
 UNKNOWN-PROC UNKNOWN UNKNOWN 0 0 POINTER) PRIVATE) (25 '_def_init' (
@@ -83,10 +83,10 @@ UNKNOWN-PROC UNKNOWN UNKNOWN 0 0 SUBROUT
 UNKNOWN-ACCESS OVERRIDABLE PASS SPECIFIC PPC '' 0))) UNKNOWN-ACCESS (
 UNKNOWN 0 0 0 0 UNKNOWN ()) 0 0 () () 0 () () () 0 0 0)
 13 '__vtype_iso_fortran_env_Team_type' 'b' '' 1 ((DERIVED UNKNOWN-INTENT
-UNKNOWN-PROC UNKNOWN UNKNOWN 0 0 VTYPE) ((30 '_hash' (INTEGER 4 0 0 0
-INTEGER ()) () () () (UNKNOWN-FL UNKNOWN-INTENT UNKNOWN-PROC UNKNOWN
-UNKNOWN 0 0) PRIVATE (CONSTANT (INTEGER 4 0 0 0 INTEGER ()) 0 '0' ())) (
-31 '_size' (INTEGER 8 0 0 0 INTEGER ()) () () () (UNKNOWN-FL
+UNKNOWN-PROC UNKNOWN UNKNOWN 0 0 RECURSIVE VTYPE) ((30 '_hash' (INTEGER
+4 0 0 0 INTEGER ()) () () () (UNKNOWN-FL UNKNOWN-INTENT UNKNOWN-PROC
+UNKNOWN UNKNOWN 0 0) PRIVATE (CONSTANT (INTEGER 4 0 0 0 INTEGER ()) 0 '0'
+())) (31 '_size' (INTEGER 8 0 0 0 INTEGER ()) () () () (UNKNOWN-FL
 UNKNOWN-INTENT UNKNOWN-PROC UNKNOWN UNKNOWN 0 0) PRIVATE) (32 '_extends'
 (DERIVED 13 0 0 0 DERIVED ()) () () () (UNKNOWN-FL UNKNOWN-INTENT
 UNKNOWN-PROC UNKNOWN UNKNOWN 0 0 POINTER) PRIVATE) (33 '_def_init' (
@@ -178,7 +178,19 @@ UNKNOWN-PROC UNKNOWN UNKNOWN 0 0 INTRINS
 58 'lock_type' 'iso_fortran_env' '' 1 ((PROCEDURE UNKNOWN-INTENT
 UNKNOWN-PROC DECL UNKNOWN 0 0 FUNCTION GENERIC) () (INTEGER 4 0 0 0
 INTEGER ()) 0 0 () () 0 () () () 1 29)
-59 'logical_kinds' 'iso_fortran_env' '' 1 ((PARAMETER UNKNOWN-INTENT
+59 'logical16' 'iso_fortran_env' '' 1 ((PARAMETER UNKNOWN-INTENT
+UNKNOWN-PROC UNKNOWN UNKNOWN 0 0) () (INTEGER 4 0 0 0 INTEGER ()) 0 0 ()
+(CONSTANT (INTEGER 4 0 0 0 INTEGER ()) 0 '0' ()) () 0 () () () 1 33)
+60 'logical32' 'iso_fortran_env' '' 1 ((PARAMETER UNKNOWN-INTENT
+UNKNOWN-PROC UNKNOWN UNKNOWN 0 0) () (INTEGER 4 0 0 0 INTEGER ()) 0 0 ()
+(CONSTANT (INTEGER 4 0 0 0 INTEGER ()) 0 '0' ()) () 0 () () () 1 34)
+61 'logical64' 'iso_fortran_env' '' 1 ((PARAMETER UNKNOWN-INTENT
+UNKNOWN-PROC UNKNOWN UNKNOWN 0 0) () (INTEGER 4 0 0 0 INTEGER ()) 0 0 ()
+(CONSTANT (INTEGER 4 0 0 0 INTEGER ()) 0 '0' ()) () 0 () () () 1 35)
+62 'logical8' 'iso_fortran_env' '' 1 ((PARAMETER UNKNOWN-INTENT
+UNKNOWN-PROC UNKNOWN UNKNOWN 0 0) () (INTEGER 4 0 0 0 INTEGER ()) 0 0 ()
+(CONSTANT (INTEGER 4 0 0 0 INTEGER ()) 0 '0' ()) () 0 () () () 1 32)
+63 'logical_kinds' 'iso_fortran_env' '' 1 ((PARAMETER UNKNOWN-INTENT
 UNKNOWN-PROC UNKNOWN UNKNOWN 0 0 DIMENSION) () (INTEGER 4 0 0 0 INTEGER
 ()) 0 0 () (ARRAY (INTEGER 4 0 0 0 INTEGER ()) 1 (((CONSTANT (INTEGER 4
 0 0 0 INTEGER ()) 0 '1' ()) ()) ((CONSTANT (INTEGER 4 0 0 0 INTEGER ())
@@ -187,23 +199,26 @@ CONSTANT (INTEGER 4 0 0 0 INTEGER ()) 0
 4 0 0 0 INTEGER ()) 0 '16' ()) ())) ('5') ()) (1 0 EXPLICIT (CONSTANT (
 INTEGER 4 0 0 0 INTEGER ()) 0 '1' ()) (CONSTANT (INTEGER 4 0 0 0 INTEGER
 ()) 0 '5' ())) 0 () () () 1 25)
-60 'numeric_storage_size' 'iso_fortran_env' '' 1 ((PARAMETER
+64 'numeric_storage_size' 'iso_fortran_env' '' 1 ((PARAMETER
 UNKNOWN-INTENT UNKNOWN-PROC UNKNOWN UNKNOWN 0 0) () (INTEGER 4 0 0 0
 INTEGER ()) 0 0 () (CONSTANT (INTEGER 4 0 0 0 INTEGER ()) 0 '32' ()) ()
 0 () () () 1 13)
-61 'output_unit' 'iso_fortran_env' '' 1 ((PARAMETER UNKNOWN-INTENT
+65 'output_unit' 'iso_fortran_env' '' 1 ((PARAMETER UNKNOWN-INTENT
 UNKNOWN-PROC UNKNOWN UNKNOWN 0 0) () (INTEGER 4 0 0 0 INTEGER ()) 0 0 ()
 (CONSTANT (INTEGER 4 0 0 0 INTEGER ()) 0 '6' ()) () 0 () () () 1 14)
-62 'real128' 'iso_fortran_env' '' 1 ((PARAMETER UNKNOWN-INTENT
+66 'real128' 'iso_fortran_env' '' 1 ((PARAMETER UNKNOWN-INTENT
 UNKNOWN-PROC UNKNOWN UNKNOWN 0 0) () (INTEGER 4 0 0 0 INTEGER ()) 0 0 ()
 (CONSTANT (INTEGER 4 0 0 0 INTEGER ()) 0 '16' ()) () 0 () () () 1 17)
-63 'real32' 'iso_fortran_env' '' 1 ((PARAMETER UNKNOWN-INTENT
+67 'real16' 'iso_fortran_env' '' 1 ((PARAMETER UNKNOWN-INTENT
+UNKNOWN-PROC UNKNOWN UNKNOWN 0 0) () (INTEGER 4 0 0 0 INTEGER ()) 0 0 ()
+(CONSTANT (INTEGER 4 0 0 0 INTEGER ()) 0 '0' ()) () 0 () () () 1 36)
+68 'real32' 'iso_fortran_env' '' 1 ((PARAMETER UNKNOWN-INTENT
 UNKNOWN-PROC UNKNOWN UNKNOWN 0 0) () (INTEGER 4 0 0 0 INTEGER ()) 0 0 ()
 (CONSTANT (INTEGER 4 0 0 0 INTEGER ()) 0 '4' ()) () 0 () () () 1 15)
-64 'real64' 'iso_fortran_env' '' 1 ((PARAMETER UNKNOWN-INTENT
+69 'real64' 'iso_fortran_env' '' 1 ((PARAMETER UNKNOWN-INTENT
 UNKNOWN-PROC UNKNOWN UNKNOWN 0 0) () (INTEGER 4 0 0 0 INTEGER ()) 0 0 ()
 (CONSTANT (INTEGER 4 0 0 0 INTEGER ()) 0 '8' ()) () 0 () () () 1 16)
-65 'real_kinds' 'iso_fortran_env' '' 1 ((PARAMETER UNKNOWN-INTENT
+70 'real_kinds' 'iso_fortran_env' '' 1 ((PARAMETER UNKNOWN-INTENT
 UNKNOWN-PROC UNKNOWN UNKNOWN 0 0 DIMENSION) () (INTEGER 4 0 0 0 INTEGER
 ()) 0 0 () (ARRAY (INTEGER 4 0 0 0 INTEGER ()) 1 (((CONSTANT (INTEGER 4
 0 0 0 INTEGER ()) 0 '4' ()) ()) ((CONSTANT (INTEGER 4 0 0 0 INTEGER ())
@@ -211,54 +226,54 @@ UNKNOWN-PROC UNKNOWN UNKNOWN 0 0 DIMENSI
 CONSTANT (INTEGER 4 0 0 0 INTEGER ()) 0 '16' ()) ())) ('4') ()) (1 0
 EXPLICIT (CONSTANT (INTEGER 4 0 0 0 INTEGER ()) 0 '1' ()) (CONSTANT (
 INTEGER 4 0 0 0 INTEGER ()) 0 '4' ())) 0 () () () 1 26)
-66 'stat_failed_image' 'iso_fortran_env' '' 1 ((PARAMETER UNKNOWN-INTENT
+71 'stat_failed_image' 'iso_fortran_env' '' 1 ((PARAMETER UNKNOWN-INTENT
 UNKNOWN-PROC UNKNOWN UNKNOWN 0 0) () (INTEGER 4 0 0 0 INTEGER ()) 0 0 ()
 (CONSTANT (INTEGER 4 0 0 0 INTEGER ()) 0 '6001' ()) () 0 () () () 1 21)
-67 'stat_locked' 'iso_fortran_env' '' 1 ((PARAMETER UNKNOWN-INTENT
+72 'stat_locked' 'iso_fortran_env' '' 1 ((PARAMETER UNKNOWN-INTENT
 UNKNOWN-PROC UNKNOWN UNKNOWN 0 0) () (INTEGER 4 0 0 0 INTEGER ()) 0 0 ()
 (CONSTANT (INTEGER 4 0 0 0 INTEGER ()) 0 '1' ()) () 0 () () () 1 18)
-68 'stat_locked_other_image' 'iso_fortran_env' '' 1 ((PARAMETER
+73 'stat_locked_other_image' 'iso_fortran_env' '' 1 ((PARAMETER
 UNKNOWN-INTENT UNKNOWN-PROC UNKNOWN UNKNOWN 0 0) () (INTEGER 4 0 0 0
 INTEGER ()) 0 0 () (CONSTANT (INTEGER 4 0 0 0 INTEGER ()) 0 '2' ()) () 0
 () () () 1 19)
-69 'stat_stopped_image' 'iso_fortran_env' '' 1 ((PARAMETER
+74 'stat_stopped_image' 'iso_fortran_env' '' 1 ((PARAMETER
 UNKNOWN-INTENT UNKNOWN-PROC UNKNOWN UNKNOWN 0 0) () (INTEGER 4 0 0 0
 INTEGER ()) 0 0 () (CONSTANT (INTEGER 4 0 0 0 INTEGER ()) 0 '6000' ()) ()
 0 () () () 1 20)
-70 'stat_unlocked' 'iso_fortran_env' '' 1 ((PARAMETER UNKNOWN-INTENT
+75 'stat_unlocked' 'iso_fortran_env' '' 1 ((PARAMETER UNKNOWN-INTENT
 UNKNOWN-PROC UNKNOWN UNKNOWN 0 0) () (INTEGER 4 0 0 0 INTEGER ()) 0 0 ()
 (CONSTANT (INTEGER 4 0 0 0 INTEGER ()) 0 '0' ()) () 0 () () () 1 22)
-71 'team_type' 'iso_fortran_env' '' 1 ((PROCEDURE UNKNOWN-INTENT
+76 'team_type' 'iso_fortran_env' '' 1 ((PROCEDURE UNKNOWN-INTENT
 UNKNOWN-PROC DECL UNKNOWN 0 0 FUNCTION GENERIC) () (REAL 4 0 0 0 REAL ())
 0 0 () () 0 () () () 1 31)
-19 '__copy_iso_fortran_env_Event_type' 'b' '' 72 ((PROCEDURE
+19 '__copy_iso_fortran_env_Event_type' 'b' '' 77 ((PROCEDURE
 UNKNOWN-INTENT UNKNOWN-PROC DECL UNKNOWN 0 0 ARTIFICIAL SUBROUTINE
-ELEMENTAL PURE ALWAYS_EXPLICIT) () (UNKNOWN 0 0 0 0 UNKNOWN ()) 0 0 (73
-74) () 0 () () () 0 0)
-27 '__copy_iso_fortran_env_Lock_type' 'b' '' 75 ((PROCEDURE
+ELEMENTAL PURE ALWAYS_EXPLICIT) () (UNKNOWN 0 0 0 0 UNKNOWN ()) 0 0 (78
+79) () 0 () () () 0 0)
+27 '__copy_iso_fortran_env_Lock_type' 'b' '' 80 ((PROCEDURE
 UNKNOWN-INTENT UNKNOWN-PROC DECL UNKNOWN 0 0 ARTIFICIAL SUBROUTINE
-ELEMENTAL PURE ALWAYS_EXPLICIT) () (UNKNOWN 0 0 0 0 UNKNOWN ()) 0 0 (76
-77) () 0 () () () 0 0)
-35 '__copy_iso_fortran_env_Team_type' 'b' '' 78 ((PROCEDURE
+ELEMENTAL PURE ALWAYS_EXPLICIT) () (UNKNOWN 0 0 0 0 UNKNOWN ()) 0 0 (81
+82) () 0 () () () 0 0)
+35 '__copy_iso_fortran_env_Team_type' 'b' '' 83 ((PROCEDURE
 UNKNOWN-INTENT UNKNOWN-PROC DECL UNKNOWN 0 0 ARTIFICIAL SUBROUTINE
-ELEMENTAL PURE ALWAYS_EXPLICIT) () (UNKNOWN 0 0 0 0 UNKNOWN ()) 0 0 (79
-80) () 0 () () () 0 0)
-73 'src' '' '' 72 ((VARIABLE IN UNKNOWN-PROC UNKNOWN UNKNOWN 0 0
+ELEMENTAL PURE ALWAYS_EXPLICIT) () (UNKNOWN 0 0 0 0 UNKNOWN ()) 0 0 (84
+85) () 0 () () () 0 0)
+78 'src' '' '' 77 ((VARIABLE IN UNKNOWN-PROC UNKNOWN UNKNOWN 0 0
 ARTIFICIAL DUMMY) () (DERIVED 2 0 0 0 DERIVED ()) 0 0 () () 0 () () () 0
 0)
-74 'dst' '' '' 72 ((VARIABLE INOUT UNKNOWN-PROC UNKNOWN UNKNOWN 0 0
+79 'dst' '' '' 77 ((VARIABLE INOUT UNKNOWN-PROC UNKNOWN UNKNOWN 0 0
 ARTIFICIAL DUMMY) () (DERIVED 2 0 0 0 DERIVED ()) 0 0 () () 0 () () () 0
 0)
-76 'src' '' '' 75 ((VARIABLE IN UNKNOWN-PROC UNKNOWN UNKNOWN 0 0
+81 'src' '' '' 80 ((VARIABLE IN UNKNOWN-PROC UNKNOWN UNKNOWN 0 0
 ARTIFICIAL DUMMY) () (DERIVED 3 0 0 0 DERIVED ()) 0 0 () () 0 () () () 0
 0)
-77 'dst' '' '' 75 ((VARIABLE INOUT UNKNOWN-PROC UNKNOWN UNKNOWN 0 0
+82 'dst' '' '' 80 ((VARIABLE INOUT UNKNOWN-PROC UNKNOWN UNKNOWN 0 0
 ARTIFICIAL DUMMY) () (DERIVED 3 0 0 0 DERIVED ()) 0 0 () () 0 () () () 0
 0)
-79 'src' '' '' 78 ((VARIABLE IN UNKNOWN-PROC UNKNOWN UNKNOWN 0 0
+84 'src' '' '' 83 ((VARIABLE IN UNKNOWN-PROC UNKNOWN UNKNOWN 0 0
 ARTIFICIAL DUMMY) () (DERIVED 4 0 0 0 DERIVED ()) 0 0 () () 0 () () () 0
 0)
-80 'dst' '' '' 78 ((VARIABLE INOUT UNKNOWN-PROC UNKNOWN UNKNOWN 0 0
+85 'dst' '' '' 83 ((VARIABLE INOUT UNKNOWN-PROC UNKNOWN UNKNOWN 0 0
 ARTIFICIAL DUMMY) () (DERIVED 4 0 0 0 DERIVED ()) 0 0 () () 0 () () () 0
 0)
 )
@@ -278,7 +293,8 @@ ARTIFICIAL DUMMY) () (DERIVED 4 0 0 0 DE
 'input_unit' 0 48 'int16' 0 49 'int32' 0 50 'int64' 0 51 'int8' 0 52
 'integer_kinds' 0 53 'iostat_end' 0 54 'iostat_eor' 0 55
 'iostat_inquire_internal_unit' 0 56 'iso_fortran_env' 0 57 'lock_type' 0
-58 'logical_kinds' 0 59 'numeric_storage_size' 0 60 'output_unit' 0 61
-'real128' 0 62 'real32' 0 63 'real64' 0 64 'real_kinds' 0 65
-'stat_failed_image' 0 66 'stat_locked' 0 67 'stat_locked_other_image' 0
-68 'stat_stopped_image' 0 69 'stat_unlocked' 0 70 'team_type' 0 71)
+58 'logical16' 0 59 'logical32' 0 60 'logical64' 0 61 'logical8' 0 62
+'logical_kinds' 0 63 'numeric_storage_size' 0 64 'output_unit' 0 65
+'real128' 0 66 'real16' 0 67 'real32' 0 68 'real64' 0 69 'real_kinds' 0
+70 'stat_failed_image' 0 71 'stat_locked' 0 72 'stat_locked_other_image'
+0 73 'stat_stopped_image' 0 74 'stat_unlocked' 0 75 'team_type' 0 76)


	Jakub
  
Andre Vehreschild Jan. 8, 2025, 10:53 a.m. UTC | #5
Well, thinking about it, it smells like a side-effect of the 116669 fix. A type
getting the recursive marker enforces the generation of the vtype for it. I
don't see yet, why the iso_c_binding_C_funptr should be marked as recursive. I
will investigate. How much time do I have?

- Andre

On Wed, 8 Jan 2025 11:42:28 +0100
Jakub Jelinek <jakub@redhat.com> wrote:

> On Wed, Jan 08, 2025 at 11:34:35AM +0100, Andre Vehreschild wrote:
> > marking the vtypes as recursive is odd, but should not be taken as any
> > incompatibility marker. Pre version 15 gfortran does not check the recursive
> > attr on types. So whether it is set or not, is of no concern to gfortran <=
> > 14. The pr that motivated the change
> > is: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116669
>
> Thanks.
>
> > The flag is used now to indicate, that a type can (indirectly) reference
> > itself. Not having the marker lead to endless recursion during construction
> > of copy or deallocate operations on an object of the type.
> >
> > About the other changes I can say nothing.
>
> The full list of changes with the posted patches is
> (first a.mod, then b.mod, 14 -> 15) below.
> I have no idea what adds those __copy_* elts etc. and whether they could be
> forced to be in the middle rather than at the end and what is an ABI break
> and what is not.
>
> --- /tmp/1	2025-01-08 10:29:17.620943636 +0100
> +++ /tmp/3	2025-01-08 10:24:17.139146386 +0100
> @@ -1,4 +1,4 @@
> -GFORTRAN module version '15' created from a.f90
> +GFORTRAN module version '16' created from a.f90
>  (() () () () () () () () () () () () () () () () () () () () () () () ()
>  () () ())
>
> @@ -38,10 +38,10 @@ DERIVED ()) 0 0 () () 0 () () () 0 0)
>  UNKNOWN-PROC UNKNOWN IMPLICIT-SAVE 0 0 TARGET VTAB) () (DERIVED 12 0 0 0
>  DERIVED ()) 0 0 () () 0 () () () 0 0)
>  10 '__vtype___iso_c_binding_C_funptr' 'a' '' 1 ((DERIVED UNKNOWN-INTENT
> -UNKNOWN-PROC UNKNOWN UNKNOWN 0 0 VTYPE) ((13 '_hash' (INTEGER 4 0 0 0
> -INTEGER ()) () () () (UNKNOWN-FL UNKNOWN-INTENT UNKNOWN-PROC UNKNOWN
> -UNKNOWN 0 0) PRIVATE (CONSTANT (INTEGER 4 0 0 0 INTEGER ()) 0 '0' ())) (
> -14 '_size' (INTEGER 8 0 0 0 INTEGER ()) () () () (UNKNOWN-FL
> +UNKNOWN-PROC UNKNOWN UNKNOWN 0 0 RECURSIVE VTYPE) ((13 '_hash' (INTEGER
> +4 0 0 0 INTEGER ()) () () () (UNKNOWN-FL UNKNOWN-INTENT UNKNOWN-PROC
> +UNKNOWN UNKNOWN 0 0) PRIVATE (CONSTANT (INTEGER 4 0 0 0 INTEGER ()) 0 '0'
> +())) (14 '_size' (INTEGER 8 0 0 0 INTEGER ()) () () () (UNKNOWN-FL
>  UNKNOWN-INTENT UNKNOWN-PROC UNKNOWN UNKNOWN 0 0) PRIVATE) (15 '_extends'
>  (DERIVED 10 0 0 0 DERIVED ()) () () () (UNKNOWN-FL UNKNOWN-INTENT
>  UNKNOWN-PROC UNKNOWN UNKNOWN 0 0 POINTER) PRIVATE) (16 '_def_init' (
> @@ -59,10 +59,10 @@ UNKNOWN-PROC UNKNOWN UNKNOWN 0 0 SUBROUT
>  UNKNOWN-ACCESS OVERRIDABLE PASS SPECIFIC PPC '' 0))) UNKNOWN-ACCESS (
>  UNKNOWN 0 0 0 0 UNKNOWN ()) 0 0 () () 0 () () () 0 0 0)
>  12 '__vtype___iso_c_binding_C_ptr' 'a' '' 1 ((DERIVED UNKNOWN-INTENT
> -UNKNOWN-PROC UNKNOWN UNKNOWN 0 0 VTYPE) ((21 '_hash' (INTEGER 4 0 0 0
> -INTEGER ()) () () () (UNKNOWN-FL UNKNOWN-INTENT UNKNOWN-PROC UNKNOWN
> -UNKNOWN 0 0) PRIVATE (CONSTANT (INTEGER 4 0 0 0 INTEGER ()) 0 '0' ())) (
> -22 '_size' (INTEGER 8 0 0 0 INTEGER ()) () () () (UNKNOWN-FL
> +UNKNOWN-PROC UNKNOWN UNKNOWN 0 0 RECURSIVE VTYPE) ((21 '_hash' (INTEGER
> +4 0 0 0 INTEGER ()) () () () (UNKNOWN-FL UNKNOWN-INTENT UNKNOWN-PROC
> +UNKNOWN UNKNOWN 0 0) PRIVATE (CONSTANT (INTEGER 4 0 0 0 INTEGER ()) 0 '0'
> +())) (22 '_size' (INTEGER 8 0 0 0 INTEGER ()) () () () (UNKNOWN-FL
>  UNKNOWN-INTENT UNKNOWN-PROC UNKNOWN UNKNOWN 0 0) PRIVATE) (23 '_extends'
>  (DERIVED 12 0 0 0 DERIVED ()) () () () (UNKNOWN-FL UNKNOWN-INTENT
>  UNKNOWN-PROC UNKNOWN UNKNOWN 0 0 POINTER) PRIVATE) (24 '_def_init' (
> @@ -295,13 +295,16 @@ UNKNOWN-PROC UNKNOWN UNKNOWN 0 0 IS_C_IN
>  0 1 1 CHARACTER ((CONSTANT (INTEGER 8 0 0 0 INTEGER ()) 0 '1' ()))) 0 0
>  () (CONSTANT (CHARACTER 1 0 1 1 UNKNOWN (())) 0 1 '\U0000000b' ()) () 0
>  () () () 2 41)
> -18 '__copy___iso_c_binding_C_funptr' 'a' '' 94 ((PROCEDURE
> +94 'f_c_string' '__iso_c_binding' '' 1 ((PROCEDURE UNKNOWN-INTENT
> +UNKNOWN-PROC DECL UNKNOWN 0 0 INTRINSIC FUNCTION PURE) () (CHARACTER 1 0
> +0 0 CHARACTER ()) 95 0 (96 97) () 0 () () () 2 52)
> +18 '__copy___iso_c_binding_C_funptr' 'a' '' 98 ((PROCEDURE
>  UNKNOWN-INTENT UNKNOWN-PROC DECL UNKNOWN 0 0 ARTIFICIAL SUBROUTINE
> -ELEMENTAL PURE ALWAYS_EXPLICIT) () (UNKNOWN 0 0 0 0 UNKNOWN ()) 0 0 (95
> -96) () 0 () () () 0 0)
> -26 '__copy___iso_c_binding_C_ptr' 'a' '' 97 ((PROCEDURE UNKNOWN-INTENT
> +ELEMENTAL PURE ALWAYS_EXPLICIT) () (UNKNOWN 0 0 0 0 UNKNOWN ()) 0 0 (99
> +100) () 0 () () () 0 0)
> +26 '__copy___iso_c_binding_C_ptr' 'a' '' 101 ((PROCEDURE UNKNOWN-INTENT
>  UNKNOWN-PROC DECL UNKNOWN 0 0 ARTIFICIAL SUBROUTINE ELEMENTAL PURE
> -ALWAYS_EXPLICIT) () (UNKNOWN 0 0 0 0 UNKNOWN ()) 0 0 (98 99) () 0 () ()
> +ALWAYS_EXPLICIT) () (UNKNOWN 0 0 0 0 UNKNOWN ()) 0 0 (102 103) () 0 () ()
>  () 0 0)
>  33 'c_ptr_1' '' '' 32 ((VARIABLE IN UNKNOWN-PROC UNKNOWN UNKNOWN 0 0
>  DUMMY) () (VOID 0 0 0 0 VOID ()) 0 0 () () 0 () () () 0 0)
> @@ -319,16 +322,21 @@ OPTIONAL DUMMY) () (INTEGER 4 0 0 0 INTE
>  () (UNKNOWN 0 0 0 0 UNKNOWN ()) 0 0 () () 0 () () () 0 0)
>  92 'x' '' '' 91 ((VARIABLE IN UNKNOWN-PROC UNKNOWN UNKNOWN 0 0 DUMMY) ()
>  (UNKNOWN 0 0 0 0 UNKNOWN ()) 0 0 () () 0 () () () 0 0)
> -95 'src' '' '' 94 ((VARIABLE IN UNKNOWN-PROC UNKNOWN UNKNOWN 0 0
> +96 'string' '' '' 95 ((VARIABLE IN UNKNOWN-PROC UNKNOWN UNKNOWN 0 0
> +DUMMY) () (CHARACTER 1 0 0 0 CHARACTER (())) 0 0 () () 0 () () () 0 0)
> +97 'asis' '' '' 95 ((VARIABLE IN UNKNOWN-PROC UNKNOWN UNKNOWN 0 0
> +OPTIONAL DUMMY) () (CHARACTER 1 0 0 0 CHARACTER (())) 0 0 () () 0 () ()
> +() 0 0)
> +99 'src' '' '' 98 ((VARIABLE IN UNKNOWN-PROC UNKNOWN UNKNOWN 0 0
>  ARTIFICIAL DUMMY) () (DERIVED 2 0 0 0 DERIVED ()) 0 0 () () 0 () () () 0
>  0)
> -96 'dst' '' '' 94 ((VARIABLE INOUT UNKNOWN-PROC UNKNOWN UNKNOWN 0 0
> +100 'dst' '' '' 98 ((VARIABLE INOUT UNKNOWN-PROC UNKNOWN UNKNOWN 0 0
>  ARTIFICIAL DUMMY) () (DERIVED 2 0 0 0 DERIVED ()) 0 0 () () 0 () () () 0
>  0)
> -98 'src' '' '' 97 ((VARIABLE IN UNKNOWN-PROC UNKNOWN UNKNOWN 0 0
> +102 'src' '' '' 101 ((VARIABLE IN UNKNOWN-PROC UNKNOWN UNKNOWN 0 0
>  ARTIFICIAL DUMMY) () (DERIVED 3 0 0 0 DERIVED ()) 0 0 () () 0 () () () 0
>  0)
> -99 'dst' '' '' 97 ((VARIABLE INOUT UNKNOWN-PROC UNKNOWN UNKNOWN 0 0
> +103 'dst' '' '' 101 ((VARIABLE INOUT UNKNOWN-PROC UNKNOWN UNKNOWN 0 0
>  ARTIFICIAL DUMMY) () (DERIVED 3 0 0 0 DERIVED ()) 0 0 () () 0 () () () 0
>  0)
>  )
> @@ -351,4 +359,4 @@ ARTIFICIAL DUMMY) () (DERIVED 3 0 0 0 DE
>  'c_long_double' 0 78 'c_long_double_complex' 0 79 'c_long_long' 0 80
>  'c_new_line' 0 81 'c_null_char' 0 82 'c_null_funptr' 0 83 'c_null_ptr' 0
>  84 'c_ptr' 0 85 'c_ptrdiff_t' 0 86 'c_short' 0 87 'c_signed_char' 0 88
> -'c_size_t' 0 89 'c_sizeof' 0 90 'c_vertical_tab' 0 93)
> +'c_size_t' 0 89 'c_sizeof' 0 90 'c_vertical_tab' 0 93 'f_c_string' 0 94)
> --- /tmp/2	2025-01-08 10:23:51.237508661 +0100
> +++ /tmp/4	2025-01-08 10:24:14.930177279 +0100
> @@ -1,4 +1,4 @@
> -GFORTRAN module version '15' created from a.f90
> +GFORTRAN module version '16' created from a.f90
>  (() () () () () () () () () () () () () () () () () () () () () () () ()
>  () () ())
>
> @@ -41,10 +41,10 @@ DERIVED ()) 0 0 () () 0 () () () 0 0)
>  UNKNOWN-PROC UNKNOWN IMPLICIT-SAVE 0 0 TARGET VTAB) () (DERIVED 13 0 0 0
>  DERIVED ()) 0 0 () () 0 () () () 0 0)
>  9 '__vtype_iso_fortran_env_Event_type' 'b' '' 1 ((DERIVED UNKNOWN-INTENT
> -UNKNOWN-PROC UNKNOWN UNKNOWN 0 0 VTYPE) ((14 '_hash' (INTEGER 4 0 0 0
> -INTEGER ()) () () () (UNKNOWN-FL UNKNOWN-INTENT UNKNOWN-PROC UNKNOWN
> -UNKNOWN 0 0) PRIVATE (CONSTANT (INTEGER 4 0 0 0 INTEGER ()) 0 '0' ())) (
> -15 '_size' (INTEGER 8 0 0 0 INTEGER ()) () () () (UNKNOWN-FL
> +UNKNOWN-PROC UNKNOWN UNKNOWN 0 0 RECURSIVE VTYPE) ((14 '_hash' (INTEGER
> +4 0 0 0 INTEGER ()) () () () (UNKNOWN-FL UNKNOWN-INTENT UNKNOWN-PROC
> +UNKNOWN UNKNOWN 0 0) PRIVATE (CONSTANT (INTEGER 4 0 0 0 INTEGER ()) 0 '0'
> +())) (15 '_size' (INTEGER 8 0 0 0 INTEGER ()) () () () (UNKNOWN-FL
>  UNKNOWN-INTENT UNKNOWN-PROC UNKNOWN UNKNOWN 0 0) PRIVATE) (16 '_extends'
>  (DERIVED 9 0 0 0 DERIVED ()) () () () (UNKNOWN-FL UNKNOWN-INTENT
>  UNKNOWN-PROC UNKNOWN UNKNOWN 0 0 POINTER) PRIVATE) (17 '_def_init' (
> @@ -62,10 +62,10 @@ UNKNOWN-PROC UNKNOWN UNKNOWN 0 0 SUBROUT
>  UNKNOWN-ACCESS OVERRIDABLE PASS SPECIFIC PPC '' 0))) UNKNOWN-ACCESS (
>  UNKNOWN 0 0 0 0 UNKNOWN ()) 0 0 () () 0 () () () 0 0 0)
>  11 '__vtype_iso_fortran_env_Lock_type' 'b' '' 1 ((DERIVED UNKNOWN-INTENT
> -UNKNOWN-PROC UNKNOWN UNKNOWN 0 0 VTYPE) ((22 '_hash' (INTEGER 4 0 0 0
> -INTEGER ()) () () () (UNKNOWN-FL UNKNOWN-INTENT UNKNOWN-PROC UNKNOWN
> -UNKNOWN 0 0) PRIVATE (CONSTANT (INTEGER 4 0 0 0 INTEGER ()) 0 '0' ())) (
> -23 '_size' (INTEGER 8 0 0 0 INTEGER ()) () () () (UNKNOWN-FL
> +UNKNOWN-PROC UNKNOWN UNKNOWN 0 0 RECURSIVE VTYPE) ((22 '_hash' (INTEGER
> +4 0 0 0 INTEGER ()) () () () (UNKNOWN-FL UNKNOWN-INTENT UNKNOWN-PROC
> +UNKNOWN UNKNOWN 0 0) PRIVATE (CONSTANT (INTEGER 4 0 0 0 INTEGER ()) 0 '0'
> +())) (23 '_size' (INTEGER 8 0 0 0 INTEGER ()) () () () (UNKNOWN-FL
>  UNKNOWN-INTENT UNKNOWN-PROC UNKNOWN UNKNOWN 0 0) PRIVATE) (24 '_extends'
>  (DERIVED 11 0 0 0 DERIVED ()) () () () (UNKNOWN-FL UNKNOWN-INTENT
>  UNKNOWN-PROC UNKNOWN UNKNOWN 0 0 POINTER) PRIVATE) (25 '_def_init' (
> @@ -83,10 +83,10 @@ UNKNOWN-PROC UNKNOWN UNKNOWN 0 0 SUBROUT
>  UNKNOWN-ACCESS OVERRIDABLE PASS SPECIFIC PPC '' 0))) UNKNOWN-ACCESS (
>  UNKNOWN 0 0 0 0 UNKNOWN ()) 0 0 () () 0 () () () 0 0 0)
>  13 '__vtype_iso_fortran_env_Team_type' 'b' '' 1 ((DERIVED UNKNOWN-INTENT
> -UNKNOWN-PROC UNKNOWN UNKNOWN 0 0 VTYPE) ((30 '_hash' (INTEGER 4 0 0 0
> -INTEGER ()) () () () (UNKNOWN-FL UNKNOWN-INTENT UNKNOWN-PROC UNKNOWN
> -UNKNOWN 0 0) PRIVATE (CONSTANT (INTEGER 4 0 0 0 INTEGER ()) 0 '0' ())) (
> -31 '_size' (INTEGER 8 0 0 0 INTEGER ()) () () () (UNKNOWN-FL
> +UNKNOWN-PROC UNKNOWN UNKNOWN 0 0 RECURSIVE VTYPE) ((30 '_hash' (INTEGER
> +4 0 0 0 INTEGER ()) () () () (UNKNOWN-FL UNKNOWN-INTENT UNKNOWN-PROC
> +UNKNOWN UNKNOWN 0 0) PRIVATE (CONSTANT (INTEGER 4 0 0 0 INTEGER ()) 0 '0'
> +())) (31 '_size' (INTEGER 8 0 0 0 INTEGER ()) () () () (UNKNOWN-FL
>  UNKNOWN-INTENT UNKNOWN-PROC UNKNOWN UNKNOWN 0 0) PRIVATE) (32 '_extends'
>  (DERIVED 13 0 0 0 DERIVED ()) () () () (UNKNOWN-FL UNKNOWN-INTENT
>  UNKNOWN-PROC UNKNOWN UNKNOWN 0 0 POINTER) PRIVATE) (33 '_def_init' (
> @@ -178,7 +178,19 @@ UNKNOWN-PROC UNKNOWN UNKNOWN 0 0 INTRINS
>  58 'lock_type' 'iso_fortran_env' '' 1 ((PROCEDURE UNKNOWN-INTENT
>  UNKNOWN-PROC DECL UNKNOWN 0 0 FUNCTION GENERIC) () (INTEGER 4 0 0 0
>  INTEGER ()) 0 0 () () 0 () () () 1 29)
> -59 'logical_kinds' 'iso_fortran_env' '' 1 ((PARAMETER UNKNOWN-INTENT
> +59 'logical16' 'iso_fortran_env' '' 1 ((PARAMETER UNKNOWN-INTENT
> +UNKNOWN-PROC UNKNOWN UNKNOWN 0 0) () (INTEGER 4 0 0 0 INTEGER ()) 0 0 ()
> +(CONSTANT (INTEGER 4 0 0 0 INTEGER ()) 0 '0' ()) () 0 () () () 1 33)
> +60 'logical32' 'iso_fortran_env' '' 1 ((PARAMETER UNKNOWN-INTENT
> +UNKNOWN-PROC UNKNOWN UNKNOWN 0 0) () (INTEGER 4 0 0 0 INTEGER ()) 0 0 ()
> +(CONSTANT (INTEGER 4 0 0 0 INTEGER ()) 0 '0' ()) () 0 () () () 1 34)
> +61 'logical64' 'iso_fortran_env' '' 1 ((PARAMETER UNKNOWN-INTENT
> +UNKNOWN-PROC UNKNOWN UNKNOWN 0 0) () (INTEGER 4 0 0 0 INTEGER ()) 0 0 ()
> +(CONSTANT (INTEGER 4 0 0 0 INTEGER ()) 0 '0' ()) () 0 () () () 1 35)
> +62 'logical8' 'iso_fortran_env' '' 1 ((PARAMETER UNKNOWN-INTENT
> +UNKNOWN-PROC UNKNOWN UNKNOWN 0 0) () (INTEGER 4 0 0 0 INTEGER ()) 0 0 ()
> +(CONSTANT (INTEGER 4 0 0 0 INTEGER ()) 0 '0' ()) () 0 () () () 1 32)
> +63 'logical_kinds' 'iso_fortran_env' '' 1 ((PARAMETER UNKNOWN-INTENT
>  UNKNOWN-PROC UNKNOWN UNKNOWN 0 0 DIMENSION) () (INTEGER 4 0 0 0 INTEGER
>  ()) 0 0 () (ARRAY (INTEGER 4 0 0 0 INTEGER ()) 1 (((CONSTANT (INTEGER 4
>  0 0 0 INTEGER ()) 0 '1' ()) ()) ((CONSTANT (INTEGER 4 0 0 0 INTEGER ())
> @@ -187,23 +199,26 @@ CONSTANT (INTEGER 4 0 0 0 INTEGER ()) 0
>  4 0 0 0 INTEGER ()) 0 '16' ()) ())) ('5') ()) (1 0 EXPLICIT (CONSTANT (
>  INTEGER 4 0 0 0 INTEGER ()) 0 '1' ()) (CONSTANT (INTEGER 4 0 0 0 INTEGER
>  ()) 0 '5' ())) 0 () () () 1 25)
> -60 'numeric_storage_size' 'iso_fortran_env' '' 1 ((PARAMETER
> +64 'numeric_storage_size' 'iso_fortran_env' '' 1 ((PARAMETER
>  UNKNOWN-INTENT UNKNOWN-PROC UNKNOWN UNKNOWN 0 0) () (INTEGER 4 0 0 0
>  INTEGER ()) 0 0 () (CONSTANT (INTEGER 4 0 0 0 INTEGER ()) 0 '32' ()) ()
>  0 () () () 1 13)
> -61 'output_unit' 'iso_fortran_env' '' 1 ((PARAMETER UNKNOWN-INTENT
> +65 'output_unit' 'iso_fortran_env' '' 1 ((PARAMETER UNKNOWN-INTENT
>  UNKNOWN-PROC UNKNOWN UNKNOWN 0 0) () (INTEGER 4 0 0 0 INTEGER ()) 0 0 ()
>  (CONSTANT (INTEGER 4 0 0 0 INTEGER ()) 0 '6' ()) () 0 () () () 1 14)
> -62 'real128' 'iso_fortran_env' '' 1 ((PARAMETER UNKNOWN-INTENT
> +66 'real128' 'iso_fortran_env' '' 1 ((PARAMETER UNKNOWN-INTENT
>  UNKNOWN-PROC UNKNOWN UNKNOWN 0 0) () (INTEGER 4 0 0 0 INTEGER ()) 0 0 ()
>  (CONSTANT (INTEGER 4 0 0 0 INTEGER ()) 0 '16' ()) () 0 () () () 1 17)
> -63 'real32' 'iso_fortran_env' '' 1 ((PARAMETER UNKNOWN-INTENT
> +67 'real16' 'iso_fortran_env' '' 1 ((PARAMETER UNKNOWN-INTENT
> +UNKNOWN-PROC UNKNOWN UNKNOWN 0 0) () (INTEGER 4 0 0 0 INTEGER ()) 0 0 ()
> +(CONSTANT (INTEGER 4 0 0 0 INTEGER ()) 0 '0' ()) () 0 () () () 1 36)
> +68 'real32' 'iso_fortran_env' '' 1 ((PARAMETER UNKNOWN-INTENT
>  UNKNOWN-PROC UNKNOWN UNKNOWN 0 0) () (INTEGER 4 0 0 0 INTEGER ()) 0 0 ()
>  (CONSTANT (INTEGER 4 0 0 0 INTEGER ()) 0 '4' ()) () 0 () () () 1 15)
> -64 'real64' 'iso_fortran_env' '' 1 ((PARAMETER UNKNOWN-INTENT
> +69 'real64' 'iso_fortran_env' '' 1 ((PARAMETER UNKNOWN-INTENT
>  UNKNOWN-PROC UNKNOWN UNKNOWN 0 0) () (INTEGER 4 0 0 0 INTEGER ()) 0 0 ()
>  (CONSTANT (INTEGER 4 0 0 0 INTEGER ()) 0 '8' ()) () 0 () () () 1 16)
> -65 'real_kinds' 'iso_fortran_env' '' 1 ((PARAMETER UNKNOWN-INTENT
> +70 'real_kinds' 'iso_fortran_env' '' 1 ((PARAMETER UNKNOWN-INTENT
>  UNKNOWN-PROC UNKNOWN UNKNOWN 0 0 DIMENSION) () (INTEGER 4 0 0 0 INTEGER
>  ()) 0 0 () (ARRAY (INTEGER 4 0 0 0 INTEGER ()) 1 (((CONSTANT (INTEGER 4
>  0 0 0 INTEGER ()) 0 '4' ()) ()) ((CONSTANT (INTEGER 4 0 0 0 INTEGER ())
> @@ -211,54 +226,54 @@ UNKNOWN-PROC UNKNOWN UNKNOWN 0 0 DIMENSI
>  CONSTANT (INTEGER 4 0 0 0 INTEGER ()) 0 '16' ()) ())) ('4') ()) (1 0
>  EXPLICIT (CONSTANT (INTEGER 4 0 0 0 INTEGER ()) 0 '1' ()) (CONSTANT (
>  INTEGER 4 0 0 0 INTEGER ()) 0 '4' ())) 0 () () () 1 26)
> -66 'stat_failed_image' 'iso_fortran_env' '' 1 ((PARAMETER UNKNOWN-INTENT
> +71 'stat_failed_image' 'iso_fortran_env' '' 1 ((PARAMETER UNKNOWN-INTENT
>  UNKNOWN-PROC UNKNOWN UNKNOWN 0 0) () (INTEGER 4 0 0 0 INTEGER ()) 0 0 ()
>  (CONSTANT (INTEGER 4 0 0 0 INTEGER ()) 0 '6001' ()) () 0 () () () 1 21)
> -67 'stat_locked' 'iso_fortran_env' '' 1 ((PARAMETER UNKNOWN-INTENT
> +72 'stat_locked' 'iso_fortran_env' '' 1 ((PARAMETER UNKNOWN-INTENT
>  UNKNOWN-PROC UNKNOWN UNKNOWN 0 0) () (INTEGER 4 0 0 0 INTEGER ()) 0 0 ()
>  (CONSTANT (INTEGER 4 0 0 0 INTEGER ()) 0 '1' ()) () 0 () () () 1 18)
> -68 'stat_locked_other_image' 'iso_fortran_env' '' 1 ((PARAMETER
> +73 'stat_locked_other_image' 'iso_fortran_env' '' 1 ((PARAMETER
>  UNKNOWN-INTENT UNKNOWN-PROC UNKNOWN UNKNOWN 0 0) () (INTEGER 4 0 0 0
>  INTEGER ()) 0 0 () (CONSTANT (INTEGER 4 0 0 0 INTEGER ()) 0 '2' ()) () 0
>  () () () 1 19)
> -69 'stat_stopped_image' 'iso_fortran_env' '' 1 ((PARAMETER
> +74 'stat_stopped_image' 'iso_fortran_env' '' 1 ((PARAMETER
>  UNKNOWN-INTENT UNKNOWN-PROC UNKNOWN UNKNOWN 0 0) () (INTEGER 4 0 0 0
>  INTEGER ()) 0 0 () (CONSTANT (INTEGER 4 0 0 0 INTEGER ()) 0 '6000' ()) ()
>  0 () () () 1 20)
> -70 'stat_unlocked' 'iso_fortran_env' '' 1 ((PARAMETER UNKNOWN-INTENT
> +75 'stat_unlocked' 'iso_fortran_env' '' 1 ((PARAMETER UNKNOWN-INTENT
>  UNKNOWN-PROC UNKNOWN UNKNOWN 0 0) () (INTEGER 4 0 0 0 INTEGER ()) 0 0 ()
>  (CONSTANT (INTEGER 4 0 0 0 INTEGER ()) 0 '0' ()) () 0 () () () 1 22)
> -71 'team_type' 'iso_fortran_env' '' 1 ((PROCEDURE UNKNOWN-INTENT
> +76 'team_type' 'iso_fortran_env' '' 1 ((PROCEDURE UNKNOWN-INTENT
>  UNKNOWN-PROC DECL UNKNOWN 0 0 FUNCTION GENERIC) () (REAL 4 0 0 0 REAL ())
>  0 0 () () 0 () () () 1 31)
> -19 '__copy_iso_fortran_env_Event_type' 'b' '' 72 ((PROCEDURE
> +19 '__copy_iso_fortran_env_Event_type' 'b' '' 77 ((PROCEDURE
>  UNKNOWN-INTENT UNKNOWN-PROC DECL UNKNOWN 0 0 ARTIFICIAL SUBROUTINE
> -ELEMENTAL PURE ALWAYS_EXPLICIT) () (UNKNOWN 0 0 0 0 UNKNOWN ()) 0 0 (73
> -74) () 0 () () () 0 0)
> -27 '__copy_iso_fortran_env_Lock_type' 'b' '' 75 ((PROCEDURE
> +ELEMENTAL PURE ALWAYS_EXPLICIT) () (UNKNOWN 0 0 0 0 UNKNOWN ()) 0 0 (78
> +79) () 0 () () () 0 0)
> +27 '__copy_iso_fortran_env_Lock_type' 'b' '' 80 ((PROCEDURE
>  UNKNOWN-INTENT UNKNOWN-PROC DECL UNKNOWN 0 0 ARTIFICIAL SUBROUTINE
> -ELEMENTAL PURE ALWAYS_EXPLICIT) () (UNKNOWN 0 0 0 0 UNKNOWN ()) 0 0 (76
> -77) () 0 () () () 0 0)
> -35 '__copy_iso_fortran_env_Team_type' 'b' '' 78 ((PROCEDURE
> +ELEMENTAL PURE ALWAYS_EXPLICIT) () (UNKNOWN 0 0 0 0 UNKNOWN ()) 0 0 (81
> +82) () 0 () () () 0 0)
> +35 '__copy_iso_fortran_env_Team_type' 'b' '' 83 ((PROCEDURE
>  UNKNOWN-INTENT UNKNOWN-PROC DECL UNKNOWN 0 0 ARTIFICIAL SUBROUTINE
> -ELEMENTAL PURE ALWAYS_EXPLICIT) () (UNKNOWN 0 0 0 0 UNKNOWN ()) 0 0 (79
> -80) () 0 () () () 0 0)
> -73 'src' '' '' 72 ((VARIABLE IN UNKNOWN-PROC UNKNOWN UNKNOWN 0 0
> +ELEMENTAL PURE ALWAYS_EXPLICIT) () (UNKNOWN 0 0 0 0 UNKNOWN ()) 0 0 (84
> +85) () 0 () () () 0 0)
> +78 'src' '' '' 77 ((VARIABLE IN UNKNOWN-PROC UNKNOWN UNKNOWN 0 0
>  ARTIFICIAL DUMMY) () (DERIVED 2 0 0 0 DERIVED ()) 0 0 () () 0 () () () 0
>  0)
> -74 'dst' '' '' 72 ((VARIABLE INOUT UNKNOWN-PROC UNKNOWN UNKNOWN 0 0
> +79 'dst' '' '' 77 ((VARIABLE INOUT UNKNOWN-PROC UNKNOWN UNKNOWN 0 0
>  ARTIFICIAL DUMMY) () (DERIVED 2 0 0 0 DERIVED ()) 0 0 () () 0 () () () 0
>  0)
> -76 'src' '' '' 75 ((VARIABLE IN UNKNOWN-PROC UNKNOWN UNKNOWN 0 0
> +81 'src' '' '' 80 ((VARIABLE IN UNKNOWN-PROC UNKNOWN UNKNOWN 0 0
>  ARTIFICIAL DUMMY) () (DERIVED 3 0 0 0 DERIVED ()) 0 0 () () 0 () () () 0
>  0)
> -77 'dst' '' '' 75 ((VARIABLE INOUT UNKNOWN-PROC UNKNOWN UNKNOWN 0 0
> +82 'dst' '' '' 80 ((VARIABLE INOUT UNKNOWN-PROC UNKNOWN UNKNOWN 0 0
>  ARTIFICIAL DUMMY) () (DERIVED 3 0 0 0 DERIVED ()) 0 0 () () 0 () () () 0
>  0)
> -79 'src' '' '' 78 ((VARIABLE IN UNKNOWN-PROC UNKNOWN UNKNOWN 0 0
> +84 'src' '' '' 83 ((VARIABLE IN UNKNOWN-PROC UNKNOWN UNKNOWN 0 0
>  ARTIFICIAL DUMMY) () (DERIVED 4 0 0 0 DERIVED ()) 0 0 () () 0 () () () 0
>  0)
> -80 'dst' '' '' 78 ((VARIABLE INOUT UNKNOWN-PROC UNKNOWN UNKNOWN 0 0
> +85 'dst' '' '' 83 ((VARIABLE INOUT UNKNOWN-PROC UNKNOWN UNKNOWN 0 0
>  ARTIFICIAL DUMMY) () (DERIVED 4 0 0 0 DERIVED ()) 0 0 () () 0 () () () 0
>  0)
>  )
> @@ -278,7 +293,8 @@ ARTIFICIAL DUMMY) () (DERIVED 4 0 0 0 DE
>  'input_unit' 0 48 'int16' 0 49 'int32' 0 50 'int64' 0 51 'int8' 0 52
>  'integer_kinds' 0 53 'iostat_end' 0 54 'iostat_eor' 0 55
>  'iostat_inquire_internal_unit' 0 56 'iso_fortran_env' 0 57 'lock_type' 0
> -58 'logical_kinds' 0 59 'numeric_storage_size' 0 60 'output_unit' 0 61
> -'real128' 0 62 'real32' 0 63 'real64' 0 64 'real_kinds' 0 65
> -'stat_failed_image' 0 66 'stat_locked' 0 67 'stat_locked_other_image' 0
> -68 'stat_stopped_image' 0 69 'stat_unlocked' 0 70 'team_type' 0 71)
> +58 'logical16' 0 59 'logical32' 0 60 'logical64' 0 61 'logical8' 0 62
> +'logical_kinds' 0 63 'numeric_storage_size' 0 64 'output_unit' 0 65
> +'real128' 0 66 'real16' 0 67 'real32' 0 68 'real64' 0 69 'real_kinds' 0
> +70 'stat_failed_image' 0 71 'stat_locked' 0 72 'stat_locked_other_image'
> +0 73 'stat_stopped_image' 0 74 'stat_unlocked' 0 75 'team_type' 0 76)
>
>
> 	Jakub
>


--
Andre Vehreschild * Email: vehre ad gmx dot de
  
Jakub Jelinek Jan. 8, 2025, 11:04 a.m. UTC | #6
On Wed, Jan 08, 2025 at 11:53:53AM +0100, Andre Vehreschild wrote:
> Well, thinking about it, it smells like a side-effect of the 116669 fix. A type
> getting the recursive marker enforces the generation of the vtype for it. I
> don't see yet, why the iso_c_binding_C_funptr should be marked as recursive. I
> will investigate. How much time do I have?

To me the other patch (just bumping of MOD_VERSION) is more important than
this one, and this one isn't finished anyway and I'm afraid I don't know
enough about the Fortran class etc. support to finish it myself.

The ABI has to be fixed by the time GCC 15 is released (so ideally frozen
on/before mid April), but it wouldn't hurt if it is fixed much earlier
(e.g. in Fedora we are building the distro with GCC 15 prerelease in second
half of January, and while it is our risk and we need to be prepared to rebuild
stuff if there are ABI changes and the like, it would be useful if the *.mod file
format didn't change much during stage4 (which is less than a week away).

	Jakub
  
Mikael Morin Jan. 8, 2025, 11:05 a.m. UTC | #7
Hello,

Le 08/01/2025 à 11:34, Andre Vehreschild a écrit :
> 
> The flag is used now to indicate, that a type can (indirectly) reference
> itself. Not having the marker lead to endless recursion during construction of
> copy or deallocate operations on an object of the type.
> 
Can it be removed from the module file maybe?
Looks like redundant information that can be reconstructed after module 
loading.

If we want to support older module files, the value of the flag would 
have to be reconstructed anyway, so let's just remove it from the module?
  
Andre Vehreschild Jan. 8, 2025, 11:13 a.m. UTC | #8
Ok, I was merely asking, if I need to stop my current fault finding immediately
and fix it within the next hours, or if a fix is ok by say beginning of next at
latest.

I will finish my current fault finding and then extend your patch.

- Andre

On Wed, 8 Jan 2025 12:04:15 +0100
Jakub Jelinek <jakub@redhat.com> wrote:

> On Wed, Jan 08, 2025 at 11:53:53AM +0100, Andre Vehreschild wrote:
> > Well, thinking about it, it smells like a side-effect of the 116669 fix. A
> > type getting the recursive marker enforces the generation of the vtype for
> > it. I don't see yet, why the iso_c_binding_C_funptr should be marked as
> > recursive. I will investigate. How much time do I have?
>
> To me the other patch (just bumping of MOD_VERSION) is more important than
> this one, and this one isn't finished anyway and I'm afraid I don't know
> enough about the Fortran class etc. support to finish it myself.
>
> The ABI has to be fixed by the time GCC 15 is released (so ideally frozen
> on/before mid April), but it wouldn't hurt if it is fixed much earlier
> (e.g. in Fedora we are building the distro with GCC 15 prerelease in second
> half of January, and while it is our risk and we need to be prepared to
> rebuild stuff if there are ABI changes and the like, it would be useful if
> the *.mod file format didn't change much during stage4 (which is less than a
> week away).
>
> 	Jakub
>


--
Andre Vehreschild * Email: vehre ad gmx dot de
  
Andre Vehreschild Jan. 8, 2025, 11:16 a.m. UTC | #9
That sounds like a feasible solution when finding the erroneous (to my belief)
setting of flag takes longer than expect.

Mikael, do you know your way around the module export stuff and can you point
me directly to the line in question? I haven't worked in that area. Just
asking. If you don't know it, don't bother.

- Andre

On Wed, 8 Jan 2025 12:05:47 +0100
Mikael Morin <morin-mikael@orange.fr> wrote:

> Hello,
> 
> Le 08/01/2025 à 11:34, Andre Vehreschild a écrit :
> > 
> > The flag is used now to indicate, that a type can (indirectly) reference
> > itself. Not having the marker lead to endless recursion during construction
> > of copy or deallocate operations on an object of the type.
> >   
> Can it be removed from the module file maybe?
> Looks like redundant information that can be reconstructed after module 
> loading.
> 
> If we want to support older module files, the value of the flag would 
> have to be reconstructed anyway, so let's just remove it from the module?
  
Andre Vehreschild Jan. 8, 2025, 11:42 a.m. UTC | #10
Er, call me stupid, but what is the easiest way to apply your patch? 'git am' on
the part from the date-line to the end stripping your greetings, always leads
to unrecognized patch format. Using `patch -p1` did not work either. What am I
not seeing?

- Andre

On Wed, 8 Jan 2025 10:44:50 +0100
Jakub Jelinek <jakub@redhat.com> wrote:

> Hi!
>
> Based on the comments in the PR, I've tried to write a patch which would
> try to keep backwards compatibility with the GCC 11-14 *.mod files.
>
> Testcase was
> module a
>   use, intrinsic :: iso_c_binding
> end module a
> module b
>   use, intrinsic :: iso_fortran_env
> end module b
> and zcat a.mod; zcat b.mod
> Without this patch there are changes all around in the numbers
> because various new entries have been added in the middle.
> With this patch, there are still some changes:
> 1) __vtype___iso_c_binding_C_funptr and
>    __vtype___iso_c_binding_C_ptr have added RECURSIVE in GCC 15 compared to
>    14
> 2) __copy___iso_c_binding_C_funptr used to be 94 and now is 98,
>    __copy___iso_c_binding_C_ptr 97 -> 101 and src/dst also changed
> 3) __vtype_iso_fortran_env_Event_type and __vtype_iso_fortran_env_Lock_type
>    and __vtype_iso_fortran_env_Team_type also have RECURSIVE added
> 4) logical_kinds 59 -> 63, numeric_storage_size 60 -> 64, etc.
> So, I really don't know if it is feasible to ensure backwards compatibility.
>
> Plus how we would actually test whether we are able to accept the older
> modules in newer compilers.
>
> 2025-01-08  Jakub Jelinek  <jakub@redhat.com>
>
> 	PR fortran/118337
> 	* module.cc (COMPAT_MOD_VERSIONS): Define.
> 	(gfc_use_module): Accept also COMPAT_MOD_VERSIONS for compatibility.
> 	* iso-c-binding.def: Reorder entries so that the GCC 14 ones come
> 	before the ones new in GCC 15.
> 	* iso-fortran-env.def: Likewise.
>
> --- gcc/fortran/module.cc.jj	2025-01-08 10:05:39.308786981 +0100
> +++ gcc/fortran/module.cc	2025-01-08 10:18:14.234222227 +0100
> @@ -85,6 +85,8 @@ along with GCC; see the file COPYING3.
>  /* Don't put any single quote (') in MOD_VERSION, if you want it to be
>     recognized.  */
>  #define MOD_VERSION "16"
> +/* Older mod versions we can still parse.  */
> +#define COMPAT_MOD_VERSIONS { "15" }
>
>
>  /* Structure that describes a position within a module file.  */
> @@ -7451,10 +7453,23 @@ gfc_use_module (gfc_use_list *module)
>  			 " module file", module_fullpath);
>        if (start == 3)
>  	{
> +	  bool fatal = false;
>  	  if (strcmp (atom_name, " version") != 0
>  	      || module_char () != ' '
> -	      || parse_atom () != ATOM_STRING
> -	      || strcmp (atom_string, MOD_VERSION))
> +	      || parse_atom () != ATOM_STRING)
> +	    fatal = true;
> +	  else if (strcmp (atom_string, MOD_VERSION))
> +	    {
> +	      static const char *compat_mod_versions[] = COMPAT_MOD_VERSIONS;
> +	      fatal = true;
> +	      for (unsigned i = 0; i < ARRAY_SIZE (compat_mod_versions); ++i)
> +		if (!strcmp (atom_string, compat_mod_versions[i]))
> +		  {
> +		    fatal = false;
> +		    break;
> +		  }
> +	    }
> +	  if (fatal)
>  	    gfc_fatal_error ("Cannot read module file %qs opened at %C,"
>  			     " because it was created by a different"
>  			     " version of GNU Fortran", module_fullpath);
> --- gcc/fortran/iso-c-binding.def.jj	2025-01-02 11:47:31.894198887
> +0100 +++ gcc/fortran/iso-c-binding.def	2025-01-08 10:09:12.454799919
> +0100 @@ -17,7 +17,8 @@ along with GCC; see the file COPYING3.
>  <http://www.gnu.org/licenses/>.  */
>
>  /* This file contains the definition of the types provided by the
> -   Fortran 2003 ISO_C_BINDING intrinsic module.  */
> +   Fortran 2003 ISO_C_BINDING intrinsic module.  The ordering of
> +   the entries matters for the *.mod backwards compatibility.  */
>
>  #ifndef NAMED_INTCST
>  # define NAMED_INTCST(a,b,c,d)
> @@ -112,62 +113,6 @@ NAMED_INTCST (ISOCBINDING_INT_FAST64_T,
>  NAMED_INTCST (ISOCBINDING_INT_FAST128_T, "c_int_fast128_t",
>  	      get_int_kind_from_width (128), GFC_STD_GNU)
>
> -/* UNSIGNED.  */
> -NAMED_UINTCST (ISOCBINDING_UINT, "c_unsigned", gfc_c_uint_kind, \
> -	       GFC_STD_UNSIGNED)
> -NAMED_UINTCST (ISOCBINDING_USHORT, "c_unsigned_short", \
> -	       get_unsigned_kind_from_node (short_unsigned_type_node), \
> -	       GFC_STD_UNSIGNED)
> -NAMED_UINTCST (ISOCBINDING_UCHAR, "c_unsigned_char", \
> -	       get_unsigned_kind_from_node (unsigned_char_type_node), \
> -	       GFC_STD_UNSIGNED)
> -NAMED_UINTCST (ISOCBINDING_ULONG, "c_unsigned_long", \
> -	       get_unsigned_kind_from_node (long_unsigned_type_node), \
> -	       GFC_STD_UNSIGNED)
> -NAMED_UINTCST (ISOCBINDING_ULONGLONG, "c_unsigned_long_long", \
> -	       get_unsigned_kind_from_node (long_long_unsigned_type_node), \
> -	       GFC_STD_UNSIGNED)
> -NAMED_UINTCST (ISOCBINDING_UINTMAX_T, "c_uintmax_t", \
> -	       get_uint_kind_from_name (UINTMAX_TYPE), GFC_STD_UNSIGNED)
> -NAMED_UINTCST (ISOCBINDING_UINT8_T, "c_uint8_t", \
> -	       get_uint_kind_from_name (UINT8_TYPE), GFC_STD_UNSIGNED)
> -NAMED_UINTCST (ISOCBINDING_UINT16_T, "c_uint16_t", \
> -	       get_uint_kind_from_name (UINT16_TYPE), GFC_STD_UNSIGNED)
> -NAMED_UINTCST (ISOCBINDING_UINT32_T, "c_uint32_t", \
> -	       get_uint_kind_from_name (UINT32_TYPE), GFC_STD_UNSIGNED)
> -NAMED_UINTCST (ISOCBINDING_UINT64_T, "c_uint64_t", \
> -	       get_uint_kind_from_name (UINT64_TYPE), GFC_STD_UNSIGNED)
> -NAMED_UINTCST (ISOCBINDING_UINT128_T, "c_uint128_t", \
> -	       get_uint_kind_from_width (128), GFC_STD_UNSIGNED)
> -NAMED_UINTCST (ISOCBINDING_UINT_LEAST8_T, "c_uint_least8_t", \
> -	       get_uint_kind_from_name (UINT_LEAST8_TYPE), \
> -	       GFC_STD_UNSIGNED)
> -NAMED_UINTCST (ISOCBINDING_UINT_LEAST16_T, "c_uint_least16_t", \
> -	       get_uint_kind_from_name (UINT_LEAST16_TYPE), \
> -	       GFC_STD_UNSIGNED)
> -NAMED_UINTCST (ISOCBINDING_UINT_LEAST32_T, "c_uint_least32_t", \
> -	       get_uint_kind_from_name (UINT_LEAST32_TYPE),\
> -	       GFC_STD_UNSIGNED)
> -NAMED_UINTCST (ISOCBINDING_UINT_LEAST64_T, "c_uint_least64_t", \
> -	       get_uint_kind_from_name (UINT_LEAST64_TYPE),\
> -	       GFC_STD_UNSIGNED)
> -NAMED_UINTCST (ISOCBINDING_UINT_LEAST128_T, "c_uint_least128_t", \
> -	       get_uint_kind_from_width (128), GFC_STD_UNSIGNED)
> -NAMED_UINTCST (ISOCBINDING_UINT_FAST8_T, "c_uint_fast8_t", \
> -	       get_uint_kind_from_name (UINT_FAST8_TYPE), \
> -	       GFC_STD_UNSIGNED)
> -NAMED_UINTCST (ISOCBINDING_UINT_FAST16_T, "c_uint_fast16_t", \
> -	       get_uint_kind_from_name (UINT_FAST16_TYPE), \
> -	       GFC_STD_UNSIGNED)
> -NAMED_UINTCST (ISOCBINDING_UINT_FAST32_T, "c_uint_fast32_t", \
> -	       get_uint_kind_from_name (UINT_FAST32_TYPE),\
> -	       GFC_STD_UNSIGNED)
> -NAMED_UINTCST (ISOCBINDING_UINT_FAST64_T, "c_uint_fast64_t", \
> -	       get_uint_kind_from_name (UINT_FAST64_TYPE),\
> -	       GFC_STD_UNSIGNED)
> -NAMED_UINTCST (ISOCBINDING_UINT_FAST128_T, "c_uint_fast128_t", \
> -	       get_uint_kind_from_width (128), GFC_STD_UNSIGNED)
> -
>  NAMED_REALCST (ISOCBINDING_FLOAT, "c_float", \
>                 get_real_kind_from_node (float_type_node), GFC_STD_F2003)
>  NAMED_REALCST (ISOCBINDING_DOUBLE, "c_double", \
> @@ -259,6 +204,62 @@ NAMED_FUNCTION (ISOCBINDING_C_SIZEOF, "c
>  NAMED_FUNCTION (ISOCBINDING_F_C_STRING, "f_c_string", \
>                  GFC_ISYM_F_C_STRING, GFC_STD_F2023)
>
> +/* UNSIGNED.  */
> +NAMED_UINTCST (ISOCBINDING_UINT, "c_unsigned", gfc_c_uint_kind, \
> +	       GFC_STD_UNSIGNED)
> +NAMED_UINTCST (ISOCBINDING_USHORT, "c_unsigned_short", \
> +	       get_unsigned_kind_from_node (short_unsigned_type_node), \
> +	       GFC_STD_UNSIGNED)
> +NAMED_UINTCST (ISOCBINDING_UCHAR, "c_unsigned_char", \
> +	       get_unsigned_kind_from_node (unsigned_char_type_node), \
> +	       GFC_STD_UNSIGNED)
> +NAMED_UINTCST (ISOCBINDING_ULONG, "c_unsigned_long", \
> +	       get_unsigned_kind_from_node (long_unsigned_type_node), \
> +	       GFC_STD_UNSIGNED)
> +NAMED_UINTCST (ISOCBINDING_ULONGLONG, "c_unsigned_long_long", \
> +	       get_unsigned_kind_from_node (long_long_unsigned_type_node), \
> +	       GFC_STD_UNSIGNED)
> +NAMED_UINTCST (ISOCBINDING_UINTMAX_T, "c_uintmax_t", \
> +	       get_uint_kind_from_name (UINTMAX_TYPE), GFC_STD_UNSIGNED)
> +NAMED_UINTCST (ISOCBINDING_UINT8_T, "c_uint8_t", \
> +	       get_uint_kind_from_name (UINT8_TYPE), GFC_STD_UNSIGNED)
> +NAMED_UINTCST (ISOCBINDING_UINT16_T, "c_uint16_t", \
> +	       get_uint_kind_from_name (UINT16_TYPE), GFC_STD_UNSIGNED)
> +NAMED_UINTCST (ISOCBINDING_UINT32_T, "c_uint32_t", \
> +	       get_uint_kind_from_name (UINT32_TYPE), GFC_STD_UNSIGNED)
> +NAMED_UINTCST (ISOCBINDING_UINT64_T, "c_uint64_t", \
> +	       get_uint_kind_from_name (UINT64_TYPE), GFC_STD_UNSIGNED)
> +NAMED_UINTCST (ISOCBINDING_UINT128_T, "c_uint128_t", \
> +	       get_uint_kind_from_width (128), GFC_STD_UNSIGNED)
> +NAMED_UINTCST (ISOCBINDING_UINT_LEAST8_T, "c_uint_least8_t", \
> +	       get_uint_kind_from_name (UINT_LEAST8_TYPE), \
> +	       GFC_STD_UNSIGNED)
> +NAMED_UINTCST (ISOCBINDING_UINT_LEAST16_T, "c_uint_least16_t", \
> +	       get_uint_kind_from_name (UINT_LEAST16_TYPE), \
> +	       GFC_STD_UNSIGNED)
> +NAMED_UINTCST (ISOCBINDING_UINT_LEAST32_T, "c_uint_least32_t", \
> +	       get_uint_kind_from_name (UINT_LEAST32_TYPE),\
> +	       GFC_STD_UNSIGNED)
> +NAMED_UINTCST (ISOCBINDING_UINT_LEAST64_T, "c_uint_least64_t", \
> +	       get_uint_kind_from_name (UINT_LEAST64_TYPE),\
> +	       GFC_STD_UNSIGNED)
> +NAMED_UINTCST (ISOCBINDING_UINT_LEAST128_T, "c_uint_least128_t", \
> +	       get_uint_kind_from_width (128), GFC_STD_UNSIGNED)
> +NAMED_UINTCST (ISOCBINDING_UINT_FAST8_T, "c_uint_fast8_t", \
> +	       get_uint_kind_from_name (UINT_FAST8_TYPE), \
> +	       GFC_STD_UNSIGNED)
> +NAMED_UINTCST (ISOCBINDING_UINT_FAST16_T, "c_uint_fast16_t", \
> +	       get_uint_kind_from_name (UINT_FAST16_TYPE), \
> +	       GFC_STD_UNSIGNED)
> +NAMED_UINTCST (ISOCBINDING_UINT_FAST32_T, "c_uint_fast32_t", \
> +	       get_uint_kind_from_name (UINT_FAST32_TYPE),\
> +	       GFC_STD_UNSIGNED)
> +NAMED_UINTCST (ISOCBINDING_UINT_FAST64_T, "c_uint_fast64_t", \
> +	       get_uint_kind_from_name (UINT_FAST64_TYPE),\
> +	       GFC_STD_UNSIGNED)
> +NAMED_UINTCST (ISOCBINDING_UINT_FAST128_T, "c_uint_fast128_t", \
> +	       get_uint_kind_from_width (128), GFC_STD_UNSIGNED)
> +
>  #undef NAMED_INTCST
>  #undef NAMED_UINTCST
>  #undef NAMED_REALCST
> --- gcc/fortran/iso-fortran-env.def.jj	2025-01-02 11:47:32.137195494
> +0100 +++ gcc/fortran/iso-fortran-env.def	2025-01-08
> 10:11:44.946667057 +0100 @@ -17,7 +17,8 @@ along with GCC; see the file
> COPYING3. <http://www.gnu.org/licenses/>.  */
>
>  /* This file contains the definition of the named integer constants provided
> -   by the Fortran 2003 ISO_FORTRAN_ENV intrinsic module.  */
> +   by the Fortran 2003 ISO_FORTRAN_ENV intrinsic module.  The ordering of
> +   the entries matters for the *.mod backwards compatibility.  */
>
>  #ifndef NAMED_INTCST
>  # define NAMED_INTCST(a,b,c,d)
> @@ -72,20 +73,10 @@ NAMED_INTCST (ISOFORTRANENV_IOSTAT_EOR,
>  NAMED_INTCST (ISOFORTRANENV_IOSTAT_INQUIRE_INTERNAL_UNIT, \
>                "iostat_inquire_internal_unit",
> LIBERROR_INQUIRE_INTERNAL_UNIT, \ GFC_STD_F2008)
> -NAMED_INTCST (ISOFORTRANENV_LOGICAL8, "logical8", \
> -              gfc_get_int_kind_from_width_isofortranenv (8), GFC_STD_F2023)
> -NAMED_INTCST (ISOFORTRANENV_LOGICAL16, "logical16", \
> -              gfc_get_int_kind_from_width_isofortranenv (16), GFC_STD_F2023)
> -NAMED_INTCST (ISOFORTRANENV_LOGICAL32, "logical32", \
> -              gfc_get_int_kind_from_width_isofortranenv (32), GFC_STD_F2023)
> -NAMED_INTCST (ISOFORTRANENV_LOGICAL64, "logical64", \
> -              gfc_get_int_kind_from_width_isofortranenv (64), GFC_STD_F2023)
>  NAMED_INTCST (ISOFORTRANENV_NUMERIC_STORAGE_SIZE, "numeric_storage_size", \
>                gfc_numeric_storage_size, GFC_STD_F2003)
>  NAMED_INTCST (ISOFORTRANENV_OUTPUT_UNIT, "output_unit",
> GFC_STDOUT_UNIT_NUMBER, \ GFC_STD_F2003)
> -NAMED_INTCST (ISOFORTRANENV_REAL16, "real16", \
> -              gfc_get_real_kind_from_width_isofortranenv (16), GFC_STD_F2023)
>  NAMED_INTCST (ISOFORTRANENV_REAL32, "real32", \
>                gfc_get_real_kind_from_width_isofortranenv (32), GFC_STD_F2008)
>  NAMED_INTCST (ISOFORTRANENV_REAL64, "real64", \
> @@ -103,14 +94,7 @@ NAMED_INTCST (ISOFORTRANENV_FILE_STAT_FA
>                GFC_STAT_FAILED_IMAGE, GFC_STD_F2018)
>  NAMED_INTCST (ISOFORTRANENV_FILE_STAT_UNLOCKED, "stat_unlocked", \
>                GFC_STAT_UNLOCKED, GFC_STD_F2008)
> -NAMED_UINTCST (ISOFORTRANENV_UINT8, "uint8", \
> -	       gfc_get_uint_kind_from_width_isofortranenv (8),
> GFC_STD_UNSIGNED) -NAMED_UINTCST (ISOFORTRANENV_UINT16, "uint16", \
> -	       gfc_get_uint_kind_from_width_isofortranenv (16),
> GFC_STD_UNSIGNED) -NAMED_UINTCST (ISOFORTRANENV_UINT32, "uint32", \
> -	       gfc_get_uint_kind_from_width_isofortranenv (32),
> GFC_STD_UNSIGNED) -NAMED_UINTCST (ISOFORTRANENV_UINT64, "uint64", \
> -	       gfc_get_uint_kind_from_width_isofortranenv (64),
> GFC_STD_UNSIGNED) +
>
>  /* The arguments to NAMED_KINDARRAY are:
>       -- an internal name
> @@ -154,6 +138,26 @@ NAMED_DERIVED_TYPE (ISOFORTRAN_TEAM_TYPE
>  		    ? get_int_kind_from_node (ptr_type_node)
>  		    : gfc_default_integer_kind, GFC_STD_F2018)
>
> +NAMED_INTCST (ISOFORTRANENV_LOGICAL8, "logical8", \
> +              gfc_get_int_kind_from_width_isofortranenv (8), GFC_STD_F2023)
> +NAMED_INTCST (ISOFORTRANENV_LOGICAL16, "logical16", \
> +              gfc_get_int_kind_from_width_isofortranenv (16), GFC_STD_F2023)
> +NAMED_INTCST (ISOFORTRANENV_LOGICAL32, "logical32", \
> +              gfc_get_int_kind_from_width_isofortranenv (32), GFC_STD_F2023)
> +NAMED_INTCST (ISOFORTRANENV_LOGICAL64, "logical64", \
> +              gfc_get_int_kind_from_width_isofortranenv (64), GFC_STD_F2023)
> +NAMED_INTCST (ISOFORTRANENV_REAL16, "real16", \
> +              gfc_get_real_kind_from_width_isofortranenv (16), GFC_STD_F2023)
> +
> +NAMED_UINTCST (ISOFORTRANENV_UINT8, "uint8", \
> +	       gfc_get_uint_kind_from_width_isofortranenv (8),
> GFC_STD_UNSIGNED) +NAMED_UINTCST (ISOFORTRANENV_UINT16, "uint16", \
> +	       gfc_get_uint_kind_from_width_isofortranenv (16),
> GFC_STD_UNSIGNED) +NAMED_UINTCST (ISOFORTRANENV_UINT32, "uint32", \
> +	       gfc_get_uint_kind_from_width_isofortranenv (32),
> GFC_STD_UNSIGNED) +NAMED_UINTCST (ISOFORTRANENV_UINT64, "uint64", \
> +	       gfc_get_uint_kind_from_width_isofortranenv (64),
> GFC_STD_UNSIGNED) +
>  #undef NAMED_INTCST
>  #undef NAMED_UINTCST
>  #undef NAMED_KINDARRAY
>
> 	Jakub
>


--
Andre Vehreschild * Email: vehre ad gmx dot de
  
Jakub Jelinek Jan. 8, 2025, 11:50 a.m. UTC | #11
On Wed, Jan 08, 2025 at 12:42:39PM +0100, Andre Vehreschild wrote:
> Er, call me stupid, but what is the easiest way to apply your patch? 'git am' on
> the part from the date-line to the end stripping your greetings, always leads
> to unrecognized patch format. Using `patch -p1` did not work either. What am I
> not seeing?

If in the toplevel directory, then patch -p0 (but note it is on top of the
https://gcc.gnu.org/pipermail/gcc-patches/2025-January/672901.html
patch).
If inside of gcc/ subdirectory, then -p1, if inside of gcc/fortran, then
-p2.

	Jakub
  
Mikael Morin Jan. 8, 2025, 11:51 a.m. UTC | #12
Le 08/01/2025 à 12:16, Andre Vehreschild a écrit :
> That sounds like a feasible solution when finding the erroneous (to my belief)
> setting of flag takes longer than expect.
> 
> Mikael, do you know your way around the module export stuff and can you point
> me directly to the line in question? I haven't worked in that area. Just
> asking. If you don't know it, don't bother.
> 
It's in module.cc's mio_symbol_attribute which handles (separately for 
reading and writing) each attribute one by one.
Maybe it's not as easy as it seems, as the flag is also used for the 
standard "recursive" attribute, not just for self-referencing types.
  
Mikael Morin Jan. 8, 2025, 12:40 p.m. UTC | #13
Le 08/01/2025 à 11:42, Jakub Jelinek a écrit :
> 
> The full list of changes with the posted patches is
> (first a.mod, then b.mod, 14 -> 15) below.
> I have no idea what adds those __copy_* elts etc. and whether they could be
> forced to be in the middle rather than at the end and what is an ABI break
> and what is not.
> 
I think the numbers starting symbol definitions don't matter, the 
numbers represent pointers, so what matters is the structure, not the 
value; that is the number can change, and in that case it should be 
changed everywhere it is used.

For the same reason, additional symbols added in the module file in the 
middle of the list of symbol definitions don't matter.  Symbols 
definitions are basically unordered in the module file.

One value that is important, I think, is intmod_sym_id, it is used to 
map from module id to intrinsic id (which is independent of the module), 
see gfc_isym_id_by_intmod.  intmod_sym_id value is determined by the 
order in the .def file.  The value comes in the module file at the end 
of each symbol definition (see module.cc's mio_symbol), so according to 
your patches, they seem to be the same between 14 and 15 with your changes.

With that in mind, I don't see any module file incompatibility remaining 
in the differences you posted.
  
Jakub Jelinek Jan. 8, 2025, 1:13 p.m. UTC | #14
On Wed, Jan 08, 2025 at 01:40:20PM +0100, Mikael Morin wrote:
> Le 08/01/2025 à 11:42, Jakub Jelinek a écrit :
> > 
> > The full list of changes with the posted patches is
> > (first a.mod, then b.mod, 14 -> 15) below.
> > I have no idea what adds those __copy_* elts etc. and whether they could be
> > forced to be in the middle rather than at the end and what is an ABI break
> > and what is not.
> > 
> I think the numbers starting symbol definitions don't matter, the numbers
> represent pointers, so what matters is the structure, not the value; that is
> the number can change, and in that case it should be changed everywhere it
> is used.

All I know is that
--- xc_f03_lib_m.mod	2025-01-07 18:47:44.155602052 +0100
+++ xc_f03_lib_m.mod	2025-01-07 18:47:53.307400792 +0100
@@ -647,12 +647,12 @@ UNKNOWN-PROC UNKNOWN IMPLICIT-SAVE 0 0)
 UNKNOWN UNKNOWN 0 0 IS_BIND_C IS_C_INTEROP PRIVATE_COMP) ((818 'c_address'
 (INTEGER 8 0 1 0 INTEGER ()) () () () (UNKNOWN-FL UNKNOWN-INTENT
 UNKNOWN-PROC UNKNOWN UNKNOWN 0 0) PRIVATE ())) PRIVATE (DERIVED 6 0 1 1
-VOID ()) 0 0 () () 0 () () () 2 42 0)
+VOID ()) 0 0 () () 0 () () () 2 63 0)
 10 'C_funptr' '__iso_c_binding' '' 1 ((DERIVED UNKNOWN-INTENT
 UNKNOWN-PROC UNKNOWN UNKNOWN 0 0 IS_BIND_C IS_C_INTEROP PRIVATE_COMP) (
 (819 'c_address' (INTEGER 8 0 1 0 INTEGER ()) () () () (UNKNOWN-FL
 UNKNOWN-INTENT UNKNOWN-PROC UNKNOWN UNKNOWN 0 0) PRIVATE ())) PRIVATE (
-DERIVED 10 0 1 1 VOID ()) 0 0 () () 0 () () () 2 44 0)
+DERIVED 10 0 1 1 VOID ()) 0 0 () () 0 () () () 2 65 0)
 30 '__copy___iso_c_binding_C_funptr' 'xc_f03_lib_m' '' 820 ((PROCEDURE
 UNKNOWN-INTENT UNKNOWN-PROC DECL UNKNOWN 0 0 ARTIFICIAL SUBROUTINE
 ELEMENTAL PURE ALWAYS_EXPLICIT) () (UNKNOWN 0 0 0 0 UNKNOWN ()) 0 0 (
changes in libxc-devel xc_f03_lib_m.mod cause various ICEs as I wrote in the
PR when using the GCC 14 compiled mod file with GCC 15.

Here is a short reproducer:
/usr/src/gcc-15/obj/gcc/f951 -quiet libxc_master.f90
/usr/src/gcc-15/obj/gcc/f951 -quiet fu.f90
This compiles fine
/usr/src/gcc-14/obj/gcc/f951 -quiet libxc_master.f90
/usr/src/gcc-15/obj/gcc/f951 -quiet fu.f90
fu.f90:10:18:

   10 | end subroutine foo
      |                  1
internal compiler error: tree check: expected record_type or union_type or qual_union_type, have pointer_type in gfc_trans_structure_assign, at fortran/trans-expr.cc:9906
0x2d322df internal_error(char const*, ...)
	../../gcc/diagnostic-global-context.cc:517
0x12fd1d3 tree_check_failed(tree_node const*, char const*, int, char const*, ...)
	../../gcc/tree.cc:9044
0x5b6939 tree_check3(tree_node*, char const*, int, char const*, tree_code, tree_code, tree_code)
	../../gcc/tree.h:3705
0x602a93 gfc_trans_structure_assign(tree_node*, gfc_expr*, bool, bool)
	../../gcc/fortran/trans-expr.cc:9906
0x6033c3 gfc_conv_structure(gfc_se*, gfc_expr*, int)
	../../gcc/fortran/trans-expr.cc:10063
0x603bb3 gfc_conv_expr(gfc_se*, gfc_expr*)
	../../gcc/fortran/trans-expr.cc:10231
0x602815 gfc_trans_subcomponent_assign
	../../gcc/fortran/trans-expr.cc:9864
0x60303e gfc_trans_structure_assign(tree_node*, gfc_expr*, bool, bool)
	../../gcc/fortran/trans-expr.cc:9997
0x6033c3 gfc_conv_structure(gfc_se*, gfc_expr*, int)
	../../gcc/fortran/trans-expr.cc:10063
0x603bb3 gfc_conv_expr(gfc_se*, gfc_expr*)
	../../gcc/fortran/trans-expr.cc:10231
0x60cad7 gfc_trans_assignment_1
	../../gcc/fortran/trans-expr.cc:12806
0x60dfc8 gfc_trans_assignment(gfc_expr*, gfc_expr*, bool, bool, bool, bool)
	../../gcc/fortran/trans-expr.cc:13213
0x5ce01c gfc_init_default_dt(gfc_symbol*, stmtblock_t*, bool)
	../../gcc/fortran/trans-decl.cc:4487
0x5d0cdc gfc_trans_deferred_vars(gfc_symbol*, gfc_wrapped_block*)
	../../gcc/fortran/trans-decl.cc:5266
0x5dc20b gfc_generate_function_code(gfc_namespace*)
	../../gcc/fortran/trans-decl.cc:8148
0x58e092 gfc_generate_module_code(gfc_namespace*)
	../../gcc/fortran/trans.cc:2764
0x5058b8 translate_all_program_units
	../../gcc/fortran/parse.cc:7216
0x5062b7 gfc_parse_file()
	../../gcc/fortran/parse.cc:7546
0x573b33 gfc_be_parse_file
	../../gcc/fortran/f95-lang.cc:241
Please submit a full bug report, with preprocessed source (by using -freport-bug).
Please include the complete backtrace with any bug report.
See <https://gcc.gnu.org/bugs/> for instructions.

	Jakub
module xc_f03_lib_m
  use, intrinsic :: iso_c_binding
  implicit none

  private
  public :: xc_f03_func_t, xc_f03_func_info_t, &
            xc_f03_func_init

  integer(c_int), parameter, public :: XC_UNPOLARIZED = 1

  type :: xc_f03_func_t
    private
    type(c_ptr) :: ptr = C_NULL_PTR
  end type xc_f03_func_t

  type :: xc_f03_func_info_t
    private
    type(c_ptr) :: ptr = C_NULL_PTR
  end type xc_f03_func_info_t

  interface
    type(c_ptr) function xc_func_alloc() bind(c)
      import
    end function xc_func_alloc

    integer(c_int) function xc_func_init(p, functional, nspin) bind(c)
      import
      type(c_ptr),    value :: p
      integer(c_int), value :: functional, nspin
    end function xc_func_init
  end interface

  contains
  subroutine xc_f03_func_init(p, functional, nspin, err)
    type(xc_f03_func_t),      intent(inout) :: p
    integer(c_int),           intent(in)    :: functional
    integer(c_int),           intent(in)    :: nspin
    integer(c_int), optional, intent(out)   :: err

    integer(c_int) :: ierr

    p%ptr = xc_func_alloc()
    ierr = xc_func_init(p%ptr, functional, nspin)

    if(present(err)) err = ierr
  end subroutine xc_f03_func_init
end module xc_f03_lib_m
module fu
implicit none
private
public :: foo
contains
subroutine foo()
  use xc_f03_lib_m, only: xc_f03_func_info_t, xc_f03_func_init, xc_f03_func_t, XC_UNPOLARIZED
  type(xc_f03_func_t) :: func
  call xc_f03_func_init(func,1_4,xc_unpolarized)
end subroutine foo
end module fu
  
Mikael Morin Jan. 8, 2025, 2:16 p.m. UTC | #15
Le 08/01/2025 à 14:13, Jakub Jelinek a écrit :
> On Wed, Jan 08, 2025 at 01:40:20PM +0100, Mikael Morin wrote:
>> Le 08/01/2025 à 11:42, Jakub Jelinek a écrit :
>>>
>>> The full list of changes with the posted patches is
>>> (first a.mod, then b.mod, 14 -> 15) below.
>>> I have no idea what adds those __copy_* elts etc. and whether they could be
>>> forced to be in the middle rather than at the end and what is an ABI break
>>> and what is not.
>>>
>> I think the numbers starting symbol definitions don't matter, the numbers
>> represent pointers, so what matters is the structure, not the value; that is
>> the number can change, and in that case it should be changed everywhere it
>> is used.
> 
This is only true for numbers representing pointers and especially 
symbol pointers, that is number that start a symbol definition (like 10 
in front of 'C_funptr' or 30 in front of 
'__copy__iso_c_binding_C_funptr' in your excerpt below), or other places 
with symbol pointers.

> All I know is that
> --- xc_f03_lib_m.mod	2025-01-07 18:47:44.155602052 +0100
> +++ xc_f03_lib_m.mod	2025-01-07 18:47:53.307400792 +0100
> @@ -647,12 +647,12 @@ UNKNOWN-PROC UNKNOWN IMPLICIT-SAVE 0 0)
>   UNKNOWN UNKNOWN 0 0 IS_BIND_C IS_C_INTEROP PRIVATE_COMP) ((818 'c_address'
>   (INTEGER 8 0 1 0 INTEGER ()) () () () (UNKNOWN-FL UNKNOWN-INTENT
>   UNKNOWN-PROC UNKNOWN UNKNOWN 0 0) PRIVATE ())) PRIVATE (DERIVED 6 0 1 1
> -VOID ()) 0 0 () () 0 () () () 2 42 0)
> +VOID ()) 0 0 () () 0 () () () 2 63 0)
>   10 'C_funptr' '__iso_c_binding' '' 1 ((DERIVED UNKNOWN-INTENT
>   UNKNOWN-PROC UNKNOWN UNKNOWN 0 0 IS_BIND_C IS_C_INTEROP PRIVATE_COMP) (
>   (819 'c_address' (INTEGER 8 0 1 0 INTEGER ()) () () () (UNKNOWN-FL
>   UNKNOWN-INTENT UNKNOWN-PROC UNKNOWN UNKNOWN 0 0) PRIVATE ())) PRIVATE (
> -DERIVED 10 0 1 1 VOID ()) 0 0 () () 0 () () () 2 44 0)
> +DERIVED 10 0 1 1 VOID ()) 0 0 () () 0 () () () 2 65 0)
>   30 '__copy___iso_c_binding_C_funptr' 'xc_f03_lib_m' '' 820 ((PROCEDURE
>   UNKNOWN-INTENT UNKNOWN-PROC DECL UNKNOWN 0 0 ARTIFICIAL SUBROUTINE
>   ELEMENTAL PURE ALWAYS_EXPLICIT) () (UNKNOWN 0 0 0 0 UNKNOWN ()) 0 0 (
> changes in libxc-devel xc_f03_lib_m.mod cause various ICEs as I wrote in the
> PR when using the GCC 14 compiled mod file with GCC 15.
> Sure, but here, the modified value doesn't represent a symbol pointer, 
so what I said above doesn't apply.  I think it is the int_mod_sym_id 
value that changed, and we should try to avoid that for compatibility 
(which your patch does).

I think your patch is enough, we don't need to target same-bytes formats 
between module versions.
  
Jakub Jelinek Jan. 8, 2025, 2:26 p.m. UTC | #16
On Wed, Jan 08, 2025 at 03:16:46PM +0100, Mikael Morin wrote:
> I think your patch is enough, we don't need to target same-bytes formats
> between module versions.

I can confirm the ICE on the small reproducer I've posted is gone with the
https://gcc.gnu.org/pipermail/gcc-patches/2025-January/672901.html
https://gcc.gnu.org/pipermail/gcc-patches/2025-January/672905.html
patches.

So, is the first one ok for trunk (that is one I've fully tested already)
and the second one too if it passes bootstrap/regtest?

	Jakub
  
Andre Vehreschild Jan. 8, 2025, 2:48 p.m. UTC | #17
Hi,

I have added this small patch (attached). Unfortunately I got regressions

some in iso_fortran_env_8.f90
and several in unsigned_NN.f90 tests.

Just retesting w/o my patch and already seeing the iso_fortran_env one again.
I am also not totally sure, that I applied both your patches correctly. But
they applied w/o issues with patch -p0.

Regards,
	Andre


On Wed, 8 Jan 2025 15:26:58 +0100
Jakub Jelinek <jakub@redhat.com> wrote:

> On Wed, Jan 08, 2025 at 03:16:46PM +0100, Mikael Morin wrote:
> > I think your patch is enough, we don't need to target same-bytes formats
> > between module versions.
>
> I can confirm the ICE on the small reproducer I've posted is gone with the
> https://gcc.gnu.org/pipermail/gcc-patches/2025-January/672901.html
> https://gcc.gnu.org/pipermail/gcc-patches/2025-January/672905.html
> patches.
>
> So, is the first one ok for trunk (that is one I've fully tested already)
> and the second one too if it passes bootstrap/regtest?
>
> 	Jakub
>


--
Andre Vehreschild * Email: vehre ad gmx dot de
  
Jakub Jelinek Jan. 8, 2025, 2:59 p.m. UTC | #18
On Wed, Jan 08, 2025 at 03:48:46PM +0100, Andre Vehreschild wrote:
> Hi,
> 
> I have added this small patch (attached). Unfortunately I got regressions
> 
> some in iso_fortran_env_8.f90
> and several in unsigned_NN.f90 tests.
> 
> Just retesting w/o my patch and already seeing the iso_fortran_env one again.
> I am also not totally sure, that I applied both your patches correctly. But
> they applied w/o issues with patch -p0.

I can reproduce it.  It is the second patch, will try to debug...

	Jakub
  
Andre Vehreschild Jan. 8, 2025, 3:09 p.m. UTC | #19
One of the issues are lines:

module.cc 7125-7130: Here it is assumed that the signed and unsigned types are
adjacent maybe?!

I have changed this:

diff --git a/gcc/fortran/module.cc b/gcc/fortran/module.cc
index c4312b641c1..05bc802957e 100644
--- a/gcc/fortran/module.cc
+++ b/gcc/fortran/module.cc
@@ -7113,8 +7113,8 @@ use_iso_fortran_env_module (void)
   int i, j;

   intmod_sym symbol[] = {
-#define NAMED_INTCST(a,b,c,d) { a, b, 0, d },
-#define NAMED_UINTCST(a,b,c,d) { a, b, 0, d },
+#define NAMED_INTCST(a, b, c, d) {a, b, c, d},
+#define NAMED_UINTCST(a, b, c, d) {a, b, c, d},
 #define NAMED_KINDARRAY(a,b,c,d) { a, b, 0, d },
 #define NAMED_DERIVED_TYPE(a,b,c,d) { a, b, 0, d },
 #define NAMED_FUNCTION(a,b,c,d) { a, b, c, d },
@@ -7122,12 +7122,12 @@ use_iso_fortran_env_module (void)
 #include "iso-fortran-env.def"
     { ISOFORTRANENV_INVALID, NULL, -1234, 0 } };

-  i = 0;
-#define NAMED_INTCST(a,b,c,d) symbol[i++].value = c;
-#include "iso-fortran-env.def"
+  //   i = 0;
+  // #define NAMED_INTCST(a,b,c,d) symbol[i++].value = c;
+  // #include "iso-fortran-env.def"

-#define NAMED_UINTCST(a,b,c,d) symbol[i++].value = c;
-#include "iso-fortran-env.def"
+  // #define NAMED_UINTCST(a,b,c,d) symbol[i++].value = c;
+  // #include "iso-fortran-env.def"

   /* Generate the symbol for the module itself.  */
   mod_symtree = gfc_find_symtree (gfc_current_ns->sym_root, mod);


And at least iso_fortran_env_8.f90 does not fail anymore.

Now regtesting.

- Andre
On Wed, 8 Jan 2025 15:59:43 +0100
Jakub Jelinek <jakub@redhat.com> wrote:

> On Wed, Jan 08, 2025 at 03:48:46PM +0100, Andre Vehreschild wrote:
> > Hi,
> >
> > I have added this small patch (attached). Unfortunately I got regressions
> >
> > some in iso_fortran_env_8.f90
> > and several in unsigned_NN.f90 tests.
> >
> > Just retesting w/o my patch and already seeing the iso_fortran_env one
> > again. I am also not totally sure, that I applied both your patches
> > correctly. But they applied w/o issues with patch -p0.
>
> I can reproduce it.  It is the second patch, will try to debug...
>
> 	Jakub
>


--
Andre Vehreschild * Email: vehre ad gmx dot de
  
Jakub Jelinek Jan. 8, 2025, 3:34 p.m. UTC | #20
On Wed, Jan 08, 2025 at 04:09:36PM +0100, Andre Vehreschild wrote:
> One of the issues are lines:
> 
> module.cc 7125-7130: Here it is assumed that the signed and unsigned types are
> adjacent maybe?!
> 
> I have changed this:
> 
> diff --git a/gcc/fortran/module.cc b/gcc/fortran/module.cc
> index c4312b641c1..05bc802957e 100644
> --- a/gcc/fortran/module.cc
> +++ b/gcc/fortran/module.cc
> @@ -7113,8 +7113,8 @@ use_iso_fortran_env_module (void)
>    int i, j;
> 
>    intmod_sym symbol[] = {
> -#define NAMED_INTCST(a,b,c,d) { a, b, 0, d },
> -#define NAMED_UINTCST(a,b,c,d) { a, b, 0, d },
> +#define NAMED_INTCST(a, b, c, d) {a, b, c, d},
> +#define NAMED_UINTCST(a, b, c, d) {a, b, c, d},
>  #define NAMED_KINDARRAY(a,b,c,d) { a, b, 0, d },
>  #define NAMED_DERIVED_TYPE(a,b,c,d) { a, b, 0, d },
>  #define NAMED_FUNCTION(a,b,c,d) { a, b, c, d },
> @@ -7122,12 +7122,12 @@ use_iso_fortran_env_module (void)
>  #include "iso-fortran-env.def"
>      { ISOFORTRANENV_INVALID, NULL, -1234, 0 } };
> 
> -  i = 0;
> -#define NAMED_INTCST(a,b,c,d) symbol[i++].value = c;
> -#include "iso-fortran-env.def"
> +  //   i = 0;
> +  // #define NAMED_INTCST(a,b,c,d) symbol[i++].value = c;
> +  // #include "iso-fortran-env.def"
> 
> -#define NAMED_UINTCST(a,b,c,d) symbol[i++].value = c;
> -#include "iso-fortran-env.def"
> +  // #define NAMED_UINTCST(a,b,c,d) symbol[i++].value = c;
> +  // #include "iso-fortran-env.def"
> 
>    /* Generate the symbol for the module itself.  */
>    mod_symtree = gfc_find_symtree (gfc_current_ns->sym_root, mod);
> 
> 
> And at least iso_fortran_env_8.f90 does not fail anymore.

I'm testing for that instead:
--- gcc/module.cc.jj	2025-01-08 15:23:54.511732946 +0100
+++ gcc/module.cc	2025-01-08 16:32:14.963984426 +0100
@@ -7122,9 +7122,11 @@ use_iso_fortran_env_module (void)
 
   i = 0;
 #define NAMED_INTCST(a,b,c,d) symbol[i++].value = c;
-#include "iso-fortran-env.def"
-
 #define NAMED_UINTCST(a,b,c,d) symbol[i++].value = c;
+#define NAMED_KINDARRAY(a,b,c,d) i++;
+#define NAMED_DERIVED_TYPE(a,b,c,d) i++;
+#define NAMED_FUNCTION(a,b,c,d) i++;
+#define NAMED_SUBROUTINE(a,b,c,d) i++;
 #include "iso-fortran-env.def"
 
   /* Generate the symbol for the module itself.  */

	Jakub
  
Andre Vehreschild Jan. 8, 2025, 5:23 p.m. UTC | #21
Hi all,

I like to take Jakub's patch a little bit further and add two things, that
annoy me:

First of all the recursive attr must not be set on vtypes, neither on module
ones nor anywhere else. Strictly speaking is a vtype recursive, because by its
extends member it references itself through a pointer. But it is guaranteed
that the base type is never the same as the extended one. So no cycle can
occur. Furthermore are vtypes never freeed nor copied (yet). So the flag is not
needed which the patch starting with 0002 ensures.

Secondly is the third parameter of the macro in the iso-fortran-env.def file a
type kind, i.e. an integer. I see no reason why there is that special treatment
in module.cc. The kinds can not be defined in iso-fortran-env and therefore no
hither and further referencing is possible. Including the file again, just
relying on order in the file, is in my opinion dangerous. And if required
must have been documented thoroughly, what I don't see. Just storing the kind
immediately as it is done by the patch starting with 0003 does all that is
needed.

I have included Jakub's original patch as 0001-* for easier application with
`git am` and testing it yourself.

Regtests ok on x86_64-pc-linux-gnu / F41. Ok for mainline?

Regards and many thanks to all your valued input and patches,
	Andre

On Wed, 8 Jan 2025 16:34:18 +0100
Jakub Jelinek <jakub@redhat.com> wrote:

> On Wed, Jan 08, 2025 at 04:09:36PM +0100, Andre Vehreschild wrote:
> > One of the issues are lines:
> >
> > module.cc 7125-7130: Here it is assumed that the signed and unsigned types
> > are adjacent maybe?!
> >
> > I have changed this:
> >
> > diff --git a/gcc/fortran/module.cc b/gcc/fortran/module.cc
> > index c4312b641c1..05bc802957e 100644
> > --- a/gcc/fortran/module.cc
> > +++ b/gcc/fortran/module.cc
> > @@ -7113,8 +7113,8 @@ use_iso_fortran_env_module (void)
> >    int i, j;
> >
> >    intmod_sym symbol[] = {
> > -#define NAMED_INTCST(a,b,c,d) { a, b, 0, d },
> > -#define NAMED_UINTCST(a,b,c,d) { a, b, 0, d },
> > +#define NAMED_INTCST(a, b, c, d) {a, b, c, d},
> > +#define NAMED_UINTCST(a, b, c, d) {a, b, c, d},
> >  #define NAMED_KINDARRAY(a,b,c,d) { a, b, 0, d },
> >  #define NAMED_DERIVED_TYPE(a,b,c,d) { a, b, 0, d },
> >  #define NAMED_FUNCTION(a,b,c,d) { a, b, c, d },
> > @@ -7122,12 +7122,12 @@ use_iso_fortran_env_module (void)
> >  #include "iso-fortran-env.def"
> >      { ISOFORTRANENV_INVALID, NULL, -1234, 0 } };
> >
> > -  i = 0;
> > -#define NAMED_INTCST(a,b,c,d) symbol[i++].value = c;
> > -#include "iso-fortran-env.def"
> > +  //   i = 0;
> > +  // #define NAMED_INTCST(a,b,c,d) symbol[i++].value = c;
> > +  // #include "iso-fortran-env.def"
> >
> > -#define NAMED_UINTCST(a,b,c,d) symbol[i++].value = c;
> > -#include "iso-fortran-env.def"
> > +  // #define NAMED_UINTCST(a,b,c,d) symbol[i++].value = c;
> > +  // #include "iso-fortran-env.def"
> >
> >    /* Generate the symbol for the module itself.  */
> >    mod_symtree = gfc_find_symtree (gfc_current_ns->sym_root, mod);
> >
> >
> > And at least iso_fortran_env_8.f90 does not fail anymore.
>
> I'm testing for that instead:
> --- gcc/module.cc.jj	2025-01-08 15:23:54.511732946 +0100
> +++ gcc/module.cc	2025-01-08 16:32:14.963984426 +0100
> @@ -7122,9 +7122,11 @@ use_iso_fortran_env_module (void)
>
>    i = 0;
>  #define NAMED_INTCST(a,b,c,d) symbol[i++].value = c;
> -#include "iso-fortran-env.def"
> -
>  #define NAMED_UINTCST(a,b,c,d) symbol[i++].value = c;
> +#define NAMED_KINDARRAY(a,b,c,d) i++;
> +#define NAMED_DERIVED_TYPE(a,b,c,d) i++;
> +#define NAMED_FUNCTION(a,b,c,d) i++;
> +#define NAMED_SUBROUTINE(a,b,c,d) i++;
>  #include "iso-fortran-env.def"
>
>    /* Generate the symbol for the module itself.  */
>
> 	Jakub
>


--
Andre Vehreschild * Email: vehre ad gmx dot de
  
Jakub Jelinek Jan. 8, 2025, 5:37 p.m. UTC | #22
On Wed, Jan 08, 2025 at 06:23:40PM +0100, Andre Vehreschild wrote:
> gcc/fortran/ChangeLog:
> 
> 	PR fortran/118337
> 	* module.cc (use_iso_fortran_env_module): Prevent additional run
> 	over (un-)signed ints and assign kind directly.
> ---
>  gcc/fortran/module.cc | 13 ++-----------
>  1 file changed, 2 insertions(+), 11 deletions(-)
> 
> diff --git a/gcc/fortran/module.cc b/gcc/fortran/module.cc
> index de8df05781d..8dc10e1d349 100644
> --- a/gcc/fortran/module.cc
> +++ b/gcc/fortran/module.cc
> @@ -7113,8 +7113,8 @@ use_iso_fortran_env_module (void)
>    int i, j;
> 
>    intmod_sym symbol[] = {
> -#define NAMED_INTCST(a,b,c,d) { a, b, 0, d },
> -#define NAMED_UINTCST(a,b,c,d) { a, b, 0, d },
> +#define NAMED_INTCST(a, b, c, d) {a, b, c, d},
> +#define NAMED_UINTCST(a, b, c, d) {a, b, c, d},
>  #define NAMED_KINDARRAY(a,b,c,d) { a, b, 0, d },
>  #define NAMED_DERIVED_TYPE(a,b,c,d) { a, b, 0, d },
>  #define NAMED_FUNCTION(a,b,c,d) { a, b, c, d },
> @@ -7122,15 +7122,6 @@ use_iso_fortran_env_module (void)
>  #include "iso-fortran-env.def"
>      { ISOFORTRANENV_INVALID, NULL, -1234, 0 } };
> 
> -  i = 0;
> -#define NAMED_INTCST(a,b,c,d) symbol[i++].value = c;
> -#define NAMED_UINTCST(a,b,c,d) symbol[i++].value = c;
> -#define NAMED_KINDARRAY(a,b,c,d) i++;
> -#define NAMED_DERIVED_TYPE(a,b,c,d) i++;
> -#define NAMED_FUNCTION(a,b,c,d) i++;
> -#define NAMED_SUBROUTINE(a,b,c,d) i++;
> -#include "iso-fortran-env.def"
> -

I thought the reason was that NAMED_{,U}INTCST c is non-constant
while everything else is constant and the source trying to help
the C++ compiler to emit decent code for it.
Though, I think g++ will end up doing pretty much the same thing,
split the non-constant parts of the initializer into statements overwriting
values in the variable and using 0 for that in the initializer before
it is overwritten.

Anyway, if you go with your patch, please use { a, b, c, d },
rather than {a, b, c, d}, for consistency with surrounding code.

	Jakub
  
Mikael Morin Jan. 8, 2025, 9:41 p.m. UTC | #23
Le 08/01/2025 à 18:37, Jakub Jelinek a écrit :
> On Wed, Jan 08, 2025 at 06:23:40PM +0100, Andre Vehreschild wrote:
>> gcc/fortran/ChangeLog:
>>
>> 	PR fortran/118337
>> 	* module.cc (use_iso_fortran_env_module): Prevent additional run
>> 	over (un-)signed ints and assign kind directly.
>> ---
>>   gcc/fortran/module.cc | 13 ++-----------
>>   1 file changed, 2 insertions(+), 11 deletions(-)
>>
>> diff --git a/gcc/fortran/module.cc b/gcc/fortran/module.cc
>> index de8df05781d..8dc10e1d349 100644
>> --- a/gcc/fortran/module.cc
>> +++ b/gcc/fortran/module.cc
>> @@ -7113,8 +7113,8 @@ use_iso_fortran_env_module (void)
>>     int i, j;
>>
>>     intmod_sym symbol[] = {
>> -#define NAMED_INTCST(a,b,c,d) { a, b, 0, d },
>> -#define NAMED_UINTCST(a,b,c,d) { a, b, 0, d },
>> +#define NAMED_INTCST(a, b, c, d) {a, b, c, d},
>> +#define NAMED_UINTCST(a, b, c, d) {a, b, c, d},
>>   #define NAMED_KINDARRAY(a,b,c,d) { a, b, 0, d },
>>   #define NAMED_DERIVED_TYPE(a,b,c,d) { a, b, 0, d },
>>   #define NAMED_FUNCTION(a,b,c,d) { a, b, c, d },
>> @@ -7122,15 +7122,6 @@ use_iso_fortran_env_module (void)
>>   #include "iso-fortran-env.def"
>>       { ISOFORTRANENV_INVALID, NULL, -1234, 0 } };
>>
>> -  i = 0;
>> -#define NAMED_INTCST(a,b,c,d) symbol[i++].value = c;
>> -#define NAMED_UINTCST(a,b,c,d) symbol[i++].value = c;
>> -#define NAMED_KINDARRAY(a,b,c,d) i++;
>> -#define NAMED_DERIVED_TYPE(a,b,c,d) i++;
>> -#define NAMED_FUNCTION(a,b,c,d) i++;
>> -#define NAMED_SUBROUTINE(a,b,c,d) i++;
>> -#include "iso-fortran-env.def"
>> -
> 
> I thought the reason was that NAMED_{,U}INTCST c is non-constant
> while everything else is constant and the source trying to help
> the C++ compiler to emit decent code for it.

> Though, I think g++ will end up doing pretty much the same thing,
> split the non-constant parts of the initializer into statements overwriting
> values in the variable and using 0 for that in the initializer before
> it is overwritten.
> 
I have double-checked that, and it doesn't seem to be the case, at least 
according to the .optimized dump.  So I'm inclined to prefer the 
two-stages initialization version.
Maybe we can add an assert making sure that i remain synced through the 
second stage?
That would be something like gcc_checking_assert (symbol[i].id == a);
  
Mikael Morin Jan. 8, 2025, 9:46 p.m. UTC | #24
Le 08/01/2025 à 18:23, Andre Vehreschild a écrit :
> 
> First of all the recursive attr must not be set on vtypes, neither on module
> ones nor anywhere else. Strictly speaking is a vtype recursive, because by its
> extends member it references itself through a pointer. But it is guaranteed
> that the base type is never the same as the extended one. So no cycle can
> occur. Furthermore are vtypes never freeed nor copied (yet). So the flag is not
> needed which the patch starting with 0002 ensures.
> 

> From d0b43ccb141dbec998e81fd437f7f1a02bd74731 Mon Sep 17 00:00:00 2001
> From: Andre Vehreschild <vehre@gcc.gnu.org>
> Date: Wed, 8 Jan 2025 14:58:35 +0100
> Subject: [PATCH 2/3] Fortran: Cylce detection for non vtypes only. [PR118337]
> 
> gcc/fortran/ChangeLog:
> 
> 	PR fortran/118337
> 
> 	* resolve.cc (resolve_fl_derived0): Exempt vtypes from cycle
> 	detection.
> ---
>  gcc/fortran/resolve.cc | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/gcc/fortran/resolve.cc b/gcc/fortran/resolve.cc
> index 6dcda70679f..dab0c3af601 100644
> --- a/gcc/fortran/resolve.cc
> +++ b/gcc/fortran/resolve.cc
> @@ -16840,7 +16840,8 @@ resolve_fl_derived0 (gfc_symbol *sym)
> 
>    /* Resolving components below, may create vtabs for which the cyclic type
>       information needs to be present.  */
> -  resolve_cyclic_derived_type (sym);
> +  if (!sym->attr.vtype)
> +    resolve_cyclic_derived_type (sym);
> 
>    c = (sym->attr.is_class) ? CLASS_DATA (sym->components)
>  			   : sym->components;
> --
> 2.47.1

OK.
  
Andre Vehreschild Jan. 9, 2025, 10:32 a.m. UTC | #25
Hi all,

I am sorry, I don't get it. So we are trying to help the compiler, i.e. the C++
one, to create a fast gfortran binary. But we don't care about devs that stumble
about the code and ask themselves, "Why is this done (without a comment) so
oddly?"! Furthermore is the code again using convention or inside knowledge:

  intmod_sym symbol[] = {
#define NAMED_INTCST(a,b,c,d) { a, b, 0, d },
#define NAMED_UINTCST(a,b,c,d) { a, b, 0, d },
#define NAMED_KINDARRAY(a,b,c,d) { a, b, 0, d },
#define NAMED_DERIVED_TYPE(a,b,c,d) { a, b, 0, d },
#define NAMED_FUNCTION(a,b,c,d) { a, b, c, d },
#define NAMED_SUBROUTINE(a,b,c,d) { a, b, c, d },

So in function and subroutine definitions `c` may become non-constant in the
future and we neither detect it nor care. 

#include "iso-fortran-env.def"
    { ISOFORTRANENV_INVALID, NULL, -1234, 0 } };

  i = 0;
#define NAMED_INTCST(a,b,c,d) symbol[i++].value = c;
#define NAMED_UINTCST(a,b,c,d) symbol[i++].value = c;
#define NAMED_KINDARRAY(a,b,c,d) i++;
#define NAMED_DERIVED_TYPE(a,b,c,d) i++;
#define NAMED_FUNCTION(a,b,c,d) i++;
#define NAMED_SUBROUTINE(a,b,c,d) i++;
#include "iso-fortran-env.def"

So why not at least adding a comment to document this design decision and I
would also propose to be consequent and also set `c` for functions and
subroutines in the second part. Just to have it similar. You know the
design "principle of least confusion"?!

A confused
	Andre


On Wed, 8 Jan 2025 22:41:13 +0100
Mikael Morin <morin-mikael@orange.fr> wrote:

> Le 08/01/2025 à 18:37, Jakub Jelinek a écrit :
> > On Wed, Jan 08, 2025 at 06:23:40PM +0100, Andre Vehreschild wrote:  
> >> gcc/fortran/ChangeLog:
> >>
> >> 	PR fortran/118337
> >> 	* module.cc (use_iso_fortran_env_module): Prevent additional run
> >> 	over (un-)signed ints and assign kind directly.
> >> ---
> >>   gcc/fortran/module.cc | 13 ++-----------
> >>   1 file changed, 2 insertions(+), 11 deletions(-)
> >>
> >> diff --git a/gcc/fortran/module.cc b/gcc/fortran/module.cc
> >> index de8df05781d..8dc10e1d349 100644
> >> --- a/gcc/fortran/module.cc
> >> +++ b/gcc/fortran/module.cc
> >> @@ -7113,8 +7113,8 @@ use_iso_fortran_env_module (void)
> >>     int i, j;
> >>
> >>     intmod_sym symbol[] = {
> >> -#define NAMED_INTCST(a,b,c,d) { a, b, 0, d },
> >> -#define NAMED_UINTCST(a,b,c,d) { a, b, 0, d },
> >> +#define NAMED_INTCST(a, b, c, d) {a, b, c, d},
> >> +#define NAMED_UINTCST(a, b, c, d) {a, b, c, d},
> >>   #define NAMED_KINDARRAY(a,b,c,d) { a, b, 0, d },
> >>   #define NAMED_DERIVED_TYPE(a,b,c,d) { a, b, 0, d },
> >>   #define NAMED_FUNCTION(a,b,c,d) { a, b, c, d },
> >> @@ -7122,15 +7122,6 @@ use_iso_fortran_env_module (void)
> >>   #include "iso-fortran-env.def"
> >>       { ISOFORTRANENV_INVALID, NULL, -1234, 0 } };
> >>
> >> -  i = 0;
> >> -#define NAMED_INTCST(a,b,c,d) symbol[i++].value = c;
> >> -#define NAMED_UINTCST(a,b,c,d) symbol[i++].value = c;
> >> -#define NAMED_KINDARRAY(a,b,c,d) i++;
> >> -#define NAMED_DERIVED_TYPE(a,b,c,d) i++;
> >> -#define NAMED_FUNCTION(a,b,c,d) i++;
> >> -#define NAMED_SUBROUTINE(a,b,c,d) i++;
> >> -#include "iso-fortran-env.def"
> >> -  
> > 
> > I thought the reason was that NAMED_{,U}INTCST c is non-constant
> > while everything else is constant and the source trying to help
> > the C++ compiler to emit decent code for it.  
> 
> > Though, I think g++ will end up doing pretty much the same thing,
> > split the non-constant parts of the initializer into statements overwriting
> > values in the variable and using 0 for that in the initializer before
> > it is overwritten.
> >   
> I have double-checked that, and it doesn't seem to be the case, at least 
> according to the .optimized dump.  So I'm inclined to prefer the 
> two-stages initialization version.
> Maybe we can add an assert making sure that i remain synced through the 
> second stage?
> That would be something like gcc_checking_assert (symbol[i].id == a);
>
  
Andre Vehreschild Jan. 9, 2025, 11:23 a.m. UTC | #26
Hi Mikael,

merged only patch #2 as gcc-15-6729-gd1071402055. 

Thanks for the ok and regards,
	Andre

On Wed, 8 Jan 2025 22:46:15 +0100
Mikael Morin <morin-mikael@orange.fr> wrote:

> Le 08/01/2025 à 18:23, Andre Vehreschild a écrit :
> > 
> > First of all the recursive attr must not be set on vtypes, neither on module
> > ones nor anywhere else. Strictly speaking is a vtype recursive, because by
> > its extends member it references itself through a pointer. But it is
> > guaranteed that the base type is never the same as the extended one. So no
> > cycle can occur. Furthermore are vtypes never freeed nor copied (yet). So
> > the flag is not needed which the patch starting with 0002 ensures.
> >   
> 
> > From d0b43ccb141dbec998e81fd437f7f1a02bd74731 Mon Sep 17 00:00:00 2001
> > From: Andre Vehreschild <vehre@gcc.gnu.org>
> > Date: Wed, 8 Jan 2025 14:58:35 +0100
> > Subject: [PATCH 2/3] Fortran: Cylce detection for non vtypes only.
> > [PR118337]
> > 
> > gcc/fortran/ChangeLog:
> > 
> > 	PR fortran/118337
> > 
> > 	* resolve.cc (resolve_fl_derived0): Exempt vtypes from cycle
> > 	detection.
> > ---
> >  gcc/fortran/resolve.cc | 3 ++-
> >  1 file changed, 2 insertions(+), 1 deletion(-)
> > 
> > diff --git a/gcc/fortran/resolve.cc b/gcc/fortran/resolve.cc
> > index 6dcda70679f..dab0c3af601 100644
> > --- a/gcc/fortran/resolve.cc
> > +++ b/gcc/fortran/resolve.cc
> > @@ -16840,7 +16840,8 @@ resolve_fl_derived0 (gfc_symbol *sym)
> > 
> >    /* Resolving components below, may create vtabs for which the cyclic type
> >       information needs to be present.  */
> > -  resolve_cyclic_derived_type (sym);
> > +  if (!sym->attr.vtype)
> > +    resolve_cyclic_derived_type (sym);
> > 
> >    c = (sym->attr.is_class) ? CLASS_DATA (sym->components)
> >  			   : sym->components;
> > --
> > 2.47.1  
> 
> OK.
  
Jakub Jelinek Jan. 9, 2025, 2:28 p.m. UTC | #27
On Thu, Jan 09, 2025 at 11:32:35AM +0100, Andre Vehreschild wrote:
> I am sorry, I don't get it. So we are trying to help the compiler, i.e. the C++
> one, to create a fast gfortran binary. But we don't care about devs that stumble
> about the code and ask themselves, "Why is this done (without a comment) so
> oddly?"! Furthermore is the code again using convention or inside knowledge:
> 
>   intmod_sym symbol[] = {
> #define NAMED_INTCST(a,b,c,d) { a, b, 0, d },
> #define NAMED_UINTCST(a,b,c,d) { a, b, 0, d },
> #define NAMED_KINDARRAY(a,b,c,d) { a, b, 0, d },
> #define NAMED_DERIVED_TYPE(a,b,c,d) { a, b, 0, d },
> #define NAMED_FUNCTION(a,b,c,d) { a, b, c, d },
> #define NAMED_SUBROUTINE(a,b,c,d) { a, b, c, d },
> 
> So in function and subroutine definitions `c` may become non-constant in the
> future and we neither detect it nor care. 
> 
> #include "iso-fortran-env.def"
>     { ISOFORTRANENV_INVALID, NULL, -1234, 0 } };
> 
>   i = 0;
> #define NAMED_INTCST(a,b,c,d) symbol[i++].value = c;
> #define NAMED_UINTCST(a,b,c,d) symbol[i++].value = c;
> #define NAMED_KINDARRAY(a,b,c,d) i++;
> #define NAMED_DERIVED_TYPE(a,b,c,d) i++;
> #define NAMED_FUNCTION(a,b,c,d) i++;
> #define NAMED_SUBROUTINE(a,b,c,d) i++;
> #include "iso-fortran-env.def"
> 
> So why not at least adding a comment to document this design decision and I

So like this?
I've also added an assert, I think it isn't really needed to assert that
symbol[i].id == a in each case, just that we increment i for all the cases.

2025-01-09  Jakub Jelinek  <jakub@redhat.com>

	PR fortran/118337
	* module.cc (use_iso_fortran_env_module): Add a comment explaining
	the optimization performed.  Add gcc_checking_assert that i was
	incremented for all the elements.  Formatting fix.

--- gcc/fortran/module.cc.jj	2025-01-09 08:25:45.648324540 +0100
+++ gcc/fortran/module.cc	2025-01-09 15:12:07.611842917 +0100
@@ -7122,6 +7122,13 @@ use_iso_fortran_env_module (void)
 #include "iso-fortran-env.def"
     { ISOFORTRANENV_INVALID, NULL, -1234, 0 } };
 
+  /* We could used c in the NAMED_{,U}INTCST macros
+     instead of c, but then current g++ expands the initialization
+     as clearing the whole object followed by explicit stores of
+     all the non-zero elements (over 150), while by using 0s for
+     the non-constant initializers and initializing them afterwards
+     g++ will often copy everything from .rodata and then only override
+     over 30 non-constant ones.  */
   i = 0;
 #define NAMED_INTCST(a,b,c,d) symbol[i++].value = c;
 #define NAMED_UINTCST(a,b,c,d) symbol[i++].value = c;
@@ -7130,6 +7137,7 @@ use_iso_fortran_env_module (void)
 #define NAMED_FUNCTION(a,b,c,d) i++;
 #define NAMED_SUBROUTINE(a,b,c,d) i++;
 #include "iso-fortran-env.def"
+  gcc_checking_assert (i == (int) ARRAY_SIZE (symbol) - 1);
 
   /* Generate the symbol for the module itself.  */
   mod_symtree = gfc_find_symtree (gfc_current_ns->sym_root, mod);
@@ -7288,12 +7296,11 @@ use_iso_fortran_env_module (void)
 	    break;
 
 #define NAMED_FUNCTION(a,b,c,d) \
-		case a:
+	  case a:
 #include "iso-fortran-env.def"
-		  create_intrinsic_function (symbol[i].name, symbol[i].id, mod,
-					     INTMOD_ISO_FORTRAN_ENV, false,
-					     NULL);
-		  break;
+	    create_intrinsic_function (symbol[i].name, symbol[i].id, mod,
+				       INTMOD_ISO_FORTRAN_ENV, false, NULL);
+	    break;
 
 	  default:
 	    gcc_unreachable ();


	Jakub
  
Jakub Jelinek Jan. 9, 2025, 3:32 p.m. UTC | #28
On Thu, Jan 09, 2025 at 03:28:28PM +0100, Jakub Jelinek wrote:
> So like this?

Thomas mentioned bad wording in a private mail.  Here is a better patch:

2025-01-09  Jakub Jelinek  <jakub@redhat.com>

	PR fortran/118337
	* module.cc (use_iso_fortran_env_module): Add a comment explaining
	the optimization performed.  Add gcc_checking_assert that i was
	incremented for all the elements.  Formatting fix.

--- gcc/fortran/module.cc.jj	2025-01-09 08:25:45.648324540 +0100
+++ gcc/fortran/module.cc	2025-01-09 15:12:07.611842917 +0100
@@ -7122,6 +7122,13 @@ use_iso_fortran_env_module (void)
 #include "iso-fortran-env.def"
     { ISOFORTRANENV_INVALID, NULL, -1234, 0 } };
 
+  /* We could have used c in the NAMED_{,U}INTCST macros
+     instead of 0, but then current g++ expands the initialization
+     as clearing the whole object followed by explicit stores of
+     all the non-zero elements (over 150), while by using 0s for
+     the non-constant initializers and initializing them afterwards
+     g++ will often copy everything from .rodata and then only override
+     over 30 non-constant ones.  */
   i = 0;
 #define NAMED_INTCST(a,b,c,d) symbol[i++].value = c;
 #define NAMED_UINTCST(a,b,c,d) symbol[i++].value = c;
@@ -7130,6 +7137,7 @@ use_iso_fortran_env_module (void)
 #define NAMED_FUNCTION(a,b,c,d) i++;
 #define NAMED_SUBROUTINE(a,b,c,d) i++;
 #include "iso-fortran-env.def"
+  gcc_checking_assert (i == (int) ARRAY_SIZE (symbol) - 1);
 
   /* Generate the symbol for the module itself.  */
   mod_symtree = gfc_find_symtree (gfc_current_ns->sym_root, mod);
@@ -7288,12 +7296,11 @@ use_iso_fortran_env_module (void)
 	    break;
 
 #define NAMED_FUNCTION(a,b,c,d) \
-		case a:
+	  case a:
 #include "iso-fortran-env.def"
-		  create_intrinsic_function (symbol[i].name, symbol[i].id, mod,
-					     INTMOD_ISO_FORTRAN_ENV, false,
-					     NULL);
-		  break;
+	    create_intrinsic_function (symbol[i].name, symbol[i].id, mod,
+				       INTMOD_ISO_FORTRAN_ENV, false, NULL);
+	    break;
 
 	  default:
 	    gcc_unreachable ();


	Jakub
  
Andre Vehreschild Jan. 9, 2025, 5:12 p.m. UTC | #29
Hi Jakub,

Yes, that is what I had in mind. Being German I don't see any problem with the
explanation, but that is better judged by a native English speaker.

Is the send patch hunk intentional where only indentation is changed? I haven't
applied it though.

Thanks for the patch,
	Andre

On Thu, 9 Jan 2025 16:32:42 +0100
Jakub Jelinek <jakub@redhat.com> wrote:

> On Thu, Jan 09, 2025 at 03:28:28PM +0100, Jakub Jelinek wrote:
> > So like this?
>
> Thomas mentioned bad wording in a private mail.  Here is a better patch:
>
> 2025-01-09  Jakub Jelinek  <jakub@redhat.com>
>
> 	PR fortran/118337
> 	* module.cc (use_iso_fortran_env_module): Add a comment explaining
> 	the optimization performed.  Add gcc_checking_assert that i was
> 	incremented for all the elements.  Formatting fix.
>
> --- gcc/fortran/module.cc.jj	2025-01-09 08:25:45.648324540 +0100
> +++ gcc/fortran/module.cc	2025-01-09 15:12:07.611842917 +0100
> @@ -7122,6 +7122,13 @@ use_iso_fortran_env_module (void)
>  #include "iso-fortran-env.def"
>      { ISOFORTRANENV_INVALID, NULL, -1234, 0 } };
>
> +  /* We could have used c in the NAMED_{,U}INTCST macros
> +     instead of 0, but then current g++ expands the initialization
> +     as clearing the whole object followed by explicit stores of
> +     all the non-zero elements (over 150), while by using 0s for
> +     the non-constant initializers and initializing them afterwards
> +     g++ will often copy everything from .rodata and then only override
> +     over 30 non-constant ones.  */
>    i = 0;
>  #define NAMED_INTCST(a,b,c,d) symbol[i++].value = c;
>  #define NAMED_UINTCST(a,b,c,d) symbol[i++].value = c;
> @@ -7130,6 +7137,7 @@ use_iso_fortran_env_module (void)
>  #define NAMED_FUNCTION(a,b,c,d) i++;
>  #define NAMED_SUBROUTINE(a,b,c,d) i++;
>  #include "iso-fortran-env.def"
> +  gcc_checking_assert (i == (int) ARRAY_SIZE (symbol) - 1);
>
>    /* Generate the symbol for the module itself.  */
>    mod_symtree = gfc_find_symtree (gfc_current_ns->sym_root, mod);
> @@ -7288,12 +7296,11 @@ use_iso_fortran_env_module (void)
>  	    break;
>
>  #define NAMED_FUNCTION(a,b,c,d) \
> -		case a:
> +	  case a:
>  #include "iso-fortran-env.def"
> -		  create_intrinsic_function (symbol[i].name, symbol[i].id,
> mod,
> -					     INTMOD_ISO_FORTRAN_ENV, false,
> -					     NULL);
> -		  break;
> +	    create_intrinsic_function (symbol[i].name, symbol[i].id, mod,
> +				       INTMOD_ISO_FORTRAN_ENV, false, NULL);
> +	    break;
>
>  	  default:
>  	    gcc_unreachable ();
>
>
> 	Jakub
>


--
Andre Vehreschild * Email: vehre ad gmx dot de
  
Jakub Jelinek Jan. 9, 2025, 5:14 p.m. UTC | #30
On Thu, Jan 09, 2025 at 06:12:51PM +0100, Andre Vehreschild wrote:
> Yes, that is what I had in mind. Being German I don't see any problem with the
> explanation, but that is better judged by a native English speaker.
> 
> Is the send patch hunk intentional where only indentation is changed? I haven't
> applied it though.

Yes, the last hunk is fixing wrong indentation.

	Jakub
  
Mikael Morin Jan. 9, 2025, 5:45 p.m. UTC | #31
Le 09/01/2025 à 18:12, Andre Vehreschild a écrit :
> Hi Jakub,
> 
> Yes, that is what I had in mind. Being German I don't see any problem with the
> explanation, but that is better judged by a native English speaker.
> 
> Is the send patch hunk intentional where only indentation is changed? I haven't
> applied it though.
> 
> Thanks for the patch,
> 	Andre
> 
Fine with me as well, thanks.
  

Patch

--- gcc/fortran/module.cc.jj	2025-01-08 10:05:39.308786981 +0100
+++ gcc/fortran/module.cc	2025-01-08 10:18:14.234222227 +0100
@@ -85,6 +85,8 @@  along with GCC; see the file COPYING3.
 /* Don't put any single quote (') in MOD_VERSION, if you want it to be
    recognized.  */
 #define MOD_VERSION "16"
+/* Older mod versions we can still parse.  */
+#define COMPAT_MOD_VERSIONS { "15" }
 
 
 /* Structure that describes a position within a module file.  */
@@ -7451,10 +7453,23 @@  gfc_use_module (gfc_use_list *module)
 			 " module file", module_fullpath);
       if (start == 3)
 	{
+	  bool fatal = false;
 	  if (strcmp (atom_name, " version") != 0
 	      || module_char () != ' '
-	      || parse_atom () != ATOM_STRING
-	      || strcmp (atom_string, MOD_VERSION))
+	      || parse_atom () != ATOM_STRING)
+	    fatal = true;
+	  else if (strcmp (atom_string, MOD_VERSION))
+	    {
+	      static const char *compat_mod_versions[] = COMPAT_MOD_VERSIONS;
+	      fatal = true;
+	      for (unsigned i = 0; i < ARRAY_SIZE (compat_mod_versions); ++i)
+		if (!strcmp (atom_string, compat_mod_versions[i]))
+		  {
+		    fatal = false;
+		    break;
+		  }
+	    }
+	  if (fatal)
 	    gfc_fatal_error ("Cannot read module file %qs opened at %C,"
 			     " because it was created by a different"
 			     " version of GNU Fortran", module_fullpath);
--- gcc/fortran/iso-c-binding.def.jj	2025-01-02 11:47:31.894198887 +0100
+++ gcc/fortran/iso-c-binding.def	2025-01-08 10:09:12.454799919 +0100
@@ -17,7 +17,8 @@  along with GCC; see the file COPYING3.
 <http://www.gnu.org/licenses/>.  */
 
 /* This file contains the definition of the types provided by the
-   Fortran 2003 ISO_C_BINDING intrinsic module.  */
+   Fortran 2003 ISO_C_BINDING intrinsic module.  The ordering of
+   the entries matters for the *.mod backwards compatibility.  */
 
 #ifndef NAMED_INTCST
 # define NAMED_INTCST(a,b,c,d)
@@ -112,62 +113,6 @@  NAMED_INTCST (ISOCBINDING_INT_FAST64_T,
 NAMED_INTCST (ISOCBINDING_INT_FAST128_T, "c_int_fast128_t",
 	      get_int_kind_from_width (128), GFC_STD_GNU)
 
-/* UNSIGNED.  */
-NAMED_UINTCST (ISOCBINDING_UINT, "c_unsigned", gfc_c_uint_kind, \
-	       GFC_STD_UNSIGNED)
-NAMED_UINTCST (ISOCBINDING_USHORT, "c_unsigned_short", \
-	       get_unsigned_kind_from_node (short_unsigned_type_node), \
-	       GFC_STD_UNSIGNED)
-NAMED_UINTCST (ISOCBINDING_UCHAR, "c_unsigned_char", \
-	       get_unsigned_kind_from_node (unsigned_char_type_node), \
-	       GFC_STD_UNSIGNED)
-NAMED_UINTCST (ISOCBINDING_ULONG, "c_unsigned_long", \
-	       get_unsigned_kind_from_node (long_unsigned_type_node), \
-	       GFC_STD_UNSIGNED)
-NAMED_UINTCST (ISOCBINDING_ULONGLONG, "c_unsigned_long_long", \
-	       get_unsigned_kind_from_node (long_long_unsigned_type_node), \
-	       GFC_STD_UNSIGNED)
-NAMED_UINTCST (ISOCBINDING_UINTMAX_T, "c_uintmax_t", \
-	       get_uint_kind_from_name (UINTMAX_TYPE), GFC_STD_UNSIGNED)
-NAMED_UINTCST (ISOCBINDING_UINT8_T, "c_uint8_t", \
-	       get_uint_kind_from_name (UINT8_TYPE), GFC_STD_UNSIGNED)
-NAMED_UINTCST (ISOCBINDING_UINT16_T, "c_uint16_t", \
-	       get_uint_kind_from_name (UINT16_TYPE), GFC_STD_UNSIGNED)
-NAMED_UINTCST (ISOCBINDING_UINT32_T, "c_uint32_t", \
-	       get_uint_kind_from_name (UINT32_TYPE), GFC_STD_UNSIGNED)
-NAMED_UINTCST (ISOCBINDING_UINT64_T, "c_uint64_t", \
-	       get_uint_kind_from_name (UINT64_TYPE), GFC_STD_UNSIGNED)
-NAMED_UINTCST (ISOCBINDING_UINT128_T, "c_uint128_t", \
-	       get_uint_kind_from_width (128), GFC_STD_UNSIGNED)
-NAMED_UINTCST (ISOCBINDING_UINT_LEAST8_T, "c_uint_least8_t", \
-	       get_uint_kind_from_name (UINT_LEAST8_TYPE), \
-	       GFC_STD_UNSIGNED)
-NAMED_UINTCST (ISOCBINDING_UINT_LEAST16_T, "c_uint_least16_t", \
-	       get_uint_kind_from_name (UINT_LEAST16_TYPE), \
-	       GFC_STD_UNSIGNED)
-NAMED_UINTCST (ISOCBINDING_UINT_LEAST32_T, "c_uint_least32_t", \
-	       get_uint_kind_from_name (UINT_LEAST32_TYPE),\
-	       GFC_STD_UNSIGNED)
-NAMED_UINTCST (ISOCBINDING_UINT_LEAST64_T, "c_uint_least64_t", \
-	       get_uint_kind_from_name (UINT_LEAST64_TYPE),\
-	       GFC_STD_UNSIGNED)
-NAMED_UINTCST (ISOCBINDING_UINT_LEAST128_T, "c_uint_least128_t", \
-	       get_uint_kind_from_width (128), GFC_STD_UNSIGNED)
-NAMED_UINTCST (ISOCBINDING_UINT_FAST8_T, "c_uint_fast8_t", \
-	       get_uint_kind_from_name (UINT_FAST8_TYPE), \
-	       GFC_STD_UNSIGNED)
-NAMED_UINTCST (ISOCBINDING_UINT_FAST16_T, "c_uint_fast16_t", \
-	       get_uint_kind_from_name (UINT_FAST16_TYPE), \
-	       GFC_STD_UNSIGNED)
-NAMED_UINTCST (ISOCBINDING_UINT_FAST32_T, "c_uint_fast32_t", \
-	       get_uint_kind_from_name (UINT_FAST32_TYPE),\
-	       GFC_STD_UNSIGNED)
-NAMED_UINTCST (ISOCBINDING_UINT_FAST64_T, "c_uint_fast64_t", \
-	       get_uint_kind_from_name (UINT_FAST64_TYPE),\
-	       GFC_STD_UNSIGNED)
-NAMED_UINTCST (ISOCBINDING_UINT_FAST128_T, "c_uint_fast128_t", \
-	       get_uint_kind_from_width (128), GFC_STD_UNSIGNED)
-
 NAMED_REALCST (ISOCBINDING_FLOAT, "c_float", \
                get_real_kind_from_node (float_type_node), GFC_STD_F2003)
 NAMED_REALCST (ISOCBINDING_DOUBLE, "c_double", \
@@ -259,6 +204,62 @@  NAMED_FUNCTION (ISOCBINDING_C_SIZEOF, "c
 NAMED_FUNCTION (ISOCBINDING_F_C_STRING, "f_c_string", \
                 GFC_ISYM_F_C_STRING, GFC_STD_F2023)
 
+/* UNSIGNED.  */
+NAMED_UINTCST (ISOCBINDING_UINT, "c_unsigned", gfc_c_uint_kind, \
+	       GFC_STD_UNSIGNED)
+NAMED_UINTCST (ISOCBINDING_USHORT, "c_unsigned_short", \
+	       get_unsigned_kind_from_node (short_unsigned_type_node), \
+	       GFC_STD_UNSIGNED)
+NAMED_UINTCST (ISOCBINDING_UCHAR, "c_unsigned_char", \
+	       get_unsigned_kind_from_node (unsigned_char_type_node), \
+	       GFC_STD_UNSIGNED)
+NAMED_UINTCST (ISOCBINDING_ULONG, "c_unsigned_long", \
+	       get_unsigned_kind_from_node (long_unsigned_type_node), \
+	       GFC_STD_UNSIGNED)
+NAMED_UINTCST (ISOCBINDING_ULONGLONG, "c_unsigned_long_long", \
+	       get_unsigned_kind_from_node (long_long_unsigned_type_node), \
+	       GFC_STD_UNSIGNED)
+NAMED_UINTCST (ISOCBINDING_UINTMAX_T, "c_uintmax_t", \
+	       get_uint_kind_from_name (UINTMAX_TYPE), GFC_STD_UNSIGNED)
+NAMED_UINTCST (ISOCBINDING_UINT8_T, "c_uint8_t", \
+	       get_uint_kind_from_name (UINT8_TYPE), GFC_STD_UNSIGNED)
+NAMED_UINTCST (ISOCBINDING_UINT16_T, "c_uint16_t", \
+	       get_uint_kind_from_name (UINT16_TYPE), GFC_STD_UNSIGNED)
+NAMED_UINTCST (ISOCBINDING_UINT32_T, "c_uint32_t", \
+	       get_uint_kind_from_name (UINT32_TYPE), GFC_STD_UNSIGNED)
+NAMED_UINTCST (ISOCBINDING_UINT64_T, "c_uint64_t", \
+	       get_uint_kind_from_name (UINT64_TYPE), GFC_STD_UNSIGNED)
+NAMED_UINTCST (ISOCBINDING_UINT128_T, "c_uint128_t", \
+	       get_uint_kind_from_width (128), GFC_STD_UNSIGNED)
+NAMED_UINTCST (ISOCBINDING_UINT_LEAST8_T, "c_uint_least8_t", \
+	       get_uint_kind_from_name (UINT_LEAST8_TYPE), \
+	       GFC_STD_UNSIGNED)
+NAMED_UINTCST (ISOCBINDING_UINT_LEAST16_T, "c_uint_least16_t", \
+	       get_uint_kind_from_name (UINT_LEAST16_TYPE), \
+	       GFC_STD_UNSIGNED)
+NAMED_UINTCST (ISOCBINDING_UINT_LEAST32_T, "c_uint_least32_t", \
+	       get_uint_kind_from_name (UINT_LEAST32_TYPE),\
+	       GFC_STD_UNSIGNED)
+NAMED_UINTCST (ISOCBINDING_UINT_LEAST64_T, "c_uint_least64_t", \
+	       get_uint_kind_from_name (UINT_LEAST64_TYPE),\
+	       GFC_STD_UNSIGNED)
+NAMED_UINTCST (ISOCBINDING_UINT_LEAST128_T, "c_uint_least128_t", \
+	       get_uint_kind_from_width (128), GFC_STD_UNSIGNED)
+NAMED_UINTCST (ISOCBINDING_UINT_FAST8_T, "c_uint_fast8_t", \
+	       get_uint_kind_from_name (UINT_FAST8_TYPE), \
+	       GFC_STD_UNSIGNED)
+NAMED_UINTCST (ISOCBINDING_UINT_FAST16_T, "c_uint_fast16_t", \
+	       get_uint_kind_from_name (UINT_FAST16_TYPE), \
+	       GFC_STD_UNSIGNED)
+NAMED_UINTCST (ISOCBINDING_UINT_FAST32_T, "c_uint_fast32_t", \
+	       get_uint_kind_from_name (UINT_FAST32_TYPE),\
+	       GFC_STD_UNSIGNED)
+NAMED_UINTCST (ISOCBINDING_UINT_FAST64_T, "c_uint_fast64_t", \
+	       get_uint_kind_from_name (UINT_FAST64_TYPE),\
+	       GFC_STD_UNSIGNED)
+NAMED_UINTCST (ISOCBINDING_UINT_FAST128_T, "c_uint_fast128_t", \
+	       get_uint_kind_from_width (128), GFC_STD_UNSIGNED)
+
 #undef NAMED_INTCST
 #undef NAMED_UINTCST
 #undef NAMED_REALCST
--- gcc/fortran/iso-fortran-env.def.jj	2025-01-02 11:47:32.137195494 +0100
+++ gcc/fortran/iso-fortran-env.def	2025-01-08 10:11:44.946667057 +0100
@@ -17,7 +17,8 @@  along with GCC; see the file COPYING3.
 <http://www.gnu.org/licenses/>.  */
 
 /* This file contains the definition of the named integer constants provided
-   by the Fortran 2003 ISO_FORTRAN_ENV intrinsic module.  */
+   by the Fortran 2003 ISO_FORTRAN_ENV intrinsic module.  The ordering of
+   the entries matters for the *.mod backwards compatibility.  */
 
 #ifndef NAMED_INTCST
 # define NAMED_INTCST(a,b,c,d)
@@ -72,20 +73,10 @@  NAMED_INTCST (ISOFORTRANENV_IOSTAT_EOR,
 NAMED_INTCST (ISOFORTRANENV_IOSTAT_INQUIRE_INTERNAL_UNIT, \
               "iostat_inquire_internal_unit", LIBERROR_INQUIRE_INTERNAL_UNIT, \
               GFC_STD_F2008)
-NAMED_INTCST (ISOFORTRANENV_LOGICAL8, "logical8", \
-              gfc_get_int_kind_from_width_isofortranenv (8), GFC_STD_F2023)
-NAMED_INTCST (ISOFORTRANENV_LOGICAL16, "logical16", \
-              gfc_get_int_kind_from_width_isofortranenv (16), GFC_STD_F2023)
-NAMED_INTCST (ISOFORTRANENV_LOGICAL32, "logical32", \
-              gfc_get_int_kind_from_width_isofortranenv (32), GFC_STD_F2023)
-NAMED_INTCST (ISOFORTRANENV_LOGICAL64, "logical64", \
-              gfc_get_int_kind_from_width_isofortranenv (64), GFC_STD_F2023)
 NAMED_INTCST (ISOFORTRANENV_NUMERIC_STORAGE_SIZE, "numeric_storage_size", \
               gfc_numeric_storage_size, GFC_STD_F2003)
 NAMED_INTCST (ISOFORTRANENV_OUTPUT_UNIT, "output_unit", GFC_STDOUT_UNIT_NUMBER, \
               GFC_STD_F2003)
-NAMED_INTCST (ISOFORTRANENV_REAL16, "real16", \
-              gfc_get_real_kind_from_width_isofortranenv (16), GFC_STD_F2023)
 NAMED_INTCST (ISOFORTRANENV_REAL32, "real32", \
               gfc_get_real_kind_from_width_isofortranenv (32), GFC_STD_F2008)
 NAMED_INTCST (ISOFORTRANENV_REAL64, "real64", \
@@ -103,14 +94,7 @@  NAMED_INTCST (ISOFORTRANENV_FILE_STAT_FA
               GFC_STAT_FAILED_IMAGE, GFC_STD_F2018)
 NAMED_INTCST (ISOFORTRANENV_FILE_STAT_UNLOCKED, "stat_unlocked", \
               GFC_STAT_UNLOCKED, GFC_STD_F2008)
-NAMED_UINTCST (ISOFORTRANENV_UINT8, "uint8", \
-	       gfc_get_uint_kind_from_width_isofortranenv (8), GFC_STD_UNSIGNED)
-NAMED_UINTCST (ISOFORTRANENV_UINT16, "uint16", \
-	       gfc_get_uint_kind_from_width_isofortranenv (16), GFC_STD_UNSIGNED)
-NAMED_UINTCST (ISOFORTRANENV_UINT32, "uint32", \
-	       gfc_get_uint_kind_from_width_isofortranenv (32), GFC_STD_UNSIGNED)
-NAMED_UINTCST (ISOFORTRANENV_UINT64, "uint64", \
-	       gfc_get_uint_kind_from_width_isofortranenv (64), GFC_STD_UNSIGNED)
+
 
 /* The arguments to NAMED_KINDARRAY are:
      -- an internal name
@@ -154,6 +138,26 @@  NAMED_DERIVED_TYPE (ISOFORTRAN_TEAM_TYPE
 		    ? get_int_kind_from_node (ptr_type_node)
 		    : gfc_default_integer_kind, GFC_STD_F2018)
 
+NAMED_INTCST (ISOFORTRANENV_LOGICAL8, "logical8", \
+              gfc_get_int_kind_from_width_isofortranenv (8), GFC_STD_F2023)
+NAMED_INTCST (ISOFORTRANENV_LOGICAL16, "logical16", \
+              gfc_get_int_kind_from_width_isofortranenv (16), GFC_STD_F2023)
+NAMED_INTCST (ISOFORTRANENV_LOGICAL32, "logical32", \
+              gfc_get_int_kind_from_width_isofortranenv (32), GFC_STD_F2023)
+NAMED_INTCST (ISOFORTRANENV_LOGICAL64, "logical64", \
+              gfc_get_int_kind_from_width_isofortranenv (64), GFC_STD_F2023)
+NAMED_INTCST (ISOFORTRANENV_REAL16, "real16", \
+              gfc_get_real_kind_from_width_isofortranenv (16), GFC_STD_F2023)
+
+NAMED_UINTCST (ISOFORTRANENV_UINT8, "uint8", \
+	       gfc_get_uint_kind_from_width_isofortranenv (8), GFC_STD_UNSIGNED)
+NAMED_UINTCST (ISOFORTRANENV_UINT16, "uint16", \
+	       gfc_get_uint_kind_from_width_isofortranenv (16), GFC_STD_UNSIGNED)
+NAMED_UINTCST (ISOFORTRANENV_UINT32, "uint32", \
+	       gfc_get_uint_kind_from_width_isofortranenv (32), GFC_STD_UNSIGNED)
+NAMED_UINTCST (ISOFORTRANENV_UINT64, "uint64", \
+	       gfc_get_uint_kind_from_width_isofortranenv (64), GFC_STD_UNSIGNED)
+
 #undef NAMED_INTCST
 #undef NAMED_UINTCST
 #undef NAMED_KINDARRAY