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

Reply via email to