re PR fortran/79402 (ICE with submodules: module procedure interface defined in paren...
authorPaul Thomas <pault@gcc.gnu.org>
Sun, 19 Feb 2017 18:27:14 +0000 (18:27 +0000)
committerPaul Thomas <pault@gcc.gnu.org>
Sun, 19 Feb 2017 18:27:14 +0000 (18:27 +0000)
2017-02-19  Paul Thomas  <pault@gcc.gnu.org>

PR fortran/79402
* resolve.c (fixup_unique_dummy): New function.
(gfc_resolve_expr): Call it for dummy variables with a unique
symtree name.

2017-02-19  Paul Thomas  <pault@gcc.gnu.org>

PR fortran/79402
* gfortran.dg/submodule_23.f90: New test.

From-SVN: r245580

gcc/fortran/ChangeLog
gcc/fortran/resolve.c
gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.dg/submodule_23.f90 [new file with mode: 0644]

index f7a89cca0ec0c002f55ecce35856225402add499..82733be6fa444eff8e8a060e07f5068605a16eff 100644 (file)
@@ -1,3 +1,10 @@
+017-02-19  Paul Thomas  <pault@gcc.gnu.org>
+
+       PR fortran/79402
+       * resolve.c (fixup_unique_dummy): New function.
+       (gfc_resolve_expr): Call it for dummy variables with a unique
+       symtree name.
+
 2017-02-19  Andre Vehreschild  <vehre@gcc.gnu.org>
 
        PR fortran/79335
index a5fe2314372c702c92e0304c5cd57ecd2de3faa3..876f3cd5d8cf83991b2d962e7a3d7c858d57a7db 100644 (file)
@@ -6433,6 +6433,31 @@ gfc_is_expandable_expr (gfc_expr *e)
   return false;
 }
 
+
+/* Sometimes variables in specification expressions of the result
+   of module procedures in submodules wind up not being the 'real'
+   dummy.  Find this, if possible, in the namespace of the first
+   formal argument.  */
+
+static void
+fixup_unique_dummy (gfc_expr *e)
+{
+  gfc_symtree *st = NULL;
+  gfc_symbol *s = NULL;
+
+  if (e->symtree->n.sym->ns->proc_name
+      && e->symtree->n.sym->ns->proc_name->formal)
+    s = e->symtree->n.sym->ns->proc_name->formal->sym;
+
+  if (s != NULL)
+    st = gfc_find_symtree (s->ns->sym_root, e->symtree->n.sym->name);
+
+  if (st != NULL
+      && st->n.sym != NULL
+      && st->n.sym->attr.dummy)
+    e->symtree = st;
+}
+
 /* Resolve an expression.  That is, make sure that types of operands agree
    with their operators, intrinsic operators are converted to function calls
    for overloaded types and unresolved function references are resolved.  */
@@ -6457,6 +6482,14 @@ gfc_resolve_expr (gfc_expr *e)
       actual_arg = false;
       first_actual_arg = false;
     }
+  else if (e->symtree != NULL
+          && *e->symtree->name == '@'
+          && e->symtree->n.sym->attr.dummy)
+    {
+      /* Deal with submodule specification expressions that are not
+        found to be referenced in module.c(read_cleanup).  */
+      fixup_unique_dummy (e);
+    }
 
   switch (e->expr_type)
     {
index 097cab4b5b8f88b10bd0af6bf001202b3deb4360..ada192093afc8d9eb82d9096157a1472f895946b 100644 (file)
@@ -1,3 +1,8 @@
+2017-02-19  Paul Thomas  <pault@gcc.gnu.org>
+
+       PR fortran/79402
+       * gfortran.dg/submodule_23.f90: New test.
+
 2017-02-19  Paolo Carlini  <paolo.carlini@oracle.com>
 
        PR c++/79380
 
        PR target/79481
        * gcc.target/i386/sse-14.c (test_2vx): Add void return type.
-       (test_3vx): Change return type from int to void. 
+       (test_3vx): Change return type from int to void.
        (_mm512_prefetch_i32gather_ps, _mm512_prefetch_i32scatter_ps,
        _mm512_prefetch_i64gather_ps, _mm512_prefetch_i64scatter_ps,
        _mm512_prefetch_i32gather_pd, _mm512_prefetch_i32scatter_pd,
diff --git a/gcc/testsuite/gfortran.dg/submodule_23.f90 b/gcc/testsuite/gfortran.dg/submodule_23.f90
new file mode 100644 (file)
index 0000000..63674fb
--- /dev/null
@@ -0,0 +1,29 @@
+! { dg-do compile }
+!
+! Test the fix for PR79402, in which the module procedure 'fun1' picked
+! up a spurious symbol for the dummy 'n' in the specification expression
+! for the result 'y'.
+!
+! Contributed by Chris Coutinho  <chrisbcoutinho@gmail.com>
+!
+module mod
+  interface myfun
+    module function fun1(n) result(y)
+      integer,  intent(in)    :: n
+      real, dimension(n)  :: y
+    end function fun1
+  end interface myfun
+
+end module mod
+
+submodule (mod) submod
+contains
+  module procedure fun1
+    integer :: i
+    y = [(float (i), i = 1, n)]
+  end procedure fun1
+end submodule
+
+  use mod
+  print *, fun1(10)
+end