-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[C23] Add *_NORM_MAX macros to <float.h> #96643
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
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.
@llvm/pr-subscribers-clang @llvm/pr-subscribers-backend-x86 Author: Aaron Ballman (AaronBallman) ChangesThis 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. Full diff: https://github.com/llvm/llvm-project/pull/96643.diff 4 Files Affected:
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
|
You can test this locally with the following command:git-clang-format --diff 748a6ad68ba31d242e3f86eddd5b0fd7b2a02ff9 aee0da9de46bfadae00774ec9206f22bf0254d05 -- clang/lib/Frontend/InitPreprocessor.cpp clang/lib/Headers/float.h clang/test/Headers/float.c clang/test/Preprocessor/init-aarch64.c clang/test/Preprocessor/init.c View the diff from clang-format here.diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp
index d40d78a385..4ab1e30e5e 100644
--- a/clang/lib/Frontend/InitPreprocessor.cpp
+++ b/clang/lib/Frontend/InitPreprocessor.cpp
@@ -148,7 +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 + "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 e5c439a9d4..356c2cab78 100644
--- a/clang/lib/Headers/float.h
+++ b/clang/lib/Headers/float.h
@@ -88,9 +88,9 @@
# endif
#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L) || \
!defined(__STRICT_ANSI__)
-# undef FLT_NORM_MAX
-# undef DBL_NORM_MAX
-# undef LDBL_NORM_MAX
+#undef FLT_NORM_MAX
+#undef DBL_NORM_MAX
+#undef LDBL_NORM_MAX
#endif
#endif
@@ -172,10 +172,10 @@
/* C23 5.2.5.3.3p29-30 */
# define INFINITY (__builtin_inff())
# define NAN (__builtin_nanf(""))
- /* C23 5.2.5.3.3p32 */
-# define FLT_NORM_MAX __FLT_NORM_MAX__
-# define DBL_NORM_MAX __DBL_NORM_MAX__
-# define LDBL_NORM_MAX __LDBL_NORM_MAX__
+/* C23 5.2.5.3.3p32 */
+#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__
|
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", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this is the correct value for ppc double-double, since double-double is supposed to give a different result for NORM_MAX than MAX (indeed, that's explicitly the point of the new macros!)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch, thank you! I see now that GCC uses the following values for long double
:
#define __LDBL_MAX__ 1.79769313486231580793728971405301e+308L
#define __LDBL_NORM_MAX__ 8.98846567431157953864652595394501e+307L
https://godbolt.org/z/M1zjxx7K5
so I should probably go with 8.98846567431157953864652595394501e+307
as the value? CC @hubert-reinterpretcast
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ping -- I think I've corrected the value (at least, I'm using the same value as GCC in this case).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm pretty sure this is correct, but I'd rather prefer someone who knows PPC to confirm this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ping @hubert-reinterpretcast @chenzheng1030 -- hoping to get this landed for Clang 19, just need verification that the value is correct here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, the value is correct for an interpretation where the LDBL_MANT_DIG
is 106.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you Hubert!
This value was gleaned from GCC's output
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.
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.