Package: hdf5
Version: 2.2.0+repack-5
Severity: minor
Tags: patch upstream
Control: forwarded -1 https://github.com/HDFGroup/hdf5/pull/6794

Dear Maintainer,

With LTO enabled, the build fails linking the Fortran test program:

 /usr/bin/ld: ...ltrans.o:(.rodata+0x58): undefined reference to 
`test_append_flush_callback'
 collect2: error: ld returned 1 exit status
 make[4]: *** [fortran/test/CMakeFiles/testhdf5_fortran.dir/build.make:333: 
bin/testhdf5_fortran] Error 1

fortran/test/tH5F_SWMR.F90 passes C_FUNLOC(test_append_flush_callback)
directly as an actual argument. gfortran stores the function address in
a static constant, and LTO does not see that as a reference, so it drops
the callback. This is GCC PR 117303
(https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117303), fixed in GCC 16
and on the gcc-15 branch.

Debian does not build with LTO by default, so the Debian build is not
affected. Ubuntu enables LTO by default, so Ubuntu builds of this
package fail. I hit it building 2.2.0+repack-5 for Ubuntu 24.04 (GCC 13).
Anyone building with DEB_BUILD_MAINT_OPTIONS=optimize=+lto and GCC 11 to
15 would hit it too.

The attached quilt patch assigns C_FUNLOC to a variable first, as the
other Fortran tests already do. It is the upstream fix
(https://github.com/HDFGroup/hdf5/pull/6794), so it can be dropped once
that is in a release.

Thanks,
Scot Breitenfeld
The HDF Group
Description: Fix testhdf5_fortran link failure with LTO
 Passing C_FUNLOC() directly as an argument hits GCC PR 117303 with LTO
 (undefined reference to test_append_flush_callback). Assign it to a
 variable first.
Origin: upstream, https://github.com/HDFGroup/hdf5/pull/6794
Bug: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117303

diff --git a/fortran/test/tH5F_SWMR.F90 b/fortran/test/tH5F_SWMR.F90
--- a/fortran/test/tH5F_SWMR.F90
+++ b/fortran/test/tH5F_SWMR.F90
@@ -110,6 +110,7 @@ CONTAINS
     INTEGER(HSIZE_T), DIMENSION(1:2) :: boundary
     INTEGER :: ndims
     TYPE(C_FUNPTR) :: callback_func
+    TYPE(C_FUNPTR) :: append_cb
     TYPE(C_PTR) :: user_data
     LOGICAL :: flag_set
 #ifdef H5_HAVE_HL
@@ -121,6 +122,9 @@ CONTAINS
 #endif
 
     ! Initialize
+    ! Assign C_FUNLOC to a variable rather than passing it directly as an argument:
+    ! with LTO, gfortran before GCC 16 drops the callback and fails to link (GCC PR 117303)
+    append_cb = C_FUNLOC(test_append_flush_callback)
     filename = "swmr_test.h5"
     CALL h5_fixname_f(filename, fix_filename, H5P_DEFAULT_F, error)
     CALL check("h5_fixname_f", error, total_error)
@@ -245,7 +249,7 @@ CONTAINS
     CALL verify("h5pset_append_flush_f: counter initial value", INT(callback_counter), 0, total_error)
 
     ! Set append flush with callback function and user data
-    CALL h5pset_append_flush_f(dapl_id, ndims, boundary, error, C_FUNLOC(test_append_flush_callback), C_LOC(callback_counter))
+    CALL h5pset_append_flush_f(dapl_id, ndims, boundary, error, append_cb, C_LOC(callback_counter))
     CALL check("h5pset_append_flush_f (with callback)", error, total_error)
 
     ! Verify counter is still 0 (callback not invoked yet - only invoked during dataset operations)
@@ -302,7 +306,7 @@ CONTAINS
     ! Set append flush with boundary=1 and our callback
     boundary(1) = 1
     CALL h5pset_append_flush_f(dapl_id, 1, boundary(1:1), error, &
-                                C_FUNLOC(test_append_flush_callback), C_LOC(callback_counter))
+                                append_cb, C_LOC(callback_counter))
     CALL check("h5pset_append_flush_f (for append test)", error, total_error)
 
     ! Create dataset with the callback-enabled DAPL

Attachment: smime.p7s
Description: S/MIME cryptographic signature

Reply via email to