On 9/13/21 11:07 AM, Tobias Burnus wrote:
On 13.09.21 18:59, Sandra Loosemore wrote:
On 9/13/21 10:51 AM, Jakub Jelinek wrote: >>> Wouldn't it be better to use the 
__LDBL_* macros anyway and not rely on
float.h?  The header doesn't want to test what float.h tells about the
long double type, but what the compiler knows about it.
I originally wrote the code to use the internal GCC __LDBL_* macros as you suggest, but Tobias complained that then the gfortran-provided .h file could not be used to compile the C parts of the program with some other C compiler.
For instance, clang does not seem to provide those - and in some cases, it can be useful to mix gfortran code with code complied by other compilers (icc, clang, ...).
Maybe it needs to first check the internal macros and then look for the float.h versions if it can't find them?

I think that makes sense. (Adding a comment that #include <float.h> is for non-GCC compilers, only.)

Here's a patch. Gerald, can you check that this fixes your bootstrap problem on i586-unknown-freebsd11?

-Sandra
commit b8b19bca743ed678ef1b59f1a363c7fa7d155c43
Author: Sandra Loosemore <san...@codesourcery.com>
Date:   Mon Sep 13 19:48:16 2021 -0700

    Fortran: Prefer GCC internal macros to float.h in ISO_Fortran_binding.h.
    
    2021-09-13  Sandra Loosemore  <san...@codesourcery.com>
    
    	libgfortran/
    	* ISO_Fortran_binding.h: Only include float.h if the C compiler
    	doesn't have predefined __LDBL_* and __DBL_* macros.

diff --git a/libgfortran/ISO_Fortran_binding.h b/libgfortran/ISO_Fortran_binding.h
index 9c42464..a3c6f80 100644
--- a/libgfortran/ISO_Fortran_binding.h
+++ b/libgfortran/ISO_Fortran_binding.h
@@ -32,7 +32,6 @@ extern "C" {
 
 #include <stddef.h>  /* Standard ptrdiff_t tand size_t. */
 #include <stdint.h>  /* Integer types. */
-#include <float.h>  /* Macros for floating-point type characteristics.  */
 
 /* Constants, defined as macros. */
 #define CFI_VERSION 1
@@ -217,40 +216,82 @@ extern int CFI_setpointer (CFI_cdesc_t *, CFI_cdesc_t *, const CFI_index_t []);
 #endif
 
 /* The situation with long double support is more complicated; we need to
-   examine the type in more detail to figure out its kind.  */
+   examine the type in more detail to figure out its kind.
+   GCC and some other compilers predefine the __LDBL* macros; otherwise
+   get the parameters we need from float.h.  */
+
+#if (defined (__LDBL_MANT_DIG__) \
+     && defined (__LDBL_MIN_EXP__) \
+     && defined (__LDBL_MAX_EXP__) \
+     && defined (__DBL_MANT_DIG__) \
+     && defined (__DBL_MIN_EXP__) \
+     && defined (__DBL_MAX_EXP__))
+#define __CFI_LDBL_MANT_DIG__ __LDBL_MANT_DIG__
+#define __CFI_LDBL_MIN_EXP__ __LDBL_MIN_EXP__
+#define __CFI_LDBL_MAX_EXP__ __LDBL_MAX_EXP__
+#define __CFI_DBL_MANT_DIG__ __DBL_MANT_DIG__
+#define __CFI_DBL_MIN_EXP__ __DBL_MIN_EXP__
+#define __CFI_DBL_MAX_EXP__ __DBL_MAX_EXP__
+
+#else
+#include <float.h>
+
+#if (defined (LDBL_MANT_DIG) \
+     && defined (LDBL_MIN_EXP) \
+     && defined (LDBL_MAX_EXP) \
+     && defined (DBL_MANT_DIG) \
+     && defined (DBL_MIN_EXP) \
+     && defined (DBL_MAX_EXP))
+#define __CFI_LDBL_MANT_DIG__ LDBL_MANT_DIG
+#define __CFI_LDBL_MIN_EXP__ LDBL_MIN_EXP
+#define __CFI_LDBL_MAX_EXP__ LDBL_MAX_EXP
+#define __CFI_DBL_MANT_DIG__ DBL_MANT_DIG
+#define __CFI_DBL_MIN_EXP__ DBL_MIN_EXP
+#define __CFI_DBL_MAX_EXP__ DBL_MAX_EXP
+
+#else
+#define CFI_no_long_double 1
+
+#endif  /* Definitions from float.h.  */
+#endif  /* Definitions from compiler builtins.  */
+
+/* Can't determine anything about long double support?  */
+#if (defined (CFI_no_long_double))
+#define CFI_type_long_double -2
+#define CFI_type_long_double_Complex -2
 
 /* Long double is the same kind as double.  */
-#if (LDBL_MANT_DIG == DBL_MANT_DIG \
-     && LDBL_MIN_EXP == DBL_MIN_EXP \
-     && LDBL_MAX_EXP == DBL_MAX_EXP)
+#elif (__CFI_LDBL_MANT_DIG__ == __CFI_DBL_MANT_DIG__ \
+     && __CFI_LDBL_MIN_EXP__ == __CFI_DBL_MIN_EXP__ \
+     && __CFI_LDBL_MAX_EXP__ == __CFI_DBL_MAX_EXP__)
 #define CFI_type_long_double CFI_type_double
 #define CFI_type_long_double_Complex CFI_type_double_Complex
 
 /* This is the 80-bit encoding on x86; Fortran assigns it kind 10.  */
-#elif (LDBL_MANT_DIG == 64 \
-       && LDBL_MIN_EXP == -16381 \
-       && LDBL_MAX_EXP == 16384)
+#elif (__CFI_LDBL_MANT_DIG__ == 64 \
+       && __CFI_LDBL_MIN_EXP__ == -16381 \
+       && __CFI_LDBL_MAX_EXP__ == 16384)
 #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))
 
 /* This is the 96-bit encoding on m68k; Fortran assigns it kind 10.  */
-#elif (LDBL_MANT_DIG == 64 \
-       && LDBL_MIN_EXP == -16382 \
-       && LDBL_MAX_EXP == 16384)
+#elif (__CFI_LDBL_MANT_DIG__ == 64 \
+       && __CFI_LDBL_MIN_EXP__ == -16382 \
+       && __CFI_LDBL_MAX_EXP__ == 16384)
 #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))
 
 /* This is the IEEE 128-bit encoding, same as float128.  */
-#elif (LDBL_MANT_DIG == 113 \
-       && LDBL_MIN_EXP == -16381 \
-       && LDBL_MAX_EXP == 16384)
+#elif (__CFI_LDBL_MANT_DIG__ == 113 \
+       && __CFI_LDBL_MIN_EXP__ == -16381 \
+       && __CFI_LDBL_MAX_EXP__ == 16384)
 #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))
 
 /* This is the IBM128 encoding used on PowerPC; also assigned kind 16.  */
-#elif (LDBL_MANT_DIG == 106 \
-       && LDBL_MIN_EXP == -968 \
-       && LDBL_MAX_EXP == 1024)
+#elif (__CFI_LDBL_MANT_DIG__ == 106 \
+       && __CFI_LDBL_MIN_EXP__ == -968 \
+       && __CFI_LDBL_MAX_EXP__ == 1024)
 #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))
 #define CFI_no_float128 1

Reply via email to