diff mbox series

float.h: C2x *_IS_IEC_60559 macros

Message ID alpine.DEB.2.22.394.2011132030560.141297@digraph.polyomino.org.uk
State New
Headers show
Series float.h: C2x *_IS_IEC_60559 macros | expand

Commit Message

Joseph Myers Nov. 13, 2020, 8:31 p.m. UTC
C2x adds float.h macros that say whether float, double and long double
match an IEC 60559 (IEEE 754) format and operations.  Add these
macros to GCC's float.h.

Bootstrapped with no regressions for x86_64-pc-linux-gnu.  OK to commit?

Although this changes the same part of float.h as
<https://gcc.gnu.org/pipermail/gcc-patches/2020-October/557136.html>
(pending review), there are no actual dependencies between the
patches; new tests are named to avoid conflicts with the tests added
in that patch.

gcc/c-family/
2020-11-13  Joseph Myers  <joseph@codesourcery.com>

	* c-cppbuiltin.c (builtin_define_float_constants): Define
	*_IS_IEC_60559__ macros.

gcc/
2020-11-13  Joseph Myers  <joseph@codesourcery.com>

	* ginclude/float.h [__STDC_VERSION__ > 201710L] (FLT_IS_IEC_60559,
	DBL_IS_IEC_60559, LDBL_IS_IEC_60559): New macros.

gcc/testsuite/
2020-11-13  Joseph Myers  <joseph@codesourcery.com>

	* gcc.dg/c11-float-6.c, gcc.dg/c2x-float-10.c: New tests.
diff mbox series

Patch

diff --git a/gcc/c-family/c-cppbuiltin.c b/gcc/c-family/c-cppbuiltin.c
index e5ebb79e22a..5a839d7fa6f 100644
--- a/gcc/c-family/c-cppbuiltin.c
+++ b/gcc/c-family/c-cppbuiltin.c
@@ -316,6 +316,16 @@  builtin_define_float_constants (const char *name_prefix,
       sprintf (name, "__FP_FAST_FMA%s", fma_suffix);
       builtin_define_with_int_value (name, 1);
     }
+
+  /* For C2x *_IS_IEC_60559.  0 means the type does not match an IEC
+     60559 format, 1 that it matches a format but not operations and 2
+     that it matches a format and operations (but may not conform to
+     Annex F; we take this as meaning exceptions and rounding modes
+     need not be supported).  */
+  sprintf (name, "__%s_IS_IEC_60559__", name_prefix);
+  builtin_define_with_int_value (name,
+				 (fmt->ieee_bits == 0
+				  ? 0 : (fmt->round_towards_zero ? 1 : 2)));
 }
 
 /* Define __DECx__ constants for TYPE using NAME_PREFIX and SUFFIX. */
diff --git a/gcc/ginclude/float.h b/gcc/ginclude/float.h
index 9c4b0385568..70149564ff1 100644
--- a/gcc/ginclude/float.h
+++ b/gcc/ginclude/float.h
@@ -248,6 +248,15 @@  see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 #define DBL_NORM_MAX	__DBL_NORM_MAX__
 #define LDBL_NORM_MAX	__LDBL_NORM_MAX__
 
+/* Whether each type matches an IEC 60559 format (1 for format, 2 for
+   format and operations).  */
+#undef FLT_IS_IEC_60559
+#undef DBL_IS_IEC_60559
+#undef LDBL_IS_IEC_60559
+#define FLT_IS_IEC_60559	__FLT_IS_IEC_60559__
+#define DBL_IS_IEC_60559	__DBL_IS_IEC_60559__
+#define LDBL_IS_IEC_60559	__LDBL_IS_IEC_60559__
+
 #endif /* C2X */
 
 #ifdef __STDC_WANT_IEC_60559_BFP_EXT__
diff --git a/gcc/testsuite/gcc.dg/c11-float-6.c b/gcc/testsuite/gcc.dg/c11-float-6.c
new file mode 100644
index 00000000000..b0381e57884
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c11-float-6.c
@@ -0,0 +1,17 @@ 
+/* Test *_IS_IEC_60559 not defined for C11.  */
+/* { dg-do preprocess } */
+/* { dg-options "-std=c11 -pedantic-errors" } */
+
+#include <float.h>
+
+#ifdef FLT_IS_IEC_60559
+#error "FLT_IS_IEC_60559 defined"
+#endif
+
+#ifdef DBL_IS_IEC_60559
+#error "DBL_IS_IEC_60559 defined"
+#endif
+
+#ifdef LDBL_IS_IEC_60559
+#error "LDBL_IS_IEC_60559 defined"
+#endif
diff --git a/gcc/testsuite/gcc.dg/c2x-float-10.c b/gcc/testsuite/gcc.dg/c2x-float-10.c
new file mode 100644
index 00000000000..7b53a6ab050
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c2x-float-10.c
@@ -0,0 +1,33 @@ 
+/* Test *_IS_IEC_60559 macros.  */
+/* { dg-do compile } */
+/* { dg-options "-std=c2x -pedantic-errors" } */
+
+#include <float.h>
+
+#ifndef FLT_IS_IEC_60559
+#error "FLT_IS_IEC_60559 undefined"
+#endif
+
+#ifndef DBL_IS_IEC_60559
+#error "DBL_IS_IEC_60559 undefined"
+#endif
+
+#ifndef LDBL_IS_IEC_60559
+#error "LDBL_IS_IEC_60559 undefined"
+#endif
+
+#if defined __pdp11__ || defined __vax__
+_Static_assert (FLT_IS_IEC_60559 == 0);
+_Static_assert (DBL_IS_IEC_60559 == 0);
+_Static_assert (LDBL_IS_IEC_60559 == 0);
+#else
+_Static_assert (FLT_IS_IEC_60559 == 2);
+_Static_assert (DBL_IS_IEC_60559 == 2);
+#if LDBL_MANT_DIG == 106 || LDBL_MIN_EXP == -16382
+/* IBM long double and m68k extended format do not meet the definition
+   of an IEC 60559 interchange or extended format.  */
+_Static_assert (LDBL_IS_IEC_60559 == 0);
+#else
+_Static_assert (LDBL_IS_IEC_60559 == 2);
+#endif
+#endif