[PATCH] fortran: Fix creation of reference to C_FUNLOC argument [PR117303]
Kirill Chilikin <[email protected]>
| Newsgroups | gmane.comp.gcc.patches,gmane.comp.gcc.fortran |
|---|---|
| Message-ID | <[email protected]> |
Dear maintainers,
The attached patch fixes PR 117303. The reference returned by C_FUNLOC
is assigned to a variable in the added code. Without that,
no reference from the calling subprogram to the argument of C_FUNLOC
was created in the call graph, resulting in an undefined-reference error
with link-time optimization.
The patch was tested using with "check-fortran" on a x86_64-pc-linux-gnu
system. One existing test from gfortran.dg/c_funloc_test_7.f90 failed
as expected due to code-generation change. The generated code was
cfp = (void (*<T6d>) (void)) nocsub;
but now it became
void * D.4685;
D.4685 = (void *) nocsub;
cfp = (void (*<T6f>) (void)) D.4685;
The test has been modified in accordance with the changes.
Another test, gfortran.dg/c_funloc_test_9.f90, has been converted from
the test case in PR.
PR fortran/117303
gcc/fortran/ChangeLog:
* trans-intrinsic.cc (conv_isocbinding_function):
Assign the reference returned by C_FUNLOC to a variable.
gcc/testsuite/ChangeLog:
* gfortran.dg/c_funloc_tests_7.f90:
Updated test due to changed code generation.
* gfortran.dg/c_funloc_tests_9.f90: New test.
Signed-off-by: Kirill Chilikin <[email protected]>
---
Please see the attached file for the actual patch.
If accepted, please commit the change as I do not have write access.
Regards,
Kirill
pr117303.patch
(text/x-patch, 3.5 KB)
From 0577f0452d7fd6973dc30f8aa8d8a3091c1560fa Mon Sep 17 00:00:00 2001 From: Kirill Chilikin <[email protected]> Date: Sun, 25 Jan 2026 14:43:08 +0700 Subject: [PATCH] fortran: Fix creation of reference to C_FUNLOC argument [PR117303] The reference returned by C_FUNLOC is assigned to a variable. Without that, no reference from the calling subprogram to the argument of C_FUNLOC was created in the call graph, resulting in an undefined-reference error with link-time optimization. Please see PR 117303 for more details. PR fortran/117303 gcc/fortran/ChangeLog: * trans-intrinsic.cc (conv_isocbinding_function): Assign the reference returned by C_FUNLOC to a variable. gcc/testsuite/ChangeLog: * gfortran.dg/c_funloc_tests_7.f90: Updated test due to changed code generation. * gfortran.dg/c_funloc_tests_9.f90: New test. Signed-off-by: Kirill Chilikin <[email protected]> --- gcc/fortran/trans-intrinsic.cc | 9 ++++- .../gfortran.dg/c_funloc_tests_7.f90 | 2 +- .../gfortran.dg/c_funloc_tests_9.f90 | 34 +++++++++++++++++++ 3 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/c_funloc_tests_9.f90 diff --git a/gcc/fortran/trans-intrinsic.cc b/gcc/fortran/trans-intrinsic.cc index 722ea933249..cfdd0258241 100644 --- a/gcc/fortran/trans-intrinsic.cc +++ b/gcc/fortran/trans-intrinsic.cc @@ -9864,7 +9864,14 @@ conv_isocbinding_function (gfc_se *se, gfc_expr *expr) 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; diff --git a/gcc/testsuite/gfortran.dg/c_funloc_tests_7.f90 b/gcc/testsuite/gfortran.dg/c_funloc_tests_7.f90 index 7a4464ab552..1e199b4503b 100644 --- a/gcc/testsuite/gfortran.dg/c_funloc_tests_7.f90 +++ b/gcc/testsuite/gfortran.dg/c_funloc_tests_7.f90 @@ -16,6 +16,6 @@ cfp = c_funloc (noCsub) 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" } } diff --git a/gcc/testsuite/gfortran.dg/c_funloc_tests_9.f90 b/gcc/testsuite/gfortran.dg/c_funloc_tests_9.f90 new file mode 100644 index 00000000000..2ebb951a6fc --- /dev/null +++ b/gcc/testsuite/gfortran.dg/c_funloc_tests_9.f90 @@ -0,0 +1,34 @@ +! { 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 -- 2.39.5