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 <ja...@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