Created attachment 40128 [details] Minimal program to test non_overridable functions in generic type-bound set Hi, As from object, I get internal compiler error (segfault) with both gcc 5.3.0 and gcc 6.1.0 in this case: In a derived type (either polymorphic or not), there is a generic type-bound procedure interface where any of the procedures are listed as "non_overridable". If the code calls any of the individual specific procedures, no error occurs. If the code calls the generic interface, I get compiler segmentation fault. I am attaching a minimal example that reproduces this behavior for both gcc 5.3.0 and 6.1.0. Thanks, Federico
I can confirm this ICE with every gfortran version from 4.7 to current trunk. The test case as provided compiles fine, but when uncommenting one of the marked lines the ICE appears. The backtrace on current trunk is: print *, ' dot_1d, generic call = ',this%dot_no_override(x1d,y1d) ! causes compiler segfault internal compiler error: in conv_function_val, at fortran/trans-expr.c:3704 0x91c09c conv_function_val /home/jweil/gcc/gcc7/trunk/gcc/fortran/trans-expr.c:3703 0x9240a2 gfc_conv_procedure_call(gfc_se*, gfc_symbol*, gfc_actual_arglist*, gfc_expr*, vec<tree_node*, va_gc, vl_embed>*) /home/jweil/gcc/gcc7/trunk/gcc/fortran/trans-expr.c:6061 0x926520 gfc_conv_function_expr /home/jweil/gcc/gcc7/trunk/gcc/fortran/trans-expr.c:6657 0x92a092 gfc_conv_expr(gfc_se*, gfc_expr*) /home/jweil/gcc/gcc7/trunk/gcc/fortran/trans-expr.c:7696 0x92a589 gfc_conv_expr_reference(gfc_se*, gfc_expr*) /home/jweil/gcc/gcc7/trunk/gcc/fortran/trans-expr.c:7831 0x95db8c gfc_trans_transfer(gfc_code*) /home/jweil/gcc/gcc7/trunk/gcc/fortran/trans-io.c:2482 0x8ce99d trans_code /home/jweil/gcc/gcc7/trunk/gcc/fortran/trans.c:1902 0x8ceb1a gfc_trans_code_cond(gfc_code*, tree_node*) /home/jweil/gcc/gcc7/trunk/gcc/fortran/trans.c:2005 0x95c7cd build_dt /home/jweil/gcc/gcc7/trunk/gcc/fortran/trans-io.c:1980 0x95c8b9 gfc_trans_write(gfc_code*) /home/jweil/gcc/gcc7/trunk/gcc/fortran/trans-io.c:2019 0x8ce913 trans_code /home/jweil/gcc/gcc7/trunk/gcc/fortran/trans.c:1874 0x8ceb39 gfc_trans_code(gfc_code*) /home/jweil/gcc/gcc7/trunk/gcc/fortran/trans.c:2013 0x90bdc8 gfc_generate_function_code(gfc_namespace*) /home/jweil/gcc/gcc7/trunk/gcc/fortran/trans-decl.c:6261 0x8ceddc gfc_generate_module_code(gfc_namespace*) /home/jweil/gcc/gcc7/trunk/gcc/fortran/trans.c:2080 0x85dc5f translate_all_program_units /home/jweil/gcc/gcc7/trunk/gcc/fortran/parse.c:6025 0x85e3a2 gfc_parse_file() /home/jweil/gcc/gcc7/trunk/gcc/fortran/parse.c:6238 0x8b7525 gfc_be_parse_file /home/jweil/gcc/gcc7/trunk/gcc/fortran/f95-lang.c:202
Here is a reduced (and slightly modified) version which gives the same ICE: module types implicit none type :: generic_class contains procedure, non_overridable :: dot_1d_no_override generic :: dot => dot_1d_no_override end type contains real function dot_1d_no_override(this,x,y) result(xdoty) class(generic_class), intent(in) :: this real, intent(in), dimension(3) :: x,y xdoty = dot_product(x,y) end function end module program main use types implicit none type(generic_class) :: a call test(a) contains subroutine test(this) class(generic_class), intent(in) :: this real, dimension(3) :: x1d = 1., y1d = -1. print *, ' dot_1d, generic call = ',this%dot(x1d,y1d) ! ICE end subroutine end
I think what happens is this: After resolving the generic TBP call to the specific one, we try to generate a polymorphic call, but that fails since the vtab does not contain an entry for the non-overridable TBP. A simple workaround is to do what had already been proposed for PR78443, namely generate a vtab entry for each TBP, no matter if it's overridable or not: Index: gcc/fortran/class.c =================================================================== --- gcc/fortran/class.c (revision 242725) +++ gcc/fortran/class.c (working copy) @@ -751,9 +751,6 @@ { gfc_component *c; - if (tb->non_overridable && !tb->overridden) - return; - c = gfc_find_component (vtype, name, true, true, NULL); if (c == NULL) That seems to work well and makes both comment #2 and comment #0 compile and run without error. However, a better fix would be to generate a non-polymorphic call after resolving the generic, just as in the case where no generics TBPs are involved.
Update with a simplification : $ cat z1.f90 module m type t contains procedure, non_overridable :: g generic :: f => g end type contains recursive function g(x) class(t), intent(in) :: x print *, x%f() end end $ gfortran-9-20181111 -c z1.f90 z1.f90:10:0: 10 | print *, x%f() | internal compiler error: in conv_function_val, at fortran/trans-expr.c:3810 0x6f95e0 conv_function_val ../../gcc/fortran/trans-expr.c:3809 0x6f95e0 gfc_conv_procedure_call(gfc_se*, gfc_symbol*, gfc_actual_arglist*, gfc_expr*, vec<tree_node*, va_gc, vl_embed>*) ../../gcc/fortran/trans-expr.c:6300 0x6fa29c gfc_conv_function_expr ../../gcc/fortran/trans-expr.c:6928 0x6ee90a gfc_conv_expr(gfc_se*, gfc_expr*) ../../gcc/fortran/trans-expr.c:8039 0x6f43b5 gfc_conv_expr_reference(gfc_se*, gfc_expr*, bool) ../../gcc/fortran/trans-expr.c:8184 0x71b007 gfc_trans_transfer(gfc_code*) ../../gcc/fortran/trans-io.c:2584 0x6c0067 trans_code ../../gcc/fortran/trans.c:2038 0x718afe build_dt ../../gcc/fortran/trans-io.c:2026 0x6c0047 trans_code ../../gcc/fortran/trans.c:2010 0x6e7674 gfc_generate_function_code(gfc_namespace*) ../../gcc/fortran/trans-decl.c:6509 0x6c3b39 gfc_generate_module_code(gfc_namespace*) ../../gcc/fortran/trans.c:2216 0x67440b translate_all_program_units ../../gcc/fortran/parse.c:6112 0x67440b gfc_parse_file() ../../gcc/fortran/parse.c:6328 0x6bc89f gfc_be_parse_file ../../gcc/fortran/f95-lang.c:204
Created attachment 53145 [details] test program: call non_overridable function from generic interface within polymorphic procedure
I've attached a simple test program that confirms ICE on gfortran 11.3.0. ICE is returned only if - the non_overridable procedure is part of a generic type-bound interface - that same generic is being called from another type-bound procedure