se->expr = gfc_evaluate_now (se->expr, &se->pre);
}
else if (expr->value.function.isym->id == GFC_ISYM_C_FUNLOC)
- gfc_conv_expr_reference (se, arg->expr);
+ {
+ gfc_conv_expr_reference (se, arg->expr);
+ /* The code below is necessary to create a reference from the calling
+ subprogram to the argument of C_FUNLOC() in the call graph.
+ Please see PR 117303 for more details. */
+ se->expr = convert (pvoid_type_node, se->expr);
+ se->expr = gfc_evaluate_now (se->expr, &se->pre);
+ }
else if (expr->value.function.isym->id == GFC_ISYM_C_ASSOCIATED)
{
gfc_se arg1se;
call c_f_procpointer (cfp, fint)
end
-! { dg-final { scan-tree-dump-times "cfp =\[^;\]+ nocsub;" 1 "original" } }
+! { dg-final { scan-tree-dump-times "D.\[0-9\]* =\[^;\]+ nocsub;" 1 "original" } }
! { dg-final { scan-tree-dump-times "fint =\[^;\]+ cfp;" 1 "original" } }
--- /dev/null
+! { dg-do link }
+! { dg-options "-O1 -flto" }
+! PR 117303
+
+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() BIND(C)
+ END SUBROUTINE
+
+END MODULE
+
+PROGRAM TEST
+ USE M1
+ INTEGER(C_INTPTR_T) I
+ ALLOCATE(T_POINTER)
+ ! There was no reference from TEST to S1 in the call graph,
+ ! resulting in undefined-reference error with link-time optimization.
+ CALL SET_FUNPTR(C_FUNLOC(S1))
+ PRINT *, TRANSFER(T_POINTER%FUNPTR, I)
+END PROGRAM