Dear All, This bug resulted from a cock-up on my part. The mechanism for suppressing .smod files depended on detecting the presence of a module procedure by resetting a flag if the module_procedure attribute was written. Of course, this didn't happen if the module procedure is private, which rather defeats the requirement that private symbols be present in an .smod file. The fix traverses the namespace and resets the flag on finding a module procedure.
Bootstraps and regtests on FC25/x86_64 - OK for trunk and 6-branch? Paul 2017-02-27 Paul Thomas <pa...@gcc.gnu.org> PR fortran/79676 * module.c (mio_symbol_attribute): Remove reset of the flag 'no_module_procedures'. (check_for_module_procedures): New function. Move declaration of 'no_module_procedures' to above it. (gfc_dump_module): Traverse namespace calling new function. 2017-02-27 Paul Thomas <pa...@gcc.gnu.org> PR fortran/79676 * gfortran.dg/submodule_28.f08 : New test.
Index: gcc/fortran/module.c =================================================================== *** gcc/fortran/module.c (revision 245602) --- gcc/fortran/module.c (working copy) *************** static const char *module_name; *** 193,202 **** /* The name of the .smod file that the submodule will write to. */ static const char *submodule_name; - /* Suppress the output of a .smod file by module, if no module - procedures have been seen. */ - static bool no_module_procedures; - static gfc_use_list *module_list; /* If we're reading an intrinsic module, this is its ID. */ --- 193,198 ---- *************** mio_symbol_attribute (symbol_attribute * *** 2243,2252 **** if (attr->array_outer_dependency) MIO_NAME (ab_attribute) (AB_ARRAY_OUTER_DEPENDENCY, attr_bits); if (attr->module_procedure) - { MIO_NAME (ab_attribute) (AB_MODULE_PROCEDURE, attr_bits); - no_module_procedures = false; - } if (attr->oacc_declare_create) MIO_NAME (ab_attribute) (AB_OACC_DECLARE_CREATE, attr_bits); if (attr->oacc_declare_copyin) --- 2239,2245 ---- *************** dump_module (const char *name, int dump_ *** 6139,6144 **** --- 6132,6149 ---- } + /* Suppress the output of a .smod file by module, if no module + procedures have been seen. */ + static bool no_module_procedures; + + static void + check_for_module_procedures (gfc_symbol *sym) + { + if (sym && sym->attr.module_procedure) + no_module_procedures = false; + } + + void gfc_dump_module (const char *name, int dump_flag) { *************** gfc_dump_module (const char *name, int d *** 6148,6153 **** --- 6153,6160 ---- dump_smod =false; no_module_procedures = true; + gfc_traverse_ns (gfc_current_ns, check_for_module_procedures); + dump_module (name, dump_flag); if (no_module_procedures || dump_smod) Index: gcc/testsuite/gfortran.dg/submodule_28.f08 =================================================================== *** gcc/testsuite/gfortran.dg/submodule_28.f08 (nonexistent) --- gcc/testsuite/gfortran.dg/submodule_28.f08 (working copy) *************** *** 0 **** --- 1,52 ---- + ! { dg-do run } + ! + ! Tests the fix for PR79676 in which submod_test was private even to the + ! submodule 'my_submod'. + ! + ! Contributed by Adam Hirst <a...@aphirst.karoo.co.uk> + ! + module my_mod + private ! This hid 'submod_test'. + interface + module subroutine submod_test(x) + integer :: x + end subroutine + end interface + integer answer + public routine1, print_two, answer + contains + subroutine routine1(x) + integer :: x + call submod_test(x) + end subroutine + subroutine print_two() + integer, parameter :: two = 2 + answer = answer * two + end subroutine + end module + + module my_mod_2 + use my_mod + contains + subroutine circular_dependency() + call print_two() + end subroutine + end module + + submodule (my_mod) my_submod + use my_mod_2 + contains + module subroutine submod_test(x) + integer :: x + answer = x + call circular_dependency() + end subroutine + + end submodule + + program hello + use my_mod + implicit none + call routine1(2) + if (answer .ne. 4) call abort + end program