[clang] [C23] Add INFINITY and NAN macros to <float.h> (PR #96659)

Aaron Ballman via cfe-commits cfe-commits at lists.llvm.org
Mon Jul 1 05:45:26 PDT 2024


https://github.com/AaronBallman updated https://github.com/llvm/llvm-project/pull/96659

>From b59c7f8c91d7c128975554d90bef3657ce3b2728 Mon Sep 17 00:00:00 2001
From: Aaron Ballman <aaron at aaronballman.com>
Date: Tue, 25 Jun 2024 10:52:56 -0400
Subject: [PATCH 1/3] [C23] Add INFINITY and NAN macros to <float.h>

This is in support of WG14 N2848 which only define the macros if
infinity and nan are supported, so use of -ffinite-math will cause the
macros to not be defined.
---
 clang/docs/ReleaseNotes.rst |  5 +++++
 clang/lib/Headers/float.h   |  6 ++++++
 clang/test/Headers/float.c  | 29 +++++++++++++++++++++++++++++
 3 files changed, 40 insertions(+)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index df579ae398c5e..45c9a2cc47b09 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -336,6 +336,11 @@ C23 Feature Support
 - Properly promote bit-fields of bit-precise integer types to the field's type
   rather than to ``int``. #GH87641
 
+- Added the ``INFINITY`` and ``NAN`` macros to Clang's ``<float.h>``
+  freestanding implementation; these macros were defined in C99 but Clang
+  implements the macros as described by C23 in
+  `WG14 N2848 <https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2848.pdf>`_.
+
 Non-comprehensive list of changes in this release
 -------------------------------------------------
 
diff --git a/clang/lib/Headers/float.h b/clang/lib/Headers/float.h
index 642c8f06cc938..929c0854a865b 100644
--- a/clang/lib/Headers/float.h
+++ b/clang/lib/Headers/float.h
@@ -47,6 +47,8 @@
     (defined(__cplusplus) && __cplusplus >= 201103L) ||                        \
     (__STDC_HOSTED__ && defined(_AIX) && defined(_ALL_SOURCE))
 #    undef DECIMAL_DIG
+#    undef INFINITY
+#    undef NAN
 #  endif
 #  undef FLT_DIG
 #  undef DBL_DIG
@@ -93,6 +95,10 @@
 #if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) ||              \
     (defined(__cplusplus) && __cplusplus >= 201103L)
 #define FLT_EVAL_METHOD __FLT_EVAL_METHOD__
+#if defined(__FINITE_MATH_ONLY__) && !__FINITE_MATH_ONLY__
+#  define INFINITY (__builtin_infinity())
+#  define NAN (__builtin_nan(""))
+#endif
 #endif
 #define FLT_ROUNDS (__builtin_flt_rounds())
 #define FLT_RADIX __FLT_RADIX__
diff --git a/clang/test/Headers/float.c b/clang/test/Headers/float.c
index 70c11b0537537..8dfbc32521ade 100644
--- a/clang/test/Headers/float.c
+++ b/clang/test/Headers/float.c
@@ -1,9 +1,13 @@
 // RUN: %clang_cc1 -fsyntax-only -verify -std=c89 -ffreestanding %s
 // RUN: %clang_cc1 -fsyntax-only -verify -std=c99 -ffreestanding %s
 // RUN: %clang_cc1 -fsyntax-only -verify -std=c11 -ffreestanding %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c23 -ffreestanding %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c23 -ffreestanding -ffinite-math-only %s
 // RUN: %clang_cc1 -fsyntax-only -verify -xc++ -std=c++11 -ffreestanding %s
 // RUN: %clang_cc1 -fsyntax-only -verify -xc++ -std=c++14 -ffreestanding %s
 // RUN: %clang_cc1 -fsyntax-only -verify -xc++ -std=c++17 -ffreestanding %s
+// RUN: %clang_cc1 -fsyntax-only -verify -xc++ -std=c++23 -ffreestanding %s
+// RUN: %clang_cc1 -fsyntax-only -verify -xc++ -std=c++23 -ffreestanding -ffinite-math-only %s
 // expected-no-diagnostics
 
 /* Basic floating point conformance checks against:
@@ -107,10 +111,35 @@
     #elif   DECIMAL_DIG < 10
         #error "Mandatory macro DECIMAL_DIG is invalid."
     #endif
+
+    #if __FINITE_MATH_ONLY__ == 0
+        #ifndef INFINITY
+            #error "Mandatory macro INFINITY is missing."
+        #endif
+        #ifndef NAN
+            #error "Mandatory macro NAN is missing."
+        #endif
+    #else
+        #ifdef INFINITY
+            #error "Macro INFINITY should not be defined."
+        #endif
+
+        #ifdef NAN
+            #error "Macro NAN should not be defined."
+        #endif
+    #endif
 #else
     #ifdef DECIMAL_DIG
         #error "Macro DECIMAL_DIG should not be defined."
     #endif
+
+    #ifdef INFINITY
+        #error "Macro INFINITY should not be defined."
+    #endif
+
+    #ifdef NAN
+        #error "Macro NAN should not be defined."
+    #endif
 #endif
 
 

>From 86055e3ecb25befdffdf17f2a1eb8b9c704a1e7a Mon Sep 17 00:00:00 2001
From: Aaron Ballman <aaron at aaronballman.com>
Date: Tue, 25 Jun 2024 10:55:03 -0400
Subject: [PATCH 2/3] Update the status page

---
 clang/www/c_status.html | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/www/c_status.html b/clang/www/c_status.html
index 04c1df9ebc050..bc37f8cd5e404 100644
--- a/clang/www/c_status.html
+++ b/clang/www/c_status.html
@@ -991,7 +991,7 @@ <h2 id="c2x">C23 implementation status</h2>
     <tr>
       <td>Contradiction about INFINITY macro</td>
       <td><a href="https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2848.pdf">N2848</a></td>
-      <td class="unknown" align="center">Unknown</td>
+      <td class="unreleased" align="center">Clang 19</td>
     </tr>
     <tr>
       <td>Require exact-width integer type interfaces</td>

>From 88019c9964068a43f96f1ab13b75fb6e60238470 Mon Sep 17 00:00:00 2001
From: Aaron Ballman <aaron at aaronballman.com>
Date: Fri, 28 Jun 2024 08:31:45 -0400
Subject: [PATCH 3/3] Update based on review feedback

* Now defines the macros even in -ffinite-math-only mode
* Defines the macros only in C23 and up, not in C99 and up
* Fixed the test coverage, added tests for use in a constant expression
* Fixed the expansion of the INFINITY macro (should resolve a precommit CI issue)
---
 clang/docs/ReleaseNotes.rst |  4 ++--
 clang/lib/Headers/float.h   | 11 +++++----
 clang/test/Headers/float.c  | 46 +++++++++++++++++--------------------
 3 files changed, 30 insertions(+), 31 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 8fcd175a3f123..9c7268cbe25b6 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -338,8 +338,8 @@ C23 Feature Support
   rather than to ``int``. #GH87641
 
 - Added the ``INFINITY`` and ``NAN`` macros to Clang's ``<float.h>``
-  freestanding implementation; these macros were defined in C99 but Clang
-  implements the macros as described by C23 in
+  freestanding implementation; these macros were defined in ``<math.h>`` in C99
+  but C23 added them to ``<float.h>`` in
   `WG14 N2848 <https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2848.pdf>`_.
 
 Non-comprehensive list of changes in this release
diff --git a/clang/lib/Headers/float.h b/clang/lib/Headers/float.h
index 929c0854a865b..a0cfeb12862f7 100644
--- a/clang/lib/Headers/float.h
+++ b/clang/lib/Headers/float.h
@@ -95,10 +95,6 @@
 #if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) ||              \
     (defined(__cplusplus) && __cplusplus >= 201103L)
 #define FLT_EVAL_METHOD __FLT_EVAL_METHOD__
-#if defined(__FINITE_MATH_ONLY__) && !__FINITE_MATH_ONLY__
-#  define INFINITY (__builtin_infinity())
-#  define NAN (__builtin_nan(""))
-#endif
 #endif
 #define FLT_ROUNDS (__builtin_flt_rounds())
 #define FLT_RADIX __FLT_RADIX__
@@ -161,6 +157,13 @@
 #  define LDBL_HAS_SUBNORM __LDBL_HAS_DENORM__
 #endif
 
+#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L) ||              \
+    !defined(__STRICT_ANSI__)
+   /* C23 5.2.5.3.3p29-30 */
+#  define INFINITY (__builtin_inf())
+#  define NAN (__builtin_nan(""))
+#endif
+
 #ifdef __STDC_WANT_IEC_60559_TYPES_EXT__
 #  define FLT16_MANT_DIG    __FLT16_MANT_DIG__
 #  define FLT16_DECIMAL_DIG __FLT16_DECIMAL_DIG__
diff --git a/clang/test/Headers/float.c b/clang/test/Headers/float.c
index 8dfbc32521ade..b9e6e971545e5 100644
--- a/clang/test/Headers/float.c
+++ b/clang/test/Headers/float.c
@@ -111,35 +111,10 @@
     #elif   DECIMAL_DIG < 10
         #error "Mandatory macro DECIMAL_DIG is invalid."
     #endif
-
-    #if __FINITE_MATH_ONLY__ == 0
-        #ifndef INFINITY
-            #error "Mandatory macro INFINITY is missing."
-        #endif
-        #ifndef NAN
-            #error "Mandatory macro NAN is missing."
-        #endif
-    #else
-        #ifdef INFINITY
-            #error "Macro INFINITY should not be defined."
-        #endif
-
-        #ifdef NAN
-            #error "Macro NAN should not be defined."
-        #endif
-    #endif
 #else
     #ifdef DECIMAL_DIG
         #error "Macro DECIMAL_DIG should not be defined."
     #endif
-
-    #ifdef INFINITY
-        #error "Macro INFINITY should not be defined."
-    #endif
-
-    #ifdef NAN
-        #error "Macro NAN should not be defined."
-    #endif
 #endif
 
 
@@ -236,6 +211,21 @@
     #error "Mandatory macros {FLT,DBL,LDBL}_MAX_10_EXP are invalid."
 #endif
 
+#if __STDC_VERSION__ >= 202311L || !defined(__STRICT_ANSI__)
+  #ifndef INFINITY
+    #error "Mandatory macro INFINITY is missing."
+  #endif
+  #ifndef NAN
+    #error "Mandatory macro NAN is missing."
+  #endif
+#else
+  #ifdef INFINITY
+    #error "Macro INFINITY should not be defined."
+  #endif
+  #ifdef NAN
+    #error "Macro NAN should not be defined."
+  #endif
+#endif
 
 /* Internal consistency checks */
 _Static_assert(FLT_RADIX == __FLT_RADIX__, "");
@@ -273,3 +263,9 @@ _Static_assert(LDBL_MAX_EXP == __LDBL_MAX_EXP__, "");
 _Static_assert(FLT_MAX_10_EXP == __FLT_MAX_10_EXP__, "");
 _Static_assert(DBL_MAX_10_EXP == __DBL_MAX_10_EXP__, "");
 _Static_assert(LDBL_MAX_10_EXP == __LDBL_MAX_10_EXP__, "");
+
+#if (__STDC_VERSION__ >= 202311L || !defined(__STRICT_ANSI__)) && __FINITE_MATH_ONLY__ == 0
+// Ensure INFINITY and NAN are suitable for use in a constant expression.
+float f1 = INFINITY;
+float f2 = NAN;
+#endif



More information about the cfe-commits mailing list