gfortran ICEs on the following testcase: module foo contains real function bar(x) real :: x(2,2) bar=baz*x(1,1) end function bar real function baz(x) real :: x(2,2) baz=x(1,1) end function baz end module foo Doesn't say anything even with implicit none, so maybe it is ok that baz lookup gives the module function rather than a local variable, but shouldn't something complain that it refers to the module function in an invalid way (rather than say calling it)? Originally this was reported due to a typo (the baz* should have been bar* ). If baz returns some incompatible type such as integer, then an error is diagnosed.
Seems the ICE is quite long, seems before around (+- 25 revisions) r137400 gfortran ICEd in the FE: internal compiler error: in gfc_conv_variable, at fortran/trans-expr.c:483 and after that it ICEs in gimple verification, as the multiplication has operand with invalid type.
With --enable-checking=yes I get pr98890.f90:3:19: 3 | real function bar(x) | ^ Error: type mismatch in binary expression real(kind=4) real(kind=4) real(kind=4) (*<T5e4>) (real(kind=4)[4] * restrict) _2 = _1 * baz; pr98890.f90:3:19: internal compiler error: 'verify_gimple' failed With --enable-checking=release and GCC8 to 11, I get 5 | bar=baz*x(1,1) | ^ internal compiler error: in convert_mode_scalar, at expr.c:314 For GCC7 I get internal compiler error: in convert_move, at expr.c:229
Likewise for the following, which uses an assignment: implicit none contains real function bar(x) real :: x(2,2) bar = bar ! OK bar = baz ! ERROR: function name not reference bar = get_funptr() ! ERROR: proc-pointer returning function bar = bar * x(1,1) ! OK bar = baz * x(1,1) ! error - as above but as operator bar = get_funptr() * x(1,1) ! likewise end function bar function get_funptr() result(ptr) procedure(bar), pointer :: ptr ptr => bar end real function baz(x) result(bazr) real :: x(2,2) bazr=x(1,1) end function baz end module foo * * * I am not sure whether the problem is that expr_type == EXPR_VARIABLE instead of expr_type == EXPR_FUNCTION or whether the proper fix should be inside both resolve_ordinary_assign() and resolve_operator() a check like: symbol_attribute rhs_attr = gfc_expr_attr (rhs); if (rhs_attr.function && ...) { gfc_error ("Unexpected function name at %L", &rhs->where); return false; } if (rhs_attr.proc_pointer) { gfc_error ("Unexpected procedure pointer at %L", &rhs->where); return false; } where "..." detects that the rhs may be used as result name in this context. This check always confuses me. And a quick try failed: I tried rhs_attr – but it is identical for 'bar' and baz'; and also 'sym->result = sym' is the same (if changing 'baz' to use no result variable). I also thought about the namespace but thanks to BLOCK and contained procedures (which may access their parent's result variable) it is not that simple. * * * I have not checked but, e.g., for 'call foo(baz)' a similar issue may pop up. I think not occurring, but to check: proc_pointer_comp (should be resolved already at parse time?) and derived-type procedures returning proc pointers (same check as for other functions).
Related issue but without an ICE: contains integer function f1() !f2 = 1 ! gives an error as expected j = f2 ! <<<< accepted; cast of function addr to integer(kind=4) f1 = 1 ! ↑ ifort: 'already been used as an external function name' end function integer function f2() f2=1 end function end
(In reply to Tobias Burnus from comment #4) > Related issue but without an ICE: > > contains > integer function f1() > !f2 = 1 ! gives an error as expected > j = f2 ! <<<< accepted; cast of function addr to integer(kind=4) > f1 = 1 ! ↑ ifort: 'already been used as an external function name' > end function > integer function f2() > f2=1 > end function > end A variation with a question: program p1 implicit none integer j, k j = 99 k = f1() print *, j, k contains integer function f1() !f2 = 1 j = f2 ! Should this be warned or rejected? print *, j f1 = 1 ! This should not be rejected end function integer function f2() f2=1 end function end
I should have noted in the above case, if we remove the parens on line 5, k = f1 is rejected.