From 9797d7f70be225181237b2a5e431ceddcd3b2061 Mon Sep 17 00:00:00 2001 From: Jonas Rembser Date: Wed, 26 Nov 2025 13:18:13 +0100 Subject: [PATCH 1/3] [h2root] Adapt to GCC 8 passing convention for string length According to the `gfortran` argument passing conventions, for any Fortran procedure, the compiler will automatically define a C prototype. This is what we use in `h2root`. Note that for procedures like `HROPEN` that takes string arguments, the signature of the C prototype will have extra arguments for the string lengths, which we also have to include in our forward declaration and usage. However, the type of these was changed with GCC 8 to size_t, so we have to also account for that as recommended in [1]. Otherwise, we get undefined behavor, which causes the `h2root` test to fail on ARM64 with GCC 14. [1] https://gcc.gnu.org/onlinedocs/gfortran/Argument-passing-conventions.html (cherry picked from commit aafddfbb1c6f44c135c3f172d7cf5d9ac5d7f79c) (cherry picked from commit 596cfee42b07c34c015032506c24f0b0b94852ac) --- main/src/h2root.cxx | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/main/src/h2root.cxx b/main/src/h2root.cxx index b839c9d8319b4..87133310483a9 100644 --- a/main/src/h2root.cxx +++ b/main/src/h2root.cxx @@ -131,6 +131,15 @@ void MAIN__() {} # define type_of_call # define DEFCHAR const char* # define PASSCHAR(string) string + +// As recommended in +// https://gcc.gnu.org/onlinedocs/gfortran/Argument-passing-conventions.html +#if __GNUC__ > 7 +typedef size_t fortran_charlen_t; +#else +typedef int fortran_charlen_t; +#endif + #else # define hlimit HLIMIT # define hropen HROPEN @@ -169,7 +178,7 @@ void MAIN__() {} extern "C" void type_of_call hlimit(const int&); #ifndef WIN32 extern "C" void type_of_call hropen(const int&,DEFCHAR,DEFCHAR,DEFCHAR, - const int&,const int&,const int,const int,const int); + const int&,const int&,fortran_charlen_t,fortran_charlen_t,fortran_charlen_t); #else extern "C" void type_of_call hropen(const int&,DEFCHAR,DEFCHAR,DEFCHAR, const int&,const int&); @@ -179,7 +188,7 @@ extern "C" void type_of_call hrin(const int&,const int&,const int&); extern "C" void type_of_call hnoent(const int&,const int&); #ifndef WIN32 extern "C" void type_of_call hgive(const int&,DEFCHAR,const int&,const float&,const float&, - const int&,const float&,const float&,const int&,const int&,const int); + const int&,const float&,const float&,const int&,const int&,fortran_charlen_t); #else extern "C" void type_of_call hgive(const int&,DEFCHAR,const int&,const float&,const float&, const int&,const float&,const float&,const int&,const int&); @@ -187,20 +196,20 @@ extern "C" void type_of_call hgive(const int&,DEFCHAR,const int&,const float&,c #ifndef WIN32 extern "C" void type_of_call hgiven(const int&,DEFCHAR,const int&,DEFCHAR, - const float&,const float&,const int,const int); + const float&,const float&,fortran_charlen_t,fortran_charlen_t); #else extern "C" void type_of_call hgiven(const int&,DEFCHAR,const int&,DEFCHAR, const float&,const float&); #endif #ifndef WIN32 -extern "C" void type_of_call hntvar2(const int&,const int&,DEFCHAR,DEFCHAR,DEFCHAR,int&,int&,int&,int&,int&,const int,const int, const int); +extern "C" void type_of_call hntvar2(const int&,const int&,DEFCHAR,DEFCHAR,DEFCHAR,int&,int&,int&,int&,int&,fortran_charlen_t,fortran_charlen_t,fortran_charlen_t); #else extern "C" void type_of_call hntvar2(const int&,const int&,DEFCHAR,DEFCHAR,DEFCHAR,int&,int&,int&,int&,int&); #endif #ifndef WIN32 -extern "C" void type_of_call hbnam(const int&,DEFCHAR,const int&,DEFCHAR,const int&,const int, const int); +extern "C" void type_of_call hbnam(const int&,DEFCHAR,const int&,DEFCHAR,const int&,fortran_charlen_t,fortran_charlen_t); #else extern "C" void type_of_call hbnam(const int&,DEFCHAR,const int&,DEFCHAR,const int&); #endif @@ -232,14 +241,14 @@ extern "C" double type_of_call hije(const int&,const int&,const int&); #endif #ifndef WIN32 -extern "C" void type_of_call hcdir(DEFCHAR,DEFCHAR ,const int,const int); +extern "C" void type_of_call hcdir(DEFCHAR,DEFCHAR ,fortran_charlen_t,fortran_charlen_t); #else extern "C" void type_of_call hcdir(DEFCHAR,DEFCHAR); #endif extern "C" void type_of_call zitoh(const int&,const int&,const int&); #ifndef WIN32 -extern "C" void type_of_call uhtoc(const int&,const int&,DEFCHAR,int&,const int); +extern "C" void type_of_call uhtoc(const int&,const int&,DEFCHAR,int&,fortran_charlen_t); #else extern "C" void type_of_call uhtoc(const int&,const int&,DEFCHAR,int&); #endif From 778d0c6261483d3fc15c9b0223da1b0812105581 Mon Sep 17 00:00:00 2001 From: ferdymercury Date: Wed, 26 Nov 2025 19:13:17 +0100 Subject: [PATCH 2/3] [hbook] Adapt to GCC 8 passing convention for string length Follow-up of https://github.com/root-project/root/pull/20535 (cherry picked from commit 4ac2999b138f953ee1a291786b44546a70e212ca) (cherry picked from commit d2a8c79848bdec328ce648f2baeaa0bf703e244a) --- hist/hbook/src/THbookFile.cxx | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/hist/hbook/src/THbookFile.cxx b/hist/hbook/src/THbookFile.cxx index 1c09f73e58aa7..d00a8fc6f7084 100644 --- a/hist/hbook/src/THbookFile.cxx +++ b/hist/hbook/src/THbookFile.cxx @@ -137,6 +137,15 @@ static Int_t gLastEntry = -1; # define type_of_call # define DEFCHAR const char* # define PASSCHAR(string) string + +// As recommended in +// https://gcc.gnu.org/onlinedocs/gfortran/Argument-passing-conventions.html +#if __GNUC__ > 7 +typedef size_t fortran_charlen_t; +#else +typedef int fortran_charlen_t; +#endif + #else # define hlimit HLIMIT # define hldir HLDIR @@ -177,8 +186,8 @@ static Int_t gLastEntry = -1; extern "C" void type_of_call hlimit(const int&); #ifndef WIN32 extern "C" void type_of_call hropen(const int&,DEFCHAR,DEFCHAR,DEFCHAR, - const int&,const int&,const int,const int,const int); -extern "C" void type_of_call hrend(DEFCHAR,const int); + const int&,const int&,fortran_charlen_t,fortran_charlen_t,fortran_charlen_t); +extern "C" void type_of_call hrend(DEFCHAR,fortran_charlen_t); #else extern "C" void type_of_call hropen(const int&,DEFCHAR,DEFCHAR,DEFCHAR, const int&,const int&); @@ -189,7 +198,7 @@ extern "C" void type_of_call hrin(const int&,const int&,const int&); extern "C" void type_of_call hnoent(const int&,const int&); #ifndef WIN32 extern "C" void type_of_call hgive(const int&,DEFCHAR,const int&,const float&,const float&, - const int&,const float&,const float&,const int&,const int&,const int); + const int&,const float&,const float&,const int&,const int&,fortran_charlen_t); #else extern "C" void type_of_call hgive(const int&,DEFCHAR,const int&,const float&,const float&, const int&,const float&,const float&,const int&,const int&); @@ -198,8 +207,8 @@ extern "C" void type_of_call hgive(const int&,DEFCHAR,const int&,const float&,c //SUBROUTINE HGNT1(IDD,BLKNA1,VAR,IOFFST,NVAR,IDNEVT,IERROR) #ifndef WIN32 extern "C" void type_of_call hgiven(const int&,DEFCHAR,const int&,DEFCHAR, - const float&,const float&,const int,const int); -extern "C" void type_of_call hgnt1(const int&,DEFCHAR,DEFCHAR,const int&,const int&,const int&,const int&,const int,const int); + const float&,const float&,fortran_charlen_t,fortran_charlen_t); +extern "C" void type_of_call hgnt1(const int&,DEFCHAR,DEFCHAR,const int&,const int&,const int&,const int&,fortran_charlen_t,fortran_charlen_t); #else extern "C" void type_of_call hgiven(const int&,DEFCHAR,const int&,DEFCHAR, const float&,const float&); @@ -207,15 +216,15 @@ extern "C" void type_of_call hgnt1(const int&,DEFCHAR,DEFCHAR,const int&,const #endif #ifndef WIN32 -extern "C" void type_of_call hntvar2(const int&,const int&,DEFCHAR,DEFCHAR,DEFCHAR,int&,int&,int&,int&,int&,const int,const int, const int); -extern "C" void type_of_call hntvar3(const int&,const int&,DEFCHAR, const int); +extern "C" void type_of_call hntvar2(const int&,const int&,DEFCHAR,DEFCHAR,DEFCHAR,int&,int&,int&,int&,int&,fortran_charlen_t,fortran_charlen_t, fortran_charlen_t); +extern "C" void type_of_call hntvar3(const int&,const int&,DEFCHAR, fortran_charlen_t); #else extern "C" void type_of_call hntvar2(const int&,const int&,DEFCHAR,DEFCHAR,DEFCHAR,int&,int&,int&,int&,int&); extern "C" void type_of_call hntvar3(const int&,const int&,DEFCHAR); #endif #ifndef WIN32 -extern "C" void type_of_call hbnam(const int&,DEFCHAR,const int&,DEFCHAR,const int&,const int, const int); +extern "C" void type_of_call hbnam(const int&,DEFCHAR,const int&,DEFCHAR,const int&,fortran_charlen_t, fortran_charlen_t); #else extern "C" void type_of_call hbnam(const int&,DEFCHAR,const int&,DEFCHAR,const int&); #endif @@ -237,8 +246,8 @@ extern "C" void type_of_call hix(const int&,const int&,const float&); extern "C" void type_of_call hijxy(const int&,const int&,const int&,const float&,const float&); extern "C" float type_of_call hije(const int&,const int&,const int&); #ifndef WIN32 -extern "C" void type_of_call hcdir(DEFCHAR,DEFCHAR ,const int,const int); -extern "C" void type_of_call hldir(DEFCHAR,DEFCHAR ,const int,const int); +extern "C" void type_of_call hcdir(DEFCHAR,DEFCHAR ,fortran_charlen_t,fortran_charlen_t); +extern "C" void type_of_call hldir(DEFCHAR,DEFCHAR ,fortran_charlen_t,fortran_charlen_t); #else extern "C" void type_of_call hcdir(DEFCHAR,DEFCHAR); extern "C" void type_of_call hldir(DEFCHAR,DEFCHAR); From e21329e34a20cf095baefcd95edbb8ee1f33b18b Mon Sep 17 00:00:00 2001 From: ferdymercury Date: Mon, 1 Dec 2025 19:47:03 +0100 Subject: [PATCH 3/3] [h2root] Adapt to GCC 8 passing convention for string length Follow-up of https://github.com/root-project/root/commit/aafddfbb1c6f44c135c3f172d7cf5d9ac5d7f79c (cherry picked from commit 34af31ca2f895ace0428f30fb923470cfabcf506) (cherry picked from commit 8e90e920f0fa2dad0acddcfb1f28cd59c966c135) --- main/src/h2root.cxx | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/main/src/h2root.cxx b/main/src/h2root.cxx index 87133310483a9..1e72e0cee44bd 100644 --- a/main/src/h2root.cxx +++ b/main/src/h2root.cxx @@ -215,10 +215,18 @@ extern "C" void type_of_call hbnam(const int&,DEFCHAR,const int&,DEFCHAR,const #endif extern "C" void type_of_call hprntu(const int&); -extern "C" void type_of_call hgnpar(const int&,const char *,const int); +#ifndef WIN32 +extern "C" void type_of_call hgnpar(const int&,DEFCHAR,fortran_charlen_t); +#else +extern "C" void type_of_call hgnpar(const int&,DEFCHAR); +#endif extern "C" void type_of_call hgnf(const int&,const int&,const float&,const int&); extern "C" void type_of_call hgnt(const int&,const int&,const int&); -extern "C" void type_of_call rzink(const int&,const int&,const char *,const int); +#ifndef WIN32 +extern "C" void type_of_call rzink(const int&,const int&,DEFCHAR,fortran_charlen_t); +#else +extern "C" void type_of_call rzink(const int&,const int&,DEFCHAR); +#endif extern "C" void type_of_call hdcofl(); extern "C" void type_of_call hmaxim(const int&,const float&); extern "C" void type_of_call hminim(const int&,const float&);