https://gcc.gnu.org/g:fed871f93c235da8ccba29d7beb715abc1482e59

commit r15-5716-gfed871f93c235da8ccba29d7beb715abc1482e59
Author: Paul Thomas <pa...@gcc.gnu.org>
Date:   Wed Nov 27 09:20:23 2024 +0000

    Fortran: Fix non_overridable typebound proc problems [PR84674/117768].
    
    2024-11-27  Paul Thomas  <pa...@gcc.gnu.org>
    
    gcc/fortran/ChangeLog
    
            PR fortran/84674
            * class.cc (add_proc_comp): If the component points to a tbp
            that is abstract, do not return since the new version is more
            likely to be usable.
            PR fortran/117768
            * resolve.cc (resolve_fl_derived): Remove the condition that
            rejected a completely empty derived type extension.
    
    gcc/testsuite/ChangeLog
    
            PR fortran/117768
            * gfortran.dg/pr117768.f90: New test.

Diff:
---
 gcc/fortran/class.cc                   | 14 ++++++-
 gcc/fortran/resolve.cc                 |  8 +---
 gcc/testsuite/gfortran.dg/pr117768.f90 | 76 ++++++++++++++++++++++++++++++++++
 3 files changed, 90 insertions(+), 8 deletions(-)

diff --git a/gcc/fortran/class.cc b/gcc/fortran/class.cc
index 59ac0d97e080..64a0e726eeb4 100644
--- a/gcc/fortran/class.cc
+++ b/gcc/fortran/class.cc
@@ -884,11 +884,21 @@ static void
 add_proc_comp (gfc_symbol *vtype, const char *name, gfc_typebound_proc *tb)
 {
   gfc_component *c;
-
+  bool is_abstract = false;
 
   c = gfc_find_component (vtype, name, true, true, NULL);
 
-  if (tb->non_overridable && !tb->overridden && c)
+  /* If the present component typebound proc is abstract, the new version
+     should unconditionally be tested if it is a suitable replacement.  */
+  if (c && c->tb && c->tb->u.specific
+      && c->tb->u.specific->n.sym->attr.abstract)
+    is_abstract = true;
+
+  /* Pass on the new tb being not overridable if a component is found and
+     either there is not an overridden specific or the present component
+     tb is abstract. This ensures that possible, viable replacements are
+     loaded.  */
+  if (tb->non_overridable && !tb->overridden && !is_abstract && c)
     return;
 
   if (c == NULL)
diff --git a/gcc/fortran/resolve.cc b/gcc/fortran/resolve.cc
index 0d3845f9ce35..afed8db7852b 100644
--- a/gcc/fortran/resolve.cc
+++ b/gcc/fortran/resolve.cc
@@ -3229,8 +3229,8 @@ static bool check_pure_function (gfc_expr *e)
   const char *name = NULL;
   code_stack *stack;
   bool saw_block = false;
-  
-  /* A BLOCK construct within a DO CONCURRENT construct leads to 
+
+  /* A BLOCK construct within a DO CONCURRENT construct leads to
      gfc_do_concurrent_flag = 0 when the check for an impure function
      occurs.  Check the stack to see if the source code has a nested
      BLOCK construct.  */
@@ -16305,10 +16305,6 @@ resolve_fl_derived (gfc_symbol *sym)
       && sym->ns->proc_name
       && sym->ns->proc_name->attr.flavor == FL_MODULE
       && sym->attr.access != ACCESS_PRIVATE
-      && !(sym->attr.extension
-          && sym->attr.zero_comp
-          && !sym->f2k_derived->tb_sym_root
-          && !sym->f2k_derived->tb_uop_root)
       && !(sym->attr.vtype || sym->attr.pdt_template))
     {
       gfc_symbol *vtab = gfc_find_derived_vtab (sym);
diff --git a/gcc/testsuite/gfortran.dg/pr117768.f90 
b/gcc/testsuite/gfortran.dg/pr117768.f90
new file mode 100644
index 000000000000..f9cf46421c15
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr117768.f90
@@ -0,0 +1,76 @@
+! { dg-do compile }
+!
+! Fix a regession caused by the first patch for PR84674.
+!
+! Contributed by Juergen Reuter  <juergen.reu...@desy.de>
+!
+module m1
+  implicit none
+  private
+  public :: t1
+  type, abstract :: t1
+  end type t1
+end module m1
+
+module t_base
+  use m1, only: t1
+  implicit none
+  private
+  public :: t_t
+  type, abstract :: t_t
+   contains
+     procedure (t_out), deferred :: output
+  end type t_t
+
+  abstract interface
+     subroutine t_out (t, handle)
+       import
+       class(t_t), intent(inout) :: t
+       class(t1), intent(inout), optional :: handle
+     end subroutine t_out
+  end interface
+
+end module t_base
+
+
+module t_ascii
+  use m1, only: t1
+  use t_base
+  implicit none
+  private
+
+  type, abstract, extends (t_t) :: t1_t
+   contains
+     procedure :: output => t_ascii_output
+  end type t1_t
+  type, extends (t1_t) :: t2_t
+  end type t2_t
+  type, extends (t1_t) :: t3_t
+     logical :: verbose = .true.
+  end type t3_t
+
+  interface
+    module subroutine t_ascii_output &
+         (t, handle)
+      class(t1_t), intent(inout) :: t
+      class(t1), intent(inout), optional :: handle
+    end subroutine t_ascii_output
+  end interface
+end module t_ascii
+
+submodule (t_ascii) t_ascii_s
+  implicit none
+contains
+  module subroutine t_ascii_output &
+       (t, handle)
+    class(t1_t), intent(inout) :: t
+    class(t1), intent(inout), optional :: handle
+    select type (t)
+    type is (t3_t)
+    type is (t2_t)
+    class default
+       return
+    end select
+  end subroutine t_ascii_output
+end submodule t_ascii_s
+

Reply via email to