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