re PR fortran/79676 ([submodules] Compilation/linking error when module procedures...
authorPaul Thomas <pault@gcc.gnu.org>
Sat, 18 Mar 2017 12:38:02 +0000 (12:38 +0000)
committerPaul Thomas <pault@gcc.gnu.org>
Sat, 18 Mar 2017 12:38:02 +0000 (12:38 +0000)
2017-03-18  Paul Thomas  <pault@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-03-18  Paul Thomas  <pault@gcc.gnu.org>

PR fortran/79676
* gfortran.dg/submodule_28.f08 : New test.

From-SVN: r246256

gcc/fortran/ChangeLog
gcc/fortran/module.c
gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.dg/submodule_28.f08 [new file with mode: 0644]

index e8d6296..5c99e1f 100644 (file)
@@ -1,5 +1,14 @@
 2017-03-18  Paul Thomas  <pault@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-03-18  Paul Thomas  <pault@gcc.gnu.org>
+
        PR fortran/71838
        * symbol.c (check_conflict): A dummy procedure in a submodule,
        module procedure is not an error.
index 5515fed..80a6524 100644 (file)
@@ -193,10 +193,6 @@ static const char *module_name;
 /* 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.  */
@@ -2243,10 +2239,7 @@ mio_symbol_attribute (symbol_attribute *attr)
       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)
@@ -6139,6 +6132,18 @@ dump_module (const char *name, int dump_flag)
 }
 
 
+/* 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)
 {
@@ -6148,6 +6153,8 @@ gfc_dump_module (const char *name, int dump_flag)
     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 da22ac2..7a8dbc0 100644 (file)
@@ -1,5 +1,10 @@
 2017-03-18  Paul Thomas  <pault@gcc.gnu.org>
 
+       PR fortran/79676
+       * gfortran.dg/submodule_28.f08 : New test.
+
+2017-03-18  Paul Thomas  <pault@gcc.gnu.org>
+
        PR fortran/71838
        * gfortran.dg/submodule_26.f08 : New test.
        * gfortran.dg/submodule_27.f08 : New test.
diff --git a/gcc/testsuite/gfortran.dg/submodule_28.f08 b/gcc/testsuite/gfortran.dg/submodule_28.f08
new file mode 100644 (file)
index 0000000..f7b10a6
--- /dev/null
@@ -0,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  <adam@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