From fef67987cf502fe322e92ddce22eea7ac46b4d75 Mon Sep 17 00:00:00 2001 From: Sandra Loosemore Date: Thu, 8 Jul 2021 08:21:20 -0700 Subject: [PATCH] Bind(C): Fix type encodings in ISO_Fortran_binding.h ISO_Fortran_binding.h had many incorrect hardwired kind encodings in the definitions of the CFI_type_* macros. Additionally, not all targets support all the defined type encodings, and the Fortran standard requires those macros to have a negative value. This patch changes ISO_Fortran_binding.h to use sizeof instead of hard-coded sizes, and assembles it from fragments that reflect the set of types supported by the target. 2021-07-22 Sandra Loosemore Tobias Burnus libgfortran/ PR libfortran/101305 * ISO_Fortran_binding.h: Fix hard-coded sizes and split into... * ISO_Fortran_binding-1-tmpl.h: New file. * ISO_Fortran_binding-2-tmpl.h: New file. * ISO_Fortran_binding-3-tmpl.h: New file. * Makefile.am: Add rule for generating ISO_Fortran_binding.h. Adjust pathnames to that file. * Makefile.in: Regenerated. * mk-kinds-h.sh: New file. * runtime/ISO_Fortran_binding.c: Fix include path. --- ...tran_binding.h => ISO_Fortran_binding-1-tmpl.h} | 74 ++++++++++------------ libgfortran/ISO_Fortran_binding-2-tmpl.h | 42 ++++++++++++ libgfortran/ISO_Fortran_binding-3-tmpl.h | 5 ++ libgfortran/Makefile.am | 15 ++++- libgfortran/Makefile.in | 16 ++++- libgfortran/mk-kinds-h.sh | 25 ++++++-- libgfortran/runtime/ISO_Fortran_binding.c | 2 +- 7 files changed, 128 insertions(+), 51 deletions(-) rename libgfortran/{ISO_Fortran_binding.h => ISO_Fortran_binding-1-tmpl.h} (66%) create mode 100644 libgfortran/ISO_Fortran_binding-2-tmpl.h create mode 100644 libgfortran/ISO_Fortran_binding-3-tmpl.h diff --git a/libgfortran/ISO_Fortran_binding.h b/libgfortran/ISO_Fortran_binding-1-tmpl.h similarity index 66% rename from libgfortran/ISO_Fortran_binding.h rename to libgfortran/ISO_Fortran_binding-1-tmpl.h index 6c4d461..8852c99 100644 --- a/libgfortran/ISO_Fortran_binding.h +++ b/libgfortran/ISO_Fortran_binding-1-tmpl.h @@ -43,8 +43,8 @@ extern "C" { #define CFI_attribute_other 2 /* Error codes. - CFI_INVALID_STRIDE should be defined in the standard because they are useful to the implementation of the functions. - */ + Note that CFI_FAILURE and CFI_INVALID_STRIDE are specific to GCC + and not part of the Fortran standard */ #define CFI_SUCCESS 0 #define CFI_FAILURE 1 #define CFI_ERROR_BASE_ADDR_NULL 2 @@ -159,48 +159,38 @@ extern int CFI_setpointer (CFI_cdesc_t *, CFI_cdesc_t *, const CFI_index_t []); #define CFI_type_other -1 /* Types with kind parameter. - The kind parameter represents the type's byte size. The exception is kind = 10, which has byte size of 64 but 80 bit precision. Complex variables are double the byte size of their real counterparts. The ucs4_char matches wchar_t if sizeof (wchar_t) == 4. + The kind parameter represents the type's byte size. The exception is + real kind = 10, which has byte size of 128 bits but 80 bit precision. + Complex variables are double the byte size of their real counterparts. + The ucs4_char matches wchar_t if sizeof (wchar_t) == 4. */ #define CFI_type_char (CFI_type_Character + (1 << CFI_type_kind_shift)) #define CFI_type_ucs4_char (CFI_type_Character + (4 << CFI_type_kind_shift)) /* C-Fortran Interoperability types. */ -#define CFI_type_signed_char (CFI_type_Integer + (1 << CFI_type_kind_shift)) -#define CFI_type_short (CFI_type_Integer + (2 << CFI_type_kind_shift)) -#define CFI_type_int (CFI_type_Integer + (4 << CFI_type_kind_shift)) -#define CFI_type_long (CFI_type_Integer + (8 << CFI_type_kind_shift)) -#define CFI_type_long_long (CFI_type_Integer + (8 << CFI_type_kind_shift)) -#define CFI_type_size_t (CFI_type_Integer + (8 << CFI_type_kind_shift)) -#define CFI_type_int8_t (CFI_type_Integer + (1 << CFI_type_kind_shift)) -#define CFI_type_int16_t (CFI_type_Integer + (2 << CFI_type_kind_shift)) -#define CFI_type_int32_t (CFI_type_Integer + (4 << CFI_type_kind_shift)) -#define CFI_type_int64_t (CFI_type_Integer + (8 << CFI_type_kind_shift)) -#define CFI_type_int_least8_t (CFI_type_Integer + (1 << CFI_type_kind_shift)) -#define CFI_type_int_least16_t (CFI_type_Integer + (2 << CFI_type_kind_shift)) -#define CFI_type_int_least32_t (CFI_type_Integer + (4 << CFI_type_kind_shift)) -#define CFI_type_int_least64_t (CFI_type_Integer + (8 << CFI_type_kind_shift)) -#define CFI_type_int_fast8_t (CFI_type_Integer + (1 << CFI_type_kind_shift)) -#define CFI_type_int_fast16_t (CFI_type_Integer + (2 << CFI_type_kind_shift)) -#define CFI_type_int_fast32_t (CFI_type_Integer + (4 << CFI_type_kind_shift)) -#define CFI_type_int_fast64_t (CFI_type_Integer + (8 << CFI_type_kind_shift)) -#define CFI_type_intmax_t (CFI_type_Integer + (8 << CFI_type_kind_shift)) -#define CFI_type_intptr_t (CFI_type_Integer + (8 << CFI_type_kind_shift)) -#define CFI_type_ptrdiff_t (CFI_type_Integer + (8 << CFI_type_kind_shift)) -#define CFI_type_int128_t (CFI_type_Integer + (16 << CFI_type_kind_shift)) -#define CFI_type_int_least128_t (CFI_type_Integer + (16 << CFI_type_kind_shift)) -#define CFI_type_int_fast128_t (CFI_type_Integer + (16 << CFI_type_kind_shift)) -#define CFI_type_Bool (CFI_type_Logical + (1 << CFI_type_kind_shift)) -#define CFI_type_float (CFI_type_Real + (4 << CFI_type_kind_shift)) -#define CFI_type_double (CFI_type_Real + (8 << CFI_type_kind_shift)) -#define CFI_type_long_double (CFI_type_Real + (10 << CFI_type_kind_shift)) -#define CFI_type_float128 (CFI_type_Real + (16 << CFI_type_kind_shift)) -#define CFI_type_float_Complex (CFI_type_Complex + (4 << CFI_type_kind_shift)) -#define CFI_type_double_Complex (CFI_type_Complex + (8 << CFI_type_kind_shift)) -#define CFI_type_long_double_Complex (CFI_type_Complex + (10 << CFI_type_kind_shift)) -#define CFI_type_float128_Complex (CFI_type_Complex + (16 << CFI_type_kind_shift)) - -#ifdef __cplusplus -} -#endif - -#endif /* ISO_FORTRAN_BINDING_H */ +#define CFI_type_signed_char (CFI_type_Integer + (sizeof (char) << CFI_type_kind_shift)) +#define CFI_type_short (CFI_type_Integer + (sizeof (short) << CFI_type_kind_shift)) +#define CFI_type_int (CFI_type_Integer + (sizeof (int) << CFI_type_kind_shift)) +#define CFI_type_long (CFI_type_Integer + (sizeof (long) << CFI_type_kind_shift)) +#define CFI_type_long_long (CFI_type_Integer + (sizeof (long long) << CFI_type_kind_shift)) +#define CFI_type_size_t (CFI_type_Integer + (sizeof (size_t) << CFI_type_kind_shift)) +#define CFI_type_int8_t (CFI_type_Integer + (sizeof (int8_t) << CFI_type_kind_shift)) +#define CFI_type_int16_t (CFI_type_Integer + (sizeof (int16_t) << CFI_type_kind_shift)) +#define CFI_type_int32_t (CFI_type_Integer + (sizeof (int32_t) << CFI_type_kind_shift)) +#define CFI_type_int64_t (CFI_type_Integer + (sizeof (int64_t) << CFI_type_kind_shift)) +#define CFI_type_int_least8_t (CFI_type_Integer + (sizeof (int_least8_t) << CFI_type_kind_shift)) +#define CFI_type_int_least16_t (CFI_type_Integer + (sizeof (int_least16_t) << CFI_type_kind_shift)) +#define CFI_type_int_least32_t (CFI_type_Integer + (sizeof (int_least32_t) << CFI_type_kind_shift)) +#define CFI_type_int_least64_t (CFI_type_Integer + (sizeof (int_least64_t) << CFI_type_kind_shift)) +#define CFI_type_int_fast8_t (CFI_type_Integer + (sizeof (int_fast8_t) << CFI_type_kind_shift)) +#define CFI_type_int_fast16_t (CFI_type_Integer + (sizeof (int_fast16_t) << CFI_type_kind_shift)) +#define CFI_type_int_fast32_t (CFI_type_Integer + (sizeof (int_fast32_t) << CFI_type_kind_shift)) +#define CFI_type_int_fast64_t (CFI_type_Integer + (sizeof (int_fast64_t) << CFI_type_kind_shift)) +#define CFI_type_intmax_t (CFI_type_Integer + (sizeof (intmax_t) << CFI_type_kind_shift)) +#define CFI_type_intptr_t (CFI_type_Integer + (sizeof (intptr_t) << CFI_type_kind_shift)) +#define CFI_type_ptrdiff_t (CFI_type_Integer + (sizeof (ptrdiff_t) << CFI_type_kind_shift)) +#define CFI_type_Bool (CFI_type_Logical + (sizeof (_Bool) << CFI_type_kind_shift)) +#define CFI_type_float (CFI_type_Real + (sizeof (float) << CFI_type_kind_shift)) +#define CFI_type_double (CFI_type_Real + (sizeof (double) << CFI_type_kind_shift)) +#define CFI_type_float_Complex (CFI_type_Complex + (sizeof (float) << CFI_type_kind_shift)) +#define CFI_type_double_Complex (CFI_type_Complex + (sizeof (double) << CFI_type_kind_shift)) diff --git a/libgfortran/ISO_Fortran_binding-2-tmpl.h b/libgfortran/ISO_Fortran_binding-2-tmpl.h new file mode 100644 index 0000000..ad88f8b --- /dev/null +++ b/libgfortran/ISO_Fortran_binding-2-tmpl.h @@ -0,0 +1,42 @@ +#include "config.h" +#include "kinds.inc" + +/* Note that -1 is used by CFI_type_other, hence, -2 is used for unavailable kinds. */ + +#if GFC_C_INT128_T_KIND == 16 +#define CFI_type_int128_t (CFI_type_Integer + (16 << CFI_type_kind_shift)) +#define CFI_type_int_least128_t (CFI_type_Integer + (16 << CFI_type_kind_shift)) +#define CFI_type_int_fast128_t (CFI_type_Integer + (16 << CFI_type_kind_shift)) +#elif GFC_C_INT128_T_KIND < 0 +#define CFI_type_int128_t -2 +#define CFI_type_int_least128_t -2 +#define CFI_type_int_fast128_t -2 +#else +#error "Unexpected value for GFC_C_INT128_T_KIND" +#endif + +#if GFC_C_LONG_DOUBLE_KIND == 16 +#define CFI_type_long_double (CFI_type_Real + (16 << CFI_type_kind_shift)) +#define CFI_type_long_double_Complex (CFI_type_Complex + (16 << CFI_type_kind_shift)) +#elif GFC_C_LONG_DOUBLE_KIND == 10 +#define CFI_type_long_double (CFI_type_Real + (10 << CFI_type_kind_shift)) +#define CFI_type_long_double_Complex (CFI_type_Complex + (10 << CFI_type_kind_shift)) +#elif GFC_C_LONG_DOUBLE_KIND == 8 +#define CFI_type_long_double (CFI_type_Real + (8 << CFI_type_kind_shift)) +#define CFI_type_long_double_Complex (CFI_type_Complex + (8 << CFI_type_kind_shift)) +#elif GFC_C_LONG_DOUBLE_KIND < 0 +#define CFI_type_long_double -2 +#define CFI_type_long_double_Complex -2 +#else +#error "Unexpected value for GFC_C_LONG_DOUBLE_KIND" +#endif + +#if GFC_C_FLOAT128_KIND == 16 +#define CFI_type_float128 (CFI_type_Real + (16 << CFI_type_kind_shift)) +#define CFI_type_float128_Complex (CFI_type_Complex + (16 << CFI_type_kind_shift)) +#elif GFC_C_FLOAT128_KIND < 0 +#define CFI_type_float128 -2 +#define CFI_type_float128_Complex -2 +#else +#error "Unexpected value for GFC_C_FLOAT128_KIND" +#endif diff --git a/libgfortran/ISO_Fortran_binding-3-tmpl.h b/libgfortran/ISO_Fortran_binding-3-tmpl.h new file mode 100644 index 0000000..aec4288 --- /dev/null +++ b/libgfortran/ISO_Fortran_binding-3-tmpl.h @@ -0,0 +1,5 @@ +#ifdef __cplusplus +} +#endif + +#endif /* ISO_FORTRAN_BINDING_H */ diff --git a/libgfortran/Makefile.am b/libgfortran/Makefile.am index 61bf05d..3546a3f 100644 --- a/libgfortran/Makefile.am +++ b/libgfortran/Makefile.am @@ -30,8 +30,8 @@ version_arg = version_dep = endif -gfor_c_HEADERS = $(srcdir)/ISO_Fortran_binding.h -gfor_cdir = $(libdir)/gcc/$(target_alias)/$(gcc_version)/include +gfor_c_HEADERS = ISO_Fortran_binding.h +gfor_cdir = $(libdir)/gcc/$(target_alias)/$(gcc_version)$(MULTISUBDIR)/include LTLDFLAGS = $(shell $(SHELL) $(top_srcdir)/../libtool-ldflags $(LDFLAGS)) \ $(lt_host_flags) @@ -817,6 +817,7 @@ gfor_built_src= $(i_all_c) $(i_any_c) $(i_count_c) $(i_maxloc0_c) \ $(i_pow_c) $(i_pack_c) $(i_unpack_c) $(i_matmulavx128_c) \ $(i_spread_c) selected_int_kind.inc selected_real_kind.inc kinds.h \ $(i_cshift0_c) kinds.inc c99_protos.inc fpu-target.h fpu-target.inc \ + ISO_Fortran_binding.h \ $(i_cshift1a_c) $(i_maxloc0s_c) $(i_minloc0s_c) $(i_maxloc1s_c) \ $(i_minloc1s_c) $(i_maxloc2s_c) $(i_minloc2s_c) $(i_maxvals_c) \ $(i_maxval0s_c) $(i_minval0s_c) $(i_maxval1s_c) $(i_minval1s_c) \ @@ -1075,6 +1076,16 @@ fpu-target.inc: fpu-target.h $(srcdir)/libgfortran.h grep '^#define GFC_FPE_' < $(top_srcdir)/../gcc/fortran/libgfortran.h > $@ || true grep '^#define GFC_FPE_' < $(srcdir)/libgfortran.h >> $@ || true +ISO_Fortran_binding.h: $(srcdir)/ISO_Fortran_binding-1-tmpl.h \ + $(srcdir)/ISO_Fortran_binding-2-tmpl.h \ + $(srcdir)/ISO_Fortran_binding-3-tmpl.h \ + kinds.inc + -rm -f $@ + cp $(srcdir)/ISO_Fortran_binding-1-tmpl.h $@ + $(COMPILE) -E -dD $(srcdir)/ISO_Fortran_binding-2-tmpl.h \ + | grep '^#define CFI_type' >> $@ + cat $(srcdir)/ISO_Fortran_binding-3-tmpl.h >> $@ + ## A 'normal' build shouldn't need to regenerate these ## so we only include them in maintainer mode diff --git a/libgfortran/Makefile.in b/libgfortran/Makefile.in index 3d043aa..a7d8e11 100644 --- a/libgfortran/Makefile.in +++ b/libgfortran/Makefile.in @@ -698,6 +698,7 @@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ @@ -723,8 +724,8 @@ gcc_version := $(shell @get_gcc_base_ver@ $(top_srcdir)/../gcc/BASE-VER) @LIBGFOR_USE_SYMVER_FALSE@version_dep = @LIBGFOR_USE_SYMVER_GNU_TRUE@@LIBGFOR_USE_SYMVER_TRUE@version_dep = $(srcdir)/gfortran.map @LIBGFOR_USE_SYMVER_SUN_TRUE@@LIBGFOR_USE_SYMVER_TRUE@version_dep = gfortran.map-sun -gfor_c_HEADERS = $(srcdir)/ISO_Fortran_binding.h -gfor_cdir = $(libdir)/gcc/$(target_alias)/$(gcc_version)/include +gfor_c_HEADERS = ISO_Fortran_binding.h +gfor_cdir = $(libdir)/gcc/$(target_alias)/$(gcc_version)$(MULTISUBDIR)/include LTLDFLAGS = $(shell $(SHELL) $(top_srcdir)/../libtool-ldflags $(LDFLAGS)) \ $(lt_host_flags) @@ -1381,6 +1382,7 @@ gfor_built_src = $(i_all_c) $(i_any_c) $(i_count_c) $(i_maxloc0_c) \ $(i_pow_c) $(i_pack_c) $(i_unpack_c) $(i_matmulavx128_c) \ $(i_spread_c) selected_int_kind.inc selected_real_kind.inc kinds.h \ $(i_cshift0_c) kinds.inc c99_protos.inc fpu-target.h fpu-target.inc \ + ISO_Fortran_binding.h \ $(i_cshift1a_c) $(i_maxloc0s_c) $(i_minloc0s_c) $(i_maxloc1s_c) \ $(i_minloc1s_c) $(i_maxloc2s_c) $(i_minloc2s_c) $(i_maxvals_c) \ $(i_maxval0s_c) $(i_minval0s_c) $(i_maxval1s_c) $(i_minval1s_c) \ @@ -7040,6 +7042,16 @@ fpu-target.inc: fpu-target.h $(srcdir)/libgfortran.h grep '^#define GFC_FPE_' < $(top_srcdir)/../gcc/fortran/libgfortran.h > $@ || true grep '^#define GFC_FPE_' < $(srcdir)/libgfortran.h >> $@ || true +ISO_Fortran_binding.h: $(srcdir)/ISO_Fortran_binding-1-tmpl.h \ + $(srcdir)/ISO_Fortran_binding-2-tmpl.h \ + $(srcdir)/ISO_Fortran_binding-3-tmpl.h \ + kinds.inc + -rm -f $@ + cp $(srcdir)/ISO_Fortran_binding-1-tmpl.h $@ + $(COMPILE) -E -dD $(srcdir)/ISO_Fortran_binding-2-tmpl.h \ + | grep '^#define CFI_type' >> $@ + cat $(srcdir)/ISO_Fortran_binding-3-tmpl.h >> $@ + @MAINTAINER_MODE_TRUE@$(i_all_c): m4/all.m4 $(I_M4_DEPS2) @MAINTAINER_MODE_TRUE@ $(M4) -Dfile=$@ -I$(srcdir)/m4 all.m4 > $@ diff --git a/libgfortran/mk-kinds-h.sh b/libgfortran/mk-kinds-h.sh index 2496190..f4244f0 100755 --- a/libgfortran/mk-kinds-h.sh +++ b/libgfortran/mk-kinds-h.sh @@ -35,8 +35,8 @@ for k in $possible_integer_kinds; do echo "typedef ${prefix}int${s}_t GFC_INTEGER_${k};" echo "typedef ${prefix}uint${s}_t GFC_UINTEGER_${k};" echo "typedef GFC_INTEGER_${k} GFC_LOGICAL_${k};" - echo "#define HAVE_GFC_LOGICAL_${k}" - echo "#define HAVE_GFC_INTEGER_${k}" + echo "#define HAVE_GFC_LOGICAL_${k} 1" + echo "#define HAVE_GFC_INTEGER_${k} 1" echo "" fi rm -f tmp$$.* @@ -98,8 +98,8 @@ for k in $possible_real_kinds; do # Output the information we've gathered echo "typedef ${ctype} GFC_REAL_${k};" echo "typedef ${cplxtype} GFC_COMPLEX_${k};" - echo "#define HAVE_GFC_REAL_${k}" - echo "#define HAVE_GFC_COMPLEX_${k}" + echo "#define HAVE_GFC_REAL_${k} 1" + echo "#define HAVE_GFC_COMPLEX_${k} 1" echo "#define GFC_REAL_${k}_HUGE ${huge}${suffix}" echo "#define GFC_REAL_${k}_LITERAL_SUFFIX ${suffix}" if [ "x$suffix" = "x" ]; then @@ -114,6 +114,23 @@ for k in $possible_real_kinds; do rm -f tmp$$.* done +# For ISO_Fortran_binding.h +for k in "C_LONG_DOUBLE" "C_FLOAT128" "C_INT128_T"; do + fname="tmp$$.val" + echo "use iso_c_binding, only: $k; end" > tmp$$.f90 + if $compile -S -fdump-parse-tree tmp$$.f90 > "$fname"; then + kind=`grep "value:" "$fname" |grep value: | sed -e 's/.*value: *//'` + if [ "x$kind" = "x" ]; then + echo "ERROR: Failed to extract kind for $k" 1>&2 + exit 1 + fi + echo "#define GFC_${k}_KIND ${kind}" + else + echo "ERROR: Failed to extract kind for $k" 1>&2 + exit 1 + fi + rm -f tmp$$.* +done # After this, we include a header that can override some of the # autodetected settings. diff --git a/libgfortran/runtime/ISO_Fortran_binding.c b/libgfortran/runtime/ISO_Fortran_binding.c index 95e9b94..9c871d3 100644 --- a/libgfortran/runtime/ISO_Fortran_binding.c +++ b/libgfortran/runtime/ISO_Fortran_binding.c @@ -27,7 +27,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see . */ #include "libgfortran.h" -#include +#include "ISO_Fortran_binding.h" #include extern void cfi_desc_to_gfc_desc (gfc_array_void *, CFI_cdesc_t **); -- 2.7.4