From 66e0d8f0a99077d00e34c88c8dd31cb26841473a Mon Sep 17 00:00:00 2001 From: Dan Bonachea Date: Sun, 5 Apr 2026 19:07:14 -0700 Subject: [PATCH] Adjust end version for GFortran c_funloc bug workaround According to https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124652 the GFortran defect with c_funloc has been fixed in the forthcoming 15.3 and 16.x releases. Cap the workaround activation at version 15.2, the last GFortran version where it should be needed, to ensure the workaround is not mistakenly applied to a fixed compiler (where it could lead to a crash). --- include/language-support.F90 | 15 +++++++++++++++ src/caffeine/caffeine.c | 3 ++- src/caffeine/co_reduce_s.F90 | 15 +++------------ 3 files changed, 20 insertions(+), 13 deletions(-) diff --git a/include/language-support.F90 b/include/language-support.F90 index bebd5411..2ec2dcf9 100644 --- a/include/language-support.F90 +++ b/include/language-support.F90 @@ -43,6 +43,21 @@ # endif #endif +#ifndef NEED_C_FUNLOC_WORKAROUND +# if __GFORTRAN__ && HAVE_GCC_VERSION <= 150200 + ! Gfortran 13..15.2 bug workaround, believed to be fixed in 15.3 and 16.x: + ! https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124652 +# define NEED_C_FUNLOC_WORKAROUND 1 +# else +# define NEED_C_FUNLOC_WORKAROUND 0 +# endif +#endif +#if NEED_C_FUNLOC_WORKAROUND +# define CAF_C_FUNLOC_PROCPTR(p) caf_c_funloc_deref(c_funloc(p)) +#else +# define CAF_C_FUNLOC_PROCPTR(p) c_funloc(p) +#endif + ! ISO_FORTRAN_ENV constant value control: ! The following knobs influence Caffeine's choice of value for the named constants ! specified by PRIF for ISO_FORTRAN_ENV: diff --git a/src/caffeine/caffeine.c b/src/caffeine/caffeine.c index 745e360a..a3968a1b 100644 --- a/src/caffeine/caffeine.c +++ b/src/caffeine/caffeine.c @@ -508,7 +508,8 @@ void caf_atomic_logical(int opcode, int image, void* addr, int64_t *result, int6 } //------------------------------------------------------------------- -// gfortran 13.2 .. 15 : c_funloc is non-compliant +// gfortran 13.2 .. 15.2 : c_funloc is non-compliant: +// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124652 // it erroneously generates a non-callable pointer to a pointer to the subroutine // This helper is used to undo that incorrect extra level of indirection typedef void (*funloc_t)(void); diff --git a/src/caffeine/co_reduce_s.F90 b/src/caffeine/co_reduce_s.F90 index aaca911d..bdb287c7 100644 --- a/src/caffeine/co_reduce_s.F90 +++ b/src/caffeine/co_reduce_s.F90 @@ -2,6 +2,7 @@ ! Terms of use are as specified in LICENSE.txt #include "assert_macros.h" +#include "language-support.F90" submodule(prif:prif_private_s) co_reduce_s ! DO NOT ADD USE STATEMENTS HERE @@ -37,12 +38,7 @@ subroutine contiguous_co_reduce(a, operation_wrapper, cdata, result_image, stat, if (present(stat)) stat=0 call_assert(associated(operation_wrapper)) -# if __GFORTRAN__ - ! Gfortran 13..15 bug workaround - funptr = caf_c_funloc_deref(c_funloc(operation_wrapper)) -# else - funptr = c_funloc(operation_wrapper) -# endif + funptr = CAF_C_FUNLOC_PROCPTR(operation_wrapper) call_assert(c_associated(funptr)) @@ -70,12 +66,7 @@ module subroutine prif_co_reduce_cptr(a_ptr, element_size, element_count, operat if (present(stat)) stat=0 call_assert(associated(operation_wrapper)) -# if __GFORTRAN__ - ! Gfortran 13..15 bug workaround - funptr = caf_c_funloc_deref(c_funloc(operation_wrapper)) -# else - funptr = c_funloc(operation_wrapper) -# endif + funptr = CAF_C_FUNLOC_PROCPTR(operation_wrapper) call_assert(c_associated(funptr)) call caf_co_reduce_cptr( &