https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117303
--- Comment #4 from Kirill Chilikin <chilikin.k at gmail dot com> ---
The original test no longer compiles for the current development version,
because it is not possible to print TYPE(C_PTR). With an additional TRANSFER,
it has been recovered. The updated test case is
$ cat test2.f90
MODULE M1
USE, INTRINSIC :: ISO_C_BINDING
TYPE T
TYPE(C_FUNPTR) FUNPTR
END TYPE
TYPE(T), POINTER :: T_POINTER
CONTAINS
SUBROUTINE SET_FUNPTR(F)
TYPE(C_FUNPTR), INTENT(IN) :: F
T_POINTER%FUNPTR = F
END SUBROUTINE
SUBROUTINE S1(I) BIND(C)
INTEGER I
END SUBROUTINE
TYPE(C_FUNPTR) FUNCTION FUNLOC(F)
INTERFACE
SUBROUTINE F(I) BIND(C)
INTEGER I
END SUBROUTINE
END INTERFACE
FUNLOC = C_FUNLOC(F)
END FUNCTION
END MODULE
PROGRAM TEST
USE M1
INTEGER(C_INTPTR_T) I
ALLOCATE(T_POINTER)
CALL SET_FUNPTR(C_FUNLOC(S1))
! If the next line is commented, compilation with -O1 -flto fails.
CALL SET_FUNPTR(FUNLOC(S1))
PRINT *, TRANSFER(T_POINTER%FUNPTR, I)
END PROGRAM
Now if there is a new line with a call to FUNLOC instead of C_FUNLOC, the
program works correctly. This suggests that the problem is not in SUBROUTINE
S1. Maybe it is caused by C_FUNLOC? Its call generates code that is different
from FUNLOC:
$ gfortran -o test2 test2.f90 -fdump-tree-gimple
$ cat test2.f90.007t.gimple
... For the first call
{
static void (*<T6af>) (integer(kind=4) & restrict) C.4740 = s1;
set_funptr (&C.4740);
}
... For the second call
{
_3 = funloc (s1);
D.4741 = _3;
set_funptr (&D.4741);
}