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)
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. */
&& 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);
--- /dev/null
+! { dg-do compile }
+!
+! Fix a regession caused by the first patch for PR84674.
+!
+! Contributed by Juergen Reuter <juergen.reuter@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
+