Hi all, here is a regression fix for a problem with the NON_OVERRIDABLE attribute. For non-overridable type-bound procedures we do not have to generate a call to the vtable, but can just translate it to a simple ('non-virtual') function call. In this particular case, an additional generic binding was present, which fooled the compiler to believe that the call goes to an overridable procedure, so it tried to generate a call to a vtable entry which did not exist. The trick is simply to take the NON-OVERRIDABLE attribute from the specific procedure, not the generic one (which means the generic call has to be resolved to a specific one first).
The patch was regtested on x86_64-unknown-linux-gnu. Ok for trunk? And for 4.8/4.9 after some time? Cheers, Janus 2014-12-15 Janus Weil <ja...@gcc.gnu.org> PR fortran/64244 * resolve.c (resolve_typebound_call): New argument to pass out the non-overridable attribute of the specific procedure. (resolve_typebound_subroutine): Get overridable flag from resolve_typebound_call. 2014-12-15 Janus Weil <ja...@gcc.gnu.org> PR fortran/64244 * gfortran.dg/typebound_call_26.f90: New.
Index: gcc/fortran/resolve.c =================================================================== --- gcc/fortran/resolve.c (Revision 218751) +++ gcc/fortran/resolve.c (Arbeitskopie) @@ -5676,7 +5676,7 @@ success: /* Resolve a call to a type-bound subroutine. */ static bool -resolve_typebound_call (gfc_code* c, const char **name) +resolve_typebound_call (gfc_code* c, const char **name, bool *overridable) { gfc_actual_arglist* newactual; gfc_symtree* target; @@ -5700,6 +5700,10 @@ static bool if (!resolve_typebound_generic_call (c->expr1, name)) return false; + /* Pass along the NON_OVERRIDABLE attribute of the specific TBP. */ + if (overridable) + *overridable = !c->expr1->value.compcall.tbp->non_overridable; + /* Transform into an ordinary EXEC_CALL for now. */ if (!resolve_typebound_static (c->expr1, &target, &newactual)) @@ -5959,7 +5963,7 @@ resolve_typebound_subroutine (gfc_code *code) if (c->ts.u.derived == NULL) c->ts.u.derived = gfc_find_derived_vtab (declared); - if (!resolve_typebound_call (code, &name)) + if (!resolve_typebound_call (code, &name, NULL)) return false; /* Use the generic name if it is there. */ @@ -5991,7 +5995,7 @@ resolve_typebound_subroutine (gfc_code *code) } if (st == NULL) - return resolve_typebound_call (code, NULL); + return resolve_typebound_call (code, NULL, NULL); if (!resolve_ref (code->expr1)) return false; @@ -6004,10 +6008,10 @@ resolve_typebound_subroutine (gfc_code *code) || (!class_ref && st->n.sym->ts.type != BT_CLASS)) { gfc_free_ref_list (new_ref); - return resolve_typebound_call (code, NULL); + return resolve_typebound_call (code, NULL, NULL); } - if (!resolve_typebound_call (code, &name)) + if (!resolve_typebound_call (code, &name, &overridable)) { gfc_free_ref_list (new_ref); return false;
! { dg-do compile } ! ! PR 64244: [4.8/4.9/5 Regression] ICE at class.c:236 when using non_overridable ! ! Contributed by Ondřej Čertík <ondrej.cer...@gmail.com> module m implicit none type :: A contains generic :: f => g procedure, non_overridable :: g end type contains subroutine g(this) class(A), intent(in) :: this end subroutine end module program test_non_overridable use m, only: A implicit none class(A), allocatable :: h call h%f() end