[fortran] PR93424 - ICE on valid with pointer result from submodule function

Message ID CAGkQGiJdCYn95R4n0cq_tHK-QFuaXPDFuLfTTvP0dTPjG2o+_g@mail.gmail.com
State New
Headers
Series [fortran] PR93424 - ICE on valid with pointer result from submodule function |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gcc_build--master-arm success Build passed
linaro-tcwg-bot/tcwg_gcc_check--master-arm success Test passed
linaro-tcwg-bot/tcwg_gcc_build--master-aarch64 success Build passed
linaro-tcwg-bot/tcwg_simplebootstrap_build--master-arm-bootstrap success Build passed
linaro-tcwg-bot/tcwg_simplebootstrap_build--master-aarch64-bootstrap success Build passed
linaro-tcwg-bot/tcwg_gcc_check--master-aarch64 fail Patch failed to apply

Commit Message

Paul Richard Thomas June 3, 2026, 12:58 p.m. UTC
  Hello All,

I am working my way through the submodule meta-bug pr121381.

This one I have stared at for rather longer than I like to think
about. claude AI cogitated about it for 2 hours without coming up with
a fix. It is quite likely that I didn't steer it well enough. However,
on following the trail that it was testing, I came up with the fix in
30 minutes.

The attached patch survives regtesting on FC44/x86_64.

OK for mainline and later backporting to 16-branch?

Cheers

Paul

PS An Octave script for testing the PRs in the meta-bug gives;
*******pr88632*******
PR88632 compiles, links and runs successfuly
*******pr90795****** fixed 13-17 branches
PR90795 compiles successfuly
*******pr93422****** fixed 13-17 branches
PR93422 compiles successfuly
*******pr93424******
PR93424 compiles successfuly
*******pr104630*******
PR93424 compiles, links and runs successfuly
*******pr105594****** spurious warning - patch with PR
pr105594 compiles successfuly with no warnings
*******pr115653****** spurious warning - patch with PR105594
pr115653 compiles successfuly with no warnings
*******pr118705******
rm: cannot remove './pr118705_exec': No such file or directory
/usr/bin/ld.bfd: heading_s.o: in function `__heading_mod_MOD_heading':
heading_s.f90:(.text+0x23): undefined reference to
`__vtab_classification_mod_Classification_t.0'
collect2: error: ld returned 1 exit status
sh: line 1: ./pr118705_exec: No such file or directory
*******pr121204******
STOP 1
*******pr121379****** should fail because of name clash
PR121379 fails to detect name clash
*******pr125527******* fixed by Jerry Delisle
pr125527 compiles, links and runs successfuly

So pr118705, pr121204 and pr121379 have to be fixed to empty out the meta-bug.
  

Comments

Paul Richard Thomas June 4, 2026, 1:51 p.m. UTC | #1
Hello All,

This patch is sufficiently simple and was holding up other submodule
patches and so I pushed it as r17-1342.

However, I will hold off before backporting.

Cheers

Paul

On Wed, 3 Jun 2026 at 13:58, Paul Richard Thomas
<paul.richard.thomas@gmail.com> wrote:
>
> Hello All,
>
> I am working my way through the submodule meta-bug pr121381.
>
> This one I have stared at for rather longer than I like to think
> about. claude AI cogitated about it for 2 hours without coming up with
> a fix. It is quite likely that I didn't steer it well enough. However,
> on following the trail that it was testing, I came up with the fix in
> 30 minutes.
>
> The attached patch survives regtesting on FC44/x86_64.
>
> OK for mainline and later backporting to 16-branch?
>
> Cheers
>
> Paul
>
> PS An Octave script for testing the PRs in the meta-bug gives;
> *******pr88632*******
> PR88632 compiles, links and runs successfuly
> *******pr90795****** fixed 13-17 branches
> PR90795 compiles successfuly
> *******pr93422****** fixed 13-17 branches
> PR93422 compiles successfuly
> *******pr93424******
> PR93424 compiles successfuly
> *******pr104630*******
> PR93424 compiles, links and runs successfuly
> *******pr105594****** spurious warning - patch with PR
> pr105594 compiles successfuly with no warnings
> *******pr115653****** spurious warning - patch with PR105594
> pr115653 compiles successfuly with no warnings
> *******pr118705******
> rm: cannot remove './pr118705_exec': No such file or directory
> /usr/bin/ld.bfd: heading_s.o: in function `__heading_mod_MOD_heading':
> heading_s.f90:(.text+0x23): undefined reference to
> `__vtab_classification_mod_Classification_t.0'
> collect2: error: ld returned 1 exit status
> sh: line 1: ./pr118705_exec: No such file or directory
> *******pr121204******
> STOP 1
> *******pr121379****** should fail because of name clash
> PR121379 fails to detect name clash
> *******pr125527******* fixed by Jerry Delisle
> pr125527 compiles, links and runs successfuly
>
> So pr118705, pr121204 and pr121379 have to be fixed to empty out the meta-bug.
  

Patch

From 07d2c00348adbd425e9fb0878cd972753f5c2c11 Mon Sep 17 00:00:00 2001
From: Paul Thomas <pault@gcc.gnu.org>
Date: Wed, 3 Jun 2026 13:24:05 +0100
Subject: [PATCH] Fortran: ICE with pointer result from submodule function
 [PR93424]

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-03  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_36.f90: New test.
---
 gcc/fortran/decl.cc                        | 19 +++++++
 gcc/testsuite/gfortran.dg/submodule_36.f90 | 59 ++++++++++++++++++++++
 2 files changed, 78 insertions(+)
 create mode 100644 gcc/testsuite/gfortran.dg/submodule_36.f90

diff --git a/gcc/fortran/decl.cc b/gcc/fortran/decl.cc
index b81d81b2dd1..d5a2adec676 100644
--- a/gcc/fortran/decl.cc
+++ b/gcc/fortran/decl.cc
@@ -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_36.f90 b/gcc/testsuite/gfortran.dg/submodule_36.f90
new file mode 100644
index 00000000000..2e8c01c9453
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/submodule_36.f90
@@ -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" } }
-- 
2.54.0