Calling gfc_find_vtab during resolution during parsing
comes too early for finalizers. This patch just moves it
to the resolution, which seems to be the simplest solution.

(I tried way more complicated ones which do not work; thus,
I settled for the simple solution ...)

OK for GCC 9/10/mainline?

Tobias

PS: I was wondering about FORALL (which is resolved separately),
but as "f = b" does not work (missing loop index) and as
"f(i)%a = b" is broken (no reallocation, no __copy call,
→ https://gcc.gnu.org/PR98336 ) I think no action is needed
for now.

-----------------
Mentor Graphics (Deutschland) GmbH, Arnulfstraße 201, 80634 München / Germany
Registergericht München HRB 106955, Geschäftsführer: Thomas Heurung, Alexander 
Walter
Fortran: Delay vtab generation until after parsing [PR92587]

gcc/fortran/ChangeLog:

	PR fortran/92587
	* match.c (gfc_match_assignment): Move gfc_find_vtab call from here ...
	* resolve.c (gfc_resolve_code): ... to here.

gcc/testsuite/ChangeLog:

	PR fortran/92587
	* gfortran.dg/finalize_37.f90: New test.

 gcc/fortran/match.c                          |  3 --
 gcc/fortran/resolve.c                        |  3 ++
 gcc/testsuite/gfortran.dg/finalize_37.f90    | 51 ++++++++++++++++++++++++++++
 4 files changed, 80 insertions(+), 3 deletions(-)

diff --git a/gcc/fortran/match.c b/gcc/fortran/match.c
index bee73e7b008..c13fe96ed33 100644
--- a/gcc/fortran/match.c
+++ b/gcc/fortran/match.c
@@ -1389,9 +1389,6 @@ gfc_match_assignment (void)
 
   gfc_check_do_variable (lvalue->symtree);
 
-  if (lvalue->ts.type == BT_CLASS)
-    gfc_find_vtab (&rvalue->ts);
-
   return MATCH_YES;
 }
 
diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c
index 05a5e43c90b..1da7ba4d031 100644
--- a/gcc/fortran/resolve.c
+++ b/gcc/fortran/resolve.c
@@ -11896,6 +11896,9 @@ start:
 	  if (!t)
 	    break;
 
+	  if (code->expr1->ts.type == BT_CLASS)
+	   gfc_find_vtab (&code->expr2->ts);
+
 	  /* Remove a GFC_ISYM_CAF_GET inserted for a coindexed variable on
 	     the LHS.  */
 	  if (code->expr1->expr_type == EXPR_FUNCTION
diff --git a/gcc/testsuite/gfortran.dg/finalize_37.f90 b/gcc/testsuite/gfortran.dg/finalize_37.f90
new file mode 100644
index 00000000000..3f872633fdd
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/finalize_37.f90
@@ -0,0 +1,51 @@
+! { dg-do compile }
+! { dg-additional-options "-fdump-tree-original" }
+!
+! PR fortran/92587
+!
+
+module m
+   implicit none (type, external)
+   type t2
+   contains
+      final :: fini
+   end type
+   type t3
+      type(t2) :: a
+   end type
+   type, extends(t3) :: t4
+   end type
+   class(t4), allocatable :: y
+   class(t4), allocatable :: z
+contains
+   subroutine sub
+      y = z
+   end
+   subroutine fini(x)
+     type(t2) :: x
+   end
+end
+
+module m2
+  use m
+  implicit none (type, external)
+  type, extends(t3) :: t5
+  end type
+  type, extends(t3) :: t6
+    contains
+      final :: fin2
+  end type
+contains
+  subroutine bar(x, y, z)
+    class(t4), allocatable, intent(out) :: x
+    class(t5), allocatable, intent(out) :: y
+    class(t6), allocatable, intent(out) :: z
+  end
+  subroutine fin2 (x)
+    type(t6) :: x
+  end
+end  
+
+! { dg-final { scan-tree-dump "__final_m_T2 \\\(struct" "original" } }
+! { dg-final { scan-tree-dump "__final_m_T3 \\\(struct" "original" } }
+! { dg-final { scan-tree-dump "__final_m2_T6 \\\(struct" "original" } }

Reply via email to