[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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.