[clang] [C23] Add *_NORM_MAX macros to <float.h> (PR #96643)

Aaron Ballman via cfe-commits cfe-commits at lists.llvm.org
Wed Jun 26 05:21:07 PDT 2024


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

>From 408c34b84966a256bb6e7fdf45758f5c77380bbe Mon Sep 17 00:00:00 2001
From: Aaron Ballman <aaron at aaronballman.com>
Date: Tue, 25 Jun 2024 10:27:10 -0400
Subject: [PATCH 1/4] [C23] Add *_NORM_MAX macros to <float.h>

This adds the *_NORM_MAX macros to <float.h> for freestanding mode in
Clang; the values were chosen based on the behavior seen coming from
GCC and the values already produced for the *_MAX macros by Clang.
---
 clang/docs/ReleaseNotes.rst             |  3 +++
 clang/lib/Frontend/InitPreprocessor.cpp |  7 ++++++-
 clang/lib/Headers/float.h               | 13 ++++++++++++
 clang/test/Headers/float.c              | 27 +++++++++++++++++++++++++
 4 files changed, 49 insertions(+), 1 deletion(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index df579ae398c5e..8879a77ba4dd9 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -336,6 +336,9 @@ C23 Feature Support
 - Properly promote bit-fields of bit-precise integer types to the field's type
   rather than to ``int``. #GH87641
 
+- Added the ``FLT_NORM_MAX``, ``DBL_NORM_MAX``, and ``LDBL_NORM_MAX`` to the
+  freestanding implementation of ``<float.h>`` that ships with Clang.
+
 Non-comprehensive list of changes in this release
 -------------------------------------------------
 
diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp
index 55ec460064830..afc4c16ab685b 100644
--- a/clang/lib/Frontend/InitPreprocessor.cpp
+++ b/clang/lib/Frontend/InitPreprocessor.cpp
@@ -113,7 +113,11 @@ static T PickFP(const llvm::fltSemantics *Sem, T IEEEHalfVal, T IEEESingleVal,
 
 static void DefineFloatMacros(MacroBuilder &Builder, StringRef Prefix,
                               const llvm::fltSemantics *Sem, StringRef Ext) {
-  const char *DenormMin, *Epsilon, *Max, *Min;
+  const char *DenormMin, *NormMax, *Epsilon, *Max, *Min;
+  NormMax = PickFP(Sem, "6.5504e+4", "3.40282347e+38",
+                   "1.7976931348623157e+308", "1.18973149535723176502e+4932",
+                   "1.79769313486231580793728971405301e+308",
+                   "1.18973149535723176508575932662800702e+4932");
   DenormMin = PickFP(Sem, "5.9604644775390625e-8", "1.40129846e-45",
                      "4.9406564584124654e-324", "3.64519953188247460253e-4951",
                      "4.94065645841246544176568792868221e-324",
@@ -144,6 +148,7 @@ static void DefineFloatMacros(MacroBuilder &Builder, StringRef Prefix,
   DefPrefix += "_";
 
   Builder.defineMacro(DefPrefix + "DENORM_MIN__", Twine(DenormMin)+Ext);
+  Builder.defineMacro(DefPrefix + "NORM_MAX__", Twine(NormMax)+Ext);
   Builder.defineMacro(DefPrefix + "HAS_DENORM__");
   Builder.defineMacro(DefPrefix + "DIG__", Twine(Digits));
   Builder.defineMacro(DefPrefix + "DECIMAL_DIG__", Twine(DecimalDigits));
diff --git a/clang/lib/Headers/float.h b/clang/lib/Headers/float.h
index 642c8f06cc938..61f65dad8debc 100644
--- a/clang/lib/Headers/float.h
+++ b/clang/lib/Headers/float.h
@@ -86,6 +86,12 @@
 #    undef DBL_HAS_SUBNORM
 #    undef LDBL_HAS_SUBNORM
 #  endif
+#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L) ||              \
+    !defined(__STRICT_ANSI__)
+#    undef FLT_NORM_MAX
+#    undef DBL_NORM_MAX
+#    undef LDBL_NORM_MAX
+#endif
 #endif
 
 /* Characteristics of floating point types, C99 5.2.4.2.2 */
@@ -155,6 +161,13 @@
 #  define LDBL_HAS_SUBNORM __LDBL_HAS_DENORM__
 #endif
 
+#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L) ||              \
+    !defined(__STRICT_ANSI__)
+#  define FLT_NORM_MAX __FLT_NORM_MAX__
+#  define DBL_NORM_MAX __DBL_NORM_MAX__
+#  define LDBL_NORM_MAX __LDBL_NORM_MAX__
+#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 70c11b0537537..59cc0faa074db 100644
--- a/clang/test/Headers/float.c
+++ b/clang/test/Headers/float.c
@@ -1,17 +1,21 @@
 // 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 -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
 // expected-no-diagnostics
 
 /* Basic floating point conformance checks against:
+    - C23 Final Std.
     - N1570 draft of C11 Std.
     - N1256 draft of C99 Std.
     - http://port70.net/~nsz/c/c89/c89-draft.html draft of C89/C90 Std.
 */
 /*
+    C23,    5.2.5.3.3p21,   pp. 25
     C11,    5.2.4.2.2p11,   pp. 30
     C99,    5.2.4.2.2p9,    pp. 25
     C89,    2.2.4.2
@@ -207,6 +211,23 @@
     #error "Mandatory macros {FLT,DBL,LDBL}_MAX_10_EXP are invalid."
 #endif
 
+#if __STDC_VERSION__ >= 202311L || !defined(__STRICT_ANSI__)
+#ifndef FLT_NORM_MAX
+  #error "Mandatory macro FLT_NORM_MAX is missing."
+#else
+  _Static_assert(FLT_NORM_MAX >= 1.0E+37F, "Mandatory macro FLT_NORM_MAX is invalid.");
+#endif
+#ifndef DBL_NORM_MAX
+  #error "Mandatory macro DBL_NORM_MAX is missing."
+#else
+  _Static_assert(DBL_NORM_MAX >= 1.0E+37F, "Mandatory macro DBL_NORM_MAX is invalid.");
+#endif
+#ifndef LDBL_NORM_MAX
+  #error "Mandatory macro LDBL_NORM_MAX is missing."
+#else
+  _Static_assert(LDBL_NORM_MAX >= 1.0E+37F, "Mandatory macro LDBL_NORM_MAX is invalid.");
+#endif
+#endif
 
 /* Internal consistency checks */
 _Static_assert(FLT_RADIX == __FLT_RADIX__, "");
@@ -244,3 +265,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__)
+_Static_assert(FLT_NORM_MAX == __FLT_NORM_MAX__, "");
+_Static_assert(DBL_NORM_MAX == __DBL_NORM_MAX__, "");
+_Static_assert(LDBL_NORM_MAX == __LDBL_NORM_MAX__, "");
+#endif

>From 486d9fb3f9f992831569e4b9e1eda0a54c777b3b Mon Sep 17 00:00:00 2001
From: Aaron Ballman <aaron at aaronballman.com>
Date: Tue, 25 Jun 2024 11:09:51 -0400
Subject: [PATCH 2/4] Fix failing test cases

---
 clang/test/Preprocessor/init-aarch64.c | 4 ++++
 clang/test/Preprocessor/init.c         | 4 ++++
 2 files changed, 8 insertions(+)

diff --git a/clang/test/Preprocessor/init-aarch64.c b/clang/test/Preprocessor/init-aarch64.c
index 9e425ac1c5ce2..81c9a66f13751 100644
--- a/clang/test/Preprocessor/init-aarch64.c
+++ b/clang/test/Preprocessor/init-aarch64.c
@@ -74,6 +74,7 @@
 // AARCH64-NEXT: #define __DBL_MIN_10_EXP__ (-307)
 // AARCH64-NEXT: #define __DBL_MIN_EXP__ (-1021)
 // AARCH64-NEXT: #define __DBL_MIN__ 2.2250738585072014e-308
+// AARCH64-NEXT: #define __DBL_NORM_MAX__ 1.7976931348623157e+308
 // AARCH64-NEXT: #define __DECIMAL_DIG__ __LDBL_DECIMAL_DIG__
 // AARCH64-NEXT: #define __ELF__ 1
 // AARCH64-NEXT: #define __FINITE_MATH_ONLY__ 0
@@ -91,6 +92,7 @@
 // AARCH64-NEXT: #define __FLT16_MIN_10_EXP__ (-4)
 // AARCH64-NEXT: #define __FLT16_MIN_EXP__ (-13)
 // AARCH64-NEXT: #define __FLT16_MIN__ 6.103515625e-5F16
+// AARCH64-NEXT: #define __FLT16_NORM_MAX__ 6.5504e+4F16
 // AARCH64-NEXT: #define __FLT_DECIMAL_DIG__ 9
 // AARCH64-NEXT: #define __FLT_DENORM_MIN__ 1.40129846e-45F
 // AARCH64-NEXT: #define __FLT_DIG__ 6
@@ -105,6 +107,7 @@
 // AARCH64-NEXT: #define __FLT_MIN_10_EXP__ (-37)
 // AARCH64-NEXT: #define __FLT_MIN_EXP__ (-125)
 // AARCH64-NEXT: #define __FLT_MIN__ 1.17549435e-38F
+// AARCH64-NEXT: #define __FLT_NORM_MAX__ 3.40282347e+38F
 // AARCH64-NEXT: #define __FLT_RADIX__ 2
 // AARCH64-NEXT: #define __FPCLASS_NEGINF 0x0004
 // AARCH64-NEXT: #define __FPCLASS_NEGNORMAL 0x0008
@@ -216,6 +219,7 @@
 // AARCH64-NEXT: #define __LDBL_MIN_10_EXP__ (-4931)
 // AARCH64-NEXT: #define __LDBL_MIN_EXP__ (-16381)
 // AARCH64-NEXT: #define __LDBL_MIN__ 3.36210314311209350626267781732175260e-4932L
+// AARCH64-NEXT: #define __LDBL_NORM_MAX__ 1.18973149535723176508575932662800702e+4932L
 // AARCH64_LE-NEXT: #define __LITTLE_ENDIAN__ 1
 // AARCH64-NEXT: #define __LLONG_WIDTH__ 64
 // AARCH64-NEXT: #define __LONG_LONG_MAX__ 9223372036854775807LL
diff --git a/clang/test/Preprocessor/init.c b/clang/test/Preprocessor/init.c
index 12ebaeaedaffa..c177975114332 100644
--- a/clang/test/Preprocessor/init.c
+++ b/clang/test/Preprocessor/init.c
@@ -1648,6 +1648,7 @@
 // WEBASSEMBLY-NEXT:#define __DBL_MIN_10_EXP__ (-307)
 // WEBASSEMBLY-NEXT:#define __DBL_MIN_EXP__ (-1021)
 // WEBASSEMBLY-NEXT:#define __DBL_MIN__ 2.2250738585072014e-308
+// WEBASSEMBLY-NEXT:#define __DBL_NORM_MAX__ 1.7976931348623157e+308
 // WEBASSEMBLY-NEXT:#define __DECIMAL_DIG__ __LDBL_DECIMAL_DIG__
 // WEBASSEMBLY-NOT:#define __ELF__
 // EMSCRIPTEN-THREADS-NEXT:#define __EMSCRIPTEN_PTHREADS__ 1
@@ -1668,6 +1669,7 @@
 // WEBASSEMBLY-NOT:#define __FLT16_MIN_10_EXP__
 // WEBASSEMBLY-NOT:#define __FLT16_MIN_EXP__
 // WEBASSEMBLY-NOT:#define __FLT16_MIN__
+// WEBASSEMBLY-NOT:#define __FLT16_NORM_MAX__
 // WEBASSEMBLY-NEXT:#define __FLT_DECIMAL_DIG__ 9
 // WEBASSEMBLY-NEXT:#define __FLT_DENORM_MIN__ 1.40129846e-45F
 // WEBASSEMBLY-NEXT:#define __FLT_DIG__ 6
@@ -1682,6 +1684,7 @@
 // WEBASSEMBLY-NEXT:#define __FLT_MIN_10_EXP__ (-37)
 // WEBASSEMBLY-NEXT:#define __FLT_MIN_EXP__ (-125)
 // WEBASSEMBLY-NEXT:#define __FLT_MIN__ 1.17549435e-38F
+// WEBASSEMBLY-NEXT:#define __FLT_NORM_MAX__ 3.40282347e+38F
 // WEBASSEMBLY-NEXT:#define __FLT_RADIX__ 2
 // WEBASSEMBLY-NEXT:#define __FPCLASS_NEGINF 0x0004
 // WEBASSEMBLY-NEXT:#define __FPCLASS_NEGNORMAL 0x0008
@@ -1806,6 +1809,7 @@
 // WEBASSEMBLY-NEXT:#define __LDBL_MIN_10_EXP__ (-4931)
 // WEBASSEMBLY-NEXT:#define __LDBL_MIN_EXP__ (-16381)
 // WEBASSEMBLY-NEXT:#define __LDBL_MIN__ 3.36210314311209350626267781732175260e-4932L
+// WEBASSEMBLY-NEXT:#define __LDBL_NORM_MAX__ 1.18973149535723176508575932662800702e+4932L
 // WEBASSEMBLY-NEXT:#define __LITTLE_ENDIAN__ 1
 // WEBASSEMBLY-NEXT:#define __LLONG_WIDTH__ 64
 // WEBASSEMBLY-NEXT:#define __LONG_LONG_MAX__ 9223372036854775807LL

>From cd2de3b865734b6a90b86c0bb3f5844992743645 Mon Sep 17 00:00:00 2001
From: Aaron Ballman <aaron at aaronballman.com>
Date: Wed, 26 Jun 2024 08:19:02 -0400
Subject: [PATCH 3/4] Correct copy pasta in tests

---
 clang/test/Headers/float.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang/test/Headers/float.c b/clang/test/Headers/float.c
index 59cc0faa074db..fd966e7f01144 100644
--- a/clang/test/Headers/float.c
+++ b/clang/test/Headers/float.c
@@ -220,12 +220,12 @@
 #ifndef DBL_NORM_MAX
   #error "Mandatory macro DBL_NORM_MAX is missing."
 #else
-  _Static_assert(DBL_NORM_MAX >= 1.0E+37F, "Mandatory macro DBL_NORM_MAX is invalid.");
+  _Static_assert(DBL_NORM_MAX >= 1.0E+37, "Mandatory macro DBL_NORM_MAX is invalid.");
 #endif
 #ifndef LDBL_NORM_MAX
   #error "Mandatory macro LDBL_NORM_MAX is missing."
 #else
-  _Static_assert(LDBL_NORM_MAX >= 1.0E+37F, "Mandatory macro LDBL_NORM_MAX is invalid.");
+  _Static_assert(LDBL_NORM_MAX >= 1.0E+37L, "Mandatory macro LDBL_NORM_MAX is invalid.");
 #endif
 #endif
 

>From e8c7c837b1d0bc0ba38d887baf25819fb8a7a6af Mon Sep 17 00:00:00 2001
From: Aaron Ballman <aaron at aaronballman.com>
Date: Wed, 26 Jun 2024 08:20:28 -0400
Subject: [PATCH 4/4] Correct value for PPC double double format

This value was gleaned from GCC's output
---
 clang/lib/Frontend/InitPreprocessor.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp
index afc4c16ab685b..8638e01af85b4 100644
--- a/clang/lib/Frontend/InitPreprocessor.cpp
+++ b/clang/lib/Frontend/InitPreprocessor.cpp
@@ -116,7 +116,7 @@ static void DefineFloatMacros(MacroBuilder &Builder, StringRef Prefix,
   const char *DenormMin, *NormMax, *Epsilon, *Max, *Min;
   NormMax = PickFP(Sem, "6.5504e+4", "3.40282347e+38",
                    "1.7976931348623157e+308", "1.18973149535723176502e+4932",
-                   "1.79769313486231580793728971405301e+308",
+                   "8.98846567431157953864652595394501e+307",
                    "1.18973149535723176508575932662800702e+4932");
   DenormMin = PickFP(Sem, "5.9604644775390625e-8", "1.40129846e-45",
                      "4.9406564584124654e-324", "3.64519953188247460253e-4951",



More information about the cfe-commits mailing list