xref: /llvm-project/clang/test/Headers/float.c (revision c9c91f59c318e28d884e5762f303348ba5724d21)
1 // RUN: %clang_cc1 -fsyntax-only -verify -std=c89 -ffreestanding %s
2 // RUN: %clang_cc1 -fsyntax-only -verify -std=c99 -ffreestanding %s
3 // RUN: %clang_cc1 -fsyntax-only -verify -std=c11 -ffreestanding %s
4 // RUN: %clang_cc1 -fsyntax-only -verify -std=c23 -ffreestanding %s
5 // RUN: %clang_cc1 -fsyntax-only -verify=finite -std=c23 -ffreestanding -menable-no-nans -menable-no-infs %s
6 // RUN: %clang_cc1 -fsyntax-only -verify -xc++ -std=c++11 -ffreestanding %s
7 // RUN: %clang_cc1 -fsyntax-only -verify -xc++ -std=c++14 -ffreestanding %s
8 // RUN: %clang_cc1 -fsyntax-only -verify -xc++ -std=c++17 -ffreestanding %s
9 // RUN: %clang_cc1 -fsyntax-only -verify -xc++ -std=c++23 -ffreestanding %s
10 // NOTE: C++23 wasn't based on top of C23, so it gets no diagnostics for
11 //       finite-math-only mode as happens in C. When C++ rebased onto C23, that
12 //       is when we'll issue diagnostics for INFINITY and NAN use.
13 // RUN: %clang_cc1 -fsyntax-only -verify -xc++ -std=c++23 -ffreestanding -ffinite-math-only %s
14 // expected-no-diagnostics
15 
16 /* Basic floating point conformance checks against:
17     - C23 Final Std.
18     - N1570 draft of C11 Std.
19     - N1256 draft of C99 Std.
20     - http://port70.net/~nsz/c/c89/c89-draft.html draft of C89/C90 Std.
21 */
22 /*
23     C23,    5.2.5.3.3p21,   pp. 25
24     C11,    5.2.4.2.2p11,   pp. 30
25     C99,    5.2.4.2.2p9,    pp. 25
26     C89,    2.2.4.2
27 */
28 #include <float.h>
29 
30 #ifndef FLT_RADIX
31     #error "Mandatory macro FLT_RADIX is missing."
32 #elif   FLT_RADIX < 2
33     #error "Mandatory macro FLT_RADIX is invalid."
34 #endif
35 
36 
37 #ifndef FLT_MANT_DIG
38     #error "Mandatory macro FLT_MANT_DIG is missing."
39 #elif   FLT_MANT_DIG < 2
40     #error "Mandatory macro FLT_MANT_DIG is invalid."
41 #endif
42 #ifndef DBL_MANT_DIG
43     #error "Mandatory macro DBL_MANT_DIG is missing."
44 #elif   DBL_MANT_DIG < 2
45     #error "Mandatory macro DBL_MANT_DIG is invalid."
46 #endif
47 #ifndef LDBL_MANT_DIG
48     #error "Mandatory macro LDBL_MANT_DIG is missing."
49 #elif   LDBL_MANT_DIG < 2
50     #error "Mandatory macro LDBL_MANT_DIG is invalid."
51 #endif
52 #if ((FLT_MANT_DIG > DBL_MANT_DIG) || (DBL_MANT_DIG > LDBL_MANT_DIG))
53     #error "Mandatory macros {FLT,DBL,LDBL}_MANT_DIG are invalid."
54 #endif
55 
56 
57 #if __STDC_VERSION__ >= 201112L || !defined(__STRICT_ANSI__) || __cplusplus >= 201703L
58     #ifndef FLT_DECIMAL_DIG
59         #error "Mandatory macro FLT_DECIMAL_DIG is missing."
60     #elif   FLT_DECIMAL_DIG < 6
61         #error "Mandatory macro FLT_DECIMAL_DIG is invalid."
62     #endif
63     #ifndef DBL_DECIMAL_DIG
64         #error "Mandatory macro DBL_DECIMAL_DIG is missing."
65     #elif   DBL_DECIMAL_DIG < 10
66         #error "Mandatory macro DBL_DECIMAL_DIG is invalid."
67     #endif
68     #ifndef LDBL_DECIMAL_DIG
69         #error "Mandatory macro LDBL_DECIMAL_DIG is missing."
70     #elif   LDBL_DECIMAL_DIG < 10
71         #error "Mandatory macro LDBL_DECIMAL_DIG is invalid."
72     #endif
73     #if ((FLT_DECIMAL_DIG > DBL_DECIMAL_DIG) || (DBL_DECIMAL_DIG > LDBL_DECIMAL_DIG))
74         #error "Mandatory macros {FLT,DBL,LDBL}_DECIMAL_DIG are invalid."
75     #endif
76     #ifndef FLT_HAS_SUBNORM
77         #error "Mandatory macro FLT_HAS_SUBNORM is missing."
78     #elif FLT_HAS_SUBNORM != __FLT_HAS_DENORM__
79         #error "Mandatory macro FLT_HAS_SUBNORM is invalid."
80     #endif
81     #ifndef LDBL_HAS_SUBNORM
82         #error "Mandatory macro LDBL_HAS_SUBNORM is missing."
83     #elif LDBL_HAS_SUBNORM != __LDBL_HAS_DENORM__
84         #error "Mandatory macro LDBL_HAS_SUBNORM is invalid."
85     #endif
86     #ifndef DBL_HAS_SUBNORM
87         #error "Mandatory macro DBL_HAS_SUBNORM is missing."
88     #elif DBL_HAS_SUBNORM != __DBL_HAS_DENORM__
89         #error "Mandatory macro DBL_HAS_SUBNORM is invalid."
90     #endif
91 #else
92     #ifdef FLT_DECIMAL_DIG
93         #error "Macro FLT_DECIMAL_DIG should not be defined."
94     #endif
95     #ifdef DBL_DECIMAL_DIG
96         #error "Macro DBL_DECIMAL_DIG should not be defined."
97     #endif
98     #ifdef LDBL_DECIMAL_DIG
99         #error "Macro LDBL_DECIMAL_DIG should not be defined."
100     #endif
101     #ifdef FLT_HAS_SUBNORM
102         #error "Macro FLT_HAS_SUBNORM should not be defined."
103     #endif
104     #ifdef DBL_HAS_SUBNORM
105         #error "Macro DBL_HAS_SUBNORM should not be defined."
106     #endif
107     #ifdef LDBL_HAS_SUBNORM
108         #error "Macro LDBL_HAS_SUBNORM should not be defined."
109     #endif
110 #endif
111 
112 
113 #if __STDC_VERSION__ >= 199901L || !defined(__STRICT_ANSI__) || __cplusplus >= 201103L
114     #ifndef DECIMAL_DIG
115         #error "Mandatory macro DECIMAL_DIG is missing."
116     #elif   DECIMAL_DIG < 10
117         #error "Mandatory macro DECIMAL_DIG is invalid."
118     #endif
119 #else
120     #ifdef DECIMAL_DIG
121         #error "Macro DECIMAL_DIG should not be defined."
122     #endif
123 #endif
124 
125 
126 #ifndef FLT_DIG
127     #error "Mandatory macro FLT_DIG is missing."
128 #elif   FLT_DIG < 6
129     #error "Mandatory macro FLT_DIG is invalid."
130 #endif
131 #ifndef DBL_DIG
132     #error "Mandatory macro DBL_DIG is missing."
133 #elif   DBL_DIG < 10
134     #error "Mandatory macro DBL_DIG is invalid."
135 #endif
136 #ifndef LDBL_DIG
137     #error "Mandatory macro LDBL_DIG is missing."
138 #elif   LDBL_DIG < 10
139     #error "Mandatory macro LDBL_DIG is invalid."
140 #endif
141 #if ((FLT_DIG > DBL_DIG) || (DBL_DIG > LDBL_DIG))
142     #error "Mandatory macros {FLT,DBL,LDBL}_DIG, are invalid."
143 #endif
144 
145 
146 #ifndef FLT_MIN_EXP
147     #error "Mandatory macro FLT_MIN_EXP is missing."
148 #elif   FLT_MIN_EXP > -1
149     #error "Mandatory macro FLT_MIN_EXP is invalid."
150 #endif
151 #ifndef DBL_MIN_EXP
152     #error "Mandatory macro DBL_MIN_EXP is missing."
153 #elif   DBL_MIN_EXP > -1
154     #error "Mandatory macro DBL_MIN_EXP is invalid."
155 #endif
156 #ifndef LDBL_MIN_EXP
157     #error "Mandatory macro LDBL_MIN_EXP is missing."
158 #elif   LDBL_MIN_EXP > -1
159     #error "Mandatory macro LDBL_MIN_EXP is invalid."
160 #endif
161 
162 
163 #ifndef FLT_MIN_10_EXP
164     #error "Mandatory macro FLT_MIN_10_EXP is missing."
165 #elif   FLT_MIN_10_EXP > -37
166     #error "Mandatory macro FLT_MIN_10_EXP is invalid."
167 #endif
168 #ifndef DBL_MIN_10_EXP
169     #error "Mandatory macro DBL_MIN_10_EXP is missing."
170 #elif   DBL_MIN_10_EXP > -37
171     #error "Mandatory macro DBL_MIN_10_EXP is invalid."
172 #endif
173 #ifndef LDBL_MIN_10_EXP
174     #error "Mandatory macro LDBL_MIN_10_EXP is missing."
175 #elif   LDBL_MIN_10_EXP > -37
176     #error "Mandatory macro LDBL_MIN_10_EXP is invalid."
177 #endif
178 
179 
180 #ifndef FLT_MAX_EXP
181     #error "Mandatory macro FLT_MAX_EXP is missing."
182 #elif   FLT_MAX_EXP < 1
183     #error "Mandatory macro FLT_MAX_EXP is invalid."
184 #endif
185 #ifndef DBL_MAX_EXP
186     #error "Mandatory macro DBL_MAX_EXP is missing."
187 #elif   DBL_MAX_EXP < 1
188     #error "Mandatory macro DBL_MAX_EXP is invalid."
189 #endif
190 #ifndef LDBL_MAX_EXP
191     #error "Mandatory macro LDBL_MAX_EXP is missing."
192 #elif   LDBL_MAX_EXP < 1
193     #error "Mandatory macro LDBL_MAX_EXP is invalid."
194 #endif
195 #if ((FLT_MAX_EXP > DBL_MAX_EXP) || (DBL_MAX_EXP > LDBL_MAX_EXP))
196     #error "Mandatory macros {FLT,DBL,LDBL}_MAX_EXP are invalid."
197 #endif
198 
199 
200 #ifndef FLT_MAX_10_EXP
201     #error "Mandatory macro FLT_MAX_10_EXP is missing."
202 #elif   FLT_MAX_10_EXP < 37
203     #error "Mandatory macro FLT_MAX_10_EXP is invalid."
204 #endif
205 #ifndef DBL_MAX_10_EXP
206     #error "Mandatory macro DBL_MAX_10_EXP is missing."
207 #elif   DBL_MAX_10_EXP < 37
208     #error "Mandatory macro DBL_MAX_10_EXP is invalid."
209 #endif
210 #ifndef LDBL_MAX_10_EXP
211     #error "Mandatory macro LDBL_MAX_10_EXP is missing."
212 #elif   LDBL_MAX_10_EXP < 37
213     #error "Mandatory macro LDBL_MAX_10_EXP is invalid."
214 #endif
215 #if ((FLT_MAX_10_EXP > DBL_MAX_10_EXP) || (DBL_MAX_10_EXP > LDBL_MAX_10_EXP))
216     #error "Mandatory macros {FLT,DBL,LDBL}_MAX_10_EXP are invalid."
217 #endif
218 
219 #if __STDC_VERSION__ >= 202311L || !defined(__STRICT_ANSI__)
220   #ifndef INFINITY
221     #error "Mandatory macro INFINITY is missing."
222   #endif
223   #ifndef NAN
224     #error "Mandatory macro NAN is missing."
225   #endif
226 // FIXME: the NAN and INF diagnostics should only be issued once, not twice.
227   _Static_assert(_Generic(INFINITY, float : 1, default : 0), ""); // finite-warning {{use of infinity via a macro is undefined behavior due to the currently enabled floating-point options}} \
228 								  finite-warning {{use of infinity is undefined behavior due to the currently enabled floating-point options}}
229   _Static_assert(_Generic(NAN, float : 1, default : 0), ""); // finite-warning {{use of NaN is undefined behavior due to the currently enabled floating-point options}} \
230                                                                 finite-warning {{use of NaN via a macro is undefined behavior due to the currently enabled floating-point options}}
231 
232 #ifndef FLT_NORM_MAX
233   #error "Mandatory macro FLT_NORM_MAX is missing."
234 #else
235   _Static_assert(FLT_NORM_MAX >= 1.0E+37F, "Mandatory macro FLT_NORM_MAX is invalid.");
236 #endif
237 #ifndef DBL_NORM_MAX
238   #error "Mandatory macro DBL_NORM_MAX is missing."
239 #else
240   _Static_assert(DBL_NORM_MAX >= 1.0E+37, "Mandatory macro DBL_NORM_MAX is invalid.");
241 #endif
242 #ifndef LDBL_NORM_MAX
243   #error "Mandatory macro LDBL_NORM_MAX is missing."
244 #else
245   _Static_assert(LDBL_NORM_MAX >= 1.0E+37L, "Mandatory macro LDBL_NORM_MAX is invalid.");
246 #endif
247 #else
248   #ifdef INFINITY
249     #error "Macro INFINITY should not be defined."
250   #endif
251   #ifdef NAN
252     #error "Macro NAN should not be defined."
253   #endif
254 #endif
255 
256 /* Internal consistency checks */
257 _Static_assert(FLT_RADIX == __FLT_RADIX__, "");
258 
259 _Static_assert(FLT_MANT_DIG == __FLT_MANT_DIG__, "");
260 _Static_assert(DBL_MANT_DIG == __DBL_MANT_DIG__, "");
261 _Static_assert(LDBL_MANT_DIG == __LDBL_MANT_DIG__, "");
262 
263 #if __STDC_VERSION__ >= 201112L || !defined(__STRICT_ANSI__) || __cplusplus >= 201703L
264 _Static_assert(FLT_DECIMAL_DIG == __FLT_DECIMAL_DIG__, "");
265 _Static_assert(DBL_DECIMAL_DIG == __DBL_DECIMAL_DIG__, "");
266 _Static_assert(LDBL_DECIMAL_DIG == __LDBL_DECIMAL_DIG__, "");
267 #endif
268 
269 #if __STDC_VERSION__ >= 199901L || !defined(__STRICT_ANSI__) || __cplusplus >= 201103L
270 _Static_assert(DECIMAL_DIG == __DECIMAL_DIG__, "");
271 #endif
272 
273 _Static_assert(FLT_DIG == __FLT_DIG__, "");
274 _Static_assert(DBL_DIG == __DBL_DIG__, "");
275 _Static_assert(LDBL_DIG == __LDBL_DIG__, "");
276 
277 _Static_assert(FLT_MIN_EXP == __FLT_MIN_EXP__, "");
278 _Static_assert(DBL_MIN_EXP == __DBL_MIN_EXP__, "");
279 _Static_assert(LDBL_MIN_EXP == __LDBL_MIN_EXP__, "");
280 
281 _Static_assert(FLT_MIN_10_EXP == __FLT_MIN_10_EXP__, "");
282 _Static_assert(DBL_MIN_10_EXP == __DBL_MIN_10_EXP__, "");
283 _Static_assert(LDBL_MIN_10_EXP == __LDBL_MIN_10_EXP__, "");
284 
285 _Static_assert(FLT_MAX_EXP == __FLT_MAX_EXP__, "");
286 _Static_assert(DBL_MAX_EXP == __DBL_MAX_EXP__, "");
287 _Static_assert(LDBL_MAX_EXP == __LDBL_MAX_EXP__, "");
288 
289 _Static_assert(FLT_MAX_10_EXP == __FLT_MAX_10_EXP__, "");
290 _Static_assert(DBL_MAX_10_EXP == __DBL_MAX_10_EXP__, "");
291 _Static_assert(LDBL_MAX_10_EXP == __LDBL_MAX_10_EXP__, "");
292 
293 #if __STDC_VERSION__ >= 202311L || !defined(__STRICT_ANSI__)
294 _Static_assert(FLT_NORM_MAX == __FLT_NORM_MAX__, "");
295 _Static_assert(DBL_NORM_MAX == __DBL_NORM_MAX__, "");
296 _Static_assert(LDBL_NORM_MAX == __LDBL_NORM_MAX__, "");
297 
298 #if __FINITE_MATH_ONLY__ == 0
299 // Ensure INFINITY and NAN are suitable for use in a constant expression.
300 float f1 = INFINITY;
301 float f2 = NAN;
302 #endif
303 #endif
304