]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Fortran: ICE with pointer result from submodule function [PR93424]
authorPaul Thomas <pault@gcc.gnu.org>
Thu, 4 Jun 2026 12:24:05 +0000 (13:24 +0100)
committerPaul Thomas <pault@gcc.gnu.org>
Thu, 4 Jun 2026 13:48:58 +0000 (14:48 +0100)
The declaration at line 41 of the testcase produced:
   42 |     class(c), pointer :: bp
      |     1
Error: Unclassifiable statement at (1)
Followed by either an ICE (gcc-13 and gcc-17) or
"(null):0: confused by earlier errors, bailing out"
for the other active branches.

It is the error that is key, the aftermath is a distraction especially
in examining the entrails for clues.

The fix recognises 'bp', in the offending line, to be the implicit
result of the module procedure, redeclared in the submodule contained
function. MATCH_YES is emitted and the potential new symbol is not
commited by jumping straight to cleanup.

2026-06-04  Paul Thomas  <pault@gcc.gnu.org>

gcc/fortran
PR fortran/93424
* decl.cc (variable_decl): Do not commit the symbol if it is
the implicit result of a module procedure being declared in a
function, used in a submodule.

gcc/testsuite/
PR fortran/93424
* gfortran.dg/submodule_37.f90: New test.

gcc/fortran/decl.cc
gcc/testsuite/gfortran.dg/submodule_37.f90 [new file with mode: 0644]

index b14463ddfe7ba0ffab619b8ce89a4b47a9b92619..fe4aa8119b90eff442b8980696b977b9e5b1d558 100644 (file)
@@ -3087,6 +3087,25 @@ variable_decl (int elem)
          gfc_free_array_spec (cp_as);
        }
     }
+  else
+    {
+      /* Check to see if this is the declaration of the type and/or attributes
+        of an implicit function result, emanating from a module function
+        interface declared within the parent module or submodule of a
+        containing submodule.  */
+      gfc_find_symbol (name, gfc_current_ns, 0, &sym);
+      if (gfc_current_state () == COMP_FUNCTION
+         && sym == gfc_current_block ()
+         && sym->attr.if_source == IFSRC_DECL
+         && sym->attr.used_in_submodule
+         && sym == sym->result
+         && sym->ts.type != BT_UNKNOWN)
+       {
+         m = MATCH_YES;
+         goto cleanup;
+       }
+      sym = NULL;
+    }
 
   /* Procedure pointer as function result.  */
   if (gfc_current_state () == COMP_FUNCTION
diff --git a/gcc/testsuite/gfortran.dg/submodule_37.f90 b/gcc/testsuite/gfortran.dg/submodule_37.f90
new file mode 100644 (file)
index 0000000..2e8c01c
--- /dev/null
@@ -0,0 +1,59 @@
+! { dg-do compile }
+! { dg-options "-fdump-tree-original" }
+!
+! Test the fix for pr93424 in which the declaration at line 41 yielded:
+! first "Error: Unclassifiable statement at (1)"
+! followed by an ICE at interface.cc:851
+!
+! Contributed by Andrew Benson  <abensonca@gmail.com>
+!
+module t
+  type :: a
+   contains
+     procedure :: p => ap
+  end type a
+
+  type, extends(a) :: b
+   contains
+     procedure :: p => bp
+  end type b
+
+  type :: c
+  end type c
+  
+  interface
+     module function bp(s)
+       class(b), intent(inout) :: s
+       class(c), pointer :: bp
+     end function
+  end interface
+contains
+  function ap(s)
+    class(a), intent(inout) :: s
+    class(c), pointer :: ap
+    ap => NULL()
+  end function ap
+end module t
+
+submodule (t) ts
+contains
+  function bp(s)
+    class(b), intent(inout) :: s
+    class(c), pointer :: bp
+    select type (s)
+      type is (b)
+      bp => NULL()
+    end select
+  end function bp  
+end submodule ts
+
+  use t
+  class(c), pointer :: x
+  type(c), target :: y
+  type(b) :: z
+  x => y
+  if (.not.associated(x,y)) stop 1
+  x => z%p()
+  if (associated(x,y)) stop 2
+end
+! { dg-final { scan-tree-dump-times "D..... = bp \\(&class..\\)" 1 "original" } }