304 lines · c
1// RUN: %clang_cc1 -fsyntax-only -verify -std=c89 -ffreestanding %s2// RUN: %clang_cc1 -fsyntax-only -verify -std=c99 -ffreestanding %s3// RUN: %clang_cc1 -fsyntax-only -verify -std=c11 -ffreestanding %s4// RUN: %clang_cc1 -fsyntax-only -verify -std=c23 -ffreestanding %s5// RUN: %clang_cc1 -fsyntax-only -verify=finite -std=c23 -ffreestanding -menable-no-nans -menable-no-infs %s6// RUN: %clang_cc1 -fsyntax-only -verify -xc++ -std=c++11 -ffreestanding %s7// RUN: %clang_cc1 -fsyntax-only -verify -xc++ -std=c++14 -ffreestanding %s8// RUN: %clang_cc1 -fsyntax-only -verify -xc++ -std=c++17 -ffreestanding %s9// RUN: %clang_cc1 -fsyntax-only -verify -xc++ -std=c++23 -ffreestanding %s10// NOTE: C++23 wasn't based on top of C23, so it gets no diagnostics for11// finite-math-only mode as happens in C. When C++ rebased onto C23, that12// 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 %s14// expected-no-diagnostics15 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. 2524 C11, 5.2.4.2.2p11, pp. 3025 C99, 5.2.4.2.2p9, pp. 2526 C89, 2.2.4.227*/28#include <float.h>29 30#ifndef FLT_RADIX31 #error "Mandatory macro FLT_RADIX is missing."32#elif FLT_RADIX < 233 #error "Mandatory macro FLT_RADIX is invalid."34#endif35 36 37#ifndef FLT_MANT_DIG38 #error "Mandatory macro FLT_MANT_DIG is missing."39#elif FLT_MANT_DIG < 240 #error "Mandatory macro FLT_MANT_DIG is invalid."41#endif42#ifndef DBL_MANT_DIG43 #error "Mandatory macro DBL_MANT_DIG is missing."44#elif DBL_MANT_DIG < 245 #error "Mandatory macro DBL_MANT_DIG is invalid."46#endif47#ifndef LDBL_MANT_DIG48 #error "Mandatory macro LDBL_MANT_DIG is missing."49#elif LDBL_MANT_DIG < 250 #error "Mandatory macro LDBL_MANT_DIG is invalid."51#endif52#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#endif55 56 57#if __STDC_VERSION__ >= 201112L || !defined(__STRICT_ANSI__) || __cplusplus >= 201703L58 #ifndef FLT_DECIMAL_DIG59 #error "Mandatory macro FLT_DECIMAL_DIG is missing."60 #elif FLT_DECIMAL_DIG < 661 #error "Mandatory macro FLT_DECIMAL_DIG is invalid."62 #endif63 #ifndef DBL_DECIMAL_DIG64 #error "Mandatory macro DBL_DECIMAL_DIG is missing."65 #elif DBL_DECIMAL_DIG < 1066 #error "Mandatory macro DBL_DECIMAL_DIG is invalid."67 #endif68 #ifndef LDBL_DECIMAL_DIG69 #error "Mandatory macro LDBL_DECIMAL_DIG is missing."70 #elif LDBL_DECIMAL_DIG < 1071 #error "Mandatory macro LDBL_DECIMAL_DIG is invalid."72 #endif73 #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 #endif76 #ifndef FLT_HAS_SUBNORM77 #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 #endif81 #ifndef LDBL_HAS_SUBNORM82 #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 #endif86 #ifndef DBL_HAS_SUBNORM87 #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 #endif91#else92 #ifdef FLT_DECIMAL_DIG93 #error "Macro FLT_DECIMAL_DIG should not be defined."94 #endif95 #ifdef DBL_DECIMAL_DIG96 #error "Macro DBL_DECIMAL_DIG should not be defined."97 #endif98 #ifdef LDBL_DECIMAL_DIG99 #error "Macro LDBL_DECIMAL_DIG should not be defined."100 #endif101 #ifdef FLT_HAS_SUBNORM102 #error "Macro FLT_HAS_SUBNORM should not be defined."103 #endif104 #ifdef DBL_HAS_SUBNORM105 #error "Macro DBL_HAS_SUBNORM should not be defined."106 #endif107 #ifdef LDBL_HAS_SUBNORM108 #error "Macro LDBL_HAS_SUBNORM should not be defined."109 #endif110#endif111 112 113#if __STDC_VERSION__ >= 199901L || !defined(__STRICT_ANSI__) || __cplusplus >= 201103L114 #ifndef DECIMAL_DIG115 #error "Mandatory macro DECIMAL_DIG is missing."116 #elif DECIMAL_DIG < 10117 #error "Mandatory macro DECIMAL_DIG is invalid."118 #endif119#else120 #ifdef DECIMAL_DIG121 #error "Macro DECIMAL_DIG should not be defined."122 #endif123#endif124 125 126#ifndef FLT_DIG127 #error "Mandatory macro FLT_DIG is missing."128#elif FLT_DIG < 6129 #error "Mandatory macro FLT_DIG is invalid."130#endif131#ifndef DBL_DIG132 #error "Mandatory macro DBL_DIG is missing."133#elif DBL_DIG < 10134 #error "Mandatory macro DBL_DIG is invalid."135#endif136#ifndef LDBL_DIG137 #error "Mandatory macro LDBL_DIG is missing."138#elif LDBL_DIG < 10139 #error "Mandatory macro LDBL_DIG is invalid."140#endif141#if ((FLT_DIG > DBL_DIG) || (DBL_DIG > LDBL_DIG))142 #error "Mandatory macros {FLT,DBL,LDBL}_DIG, are invalid."143#endif144 145 146#ifndef FLT_MIN_EXP147 #error "Mandatory macro FLT_MIN_EXP is missing."148#elif FLT_MIN_EXP > -1149 #error "Mandatory macro FLT_MIN_EXP is invalid."150#endif151#ifndef DBL_MIN_EXP152 #error "Mandatory macro DBL_MIN_EXP is missing."153#elif DBL_MIN_EXP > -1154 #error "Mandatory macro DBL_MIN_EXP is invalid."155#endif156#ifndef LDBL_MIN_EXP157 #error "Mandatory macro LDBL_MIN_EXP is missing."158#elif LDBL_MIN_EXP > -1159 #error "Mandatory macro LDBL_MIN_EXP is invalid."160#endif161 162 163#ifndef FLT_MIN_10_EXP164 #error "Mandatory macro FLT_MIN_10_EXP is missing."165#elif FLT_MIN_10_EXP > -37166 #error "Mandatory macro FLT_MIN_10_EXP is invalid."167#endif168#ifndef DBL_MIN_10_EXP169 #error "Mandatory macro DBL_MIN_10_EXP is missing."170#elif DBL_MIN_10_EXP > -37171 #error "Mandatory macro DBL_MIN_10_EXP is invalid."172#endif173#ifndef LDBL_MIN_10_EXP174 #error "Mandatory macro LDBL_MIN_10_EXP is missing."175#elif LDBL_MIN_10_EXP > -37176 #error "Mandatory macro LDBL_MIN_10_EXP is invalid."177#endif178 179 180#ifndef FLT_MAX_EXP181 #error "Mandatory macro FLT_MAX_EXP is missing."182#elif FLT_MAX_EXP < 1183 #error "Mandatory macro FLT_MAX_EXP is invalid."184#endif185#ifndef DBL_MAX_EXP186 #error "Mandatory macro DBL_MAX_EXP is missing."187#elif DBL_MAX_EXP < 1188 #error "Mandatory macro DBL_MAX_EXP is invalid."189#endif190#ifndef LDBL_MAX_EXP191 #error "Mandatory macro LDBL_MAX_EXP is missing."192#elif LDBL_MAX_EXP < 1193 #error "Mandatory macro LDBL_MAX_EXP is invalid."194#endif195#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#endif198 199 200#ifndef FLT_MAX_10_EXP201 #error "Mandatory macro FLT_MAX_10_EXP is missing."202#elif FLT_MAX_10_EXP < 37203 #error "Mandatory macro FLT_MAX_10_EXP is invalid."204#endif205#ifndef DBL_MAX_10_EXP206 #error "Mandatory macro DBL_MAX_10_EXP is missing."207#elif DBL_MAX_10_EXP < 37208 #error "Mandatory macro DBL_MAX_10_EXP is invalid."209#endif210#ifndef LDBL_MAX_10_EXP211 #error "Mandatory macro LDBL_MAX_10_EXP is missing."212#elif LDBL_MAX_10_EXP < 37213 #error "Mandatory macro LDBL_MAX_10_EXP is invalid."214#endif215#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#endif218 219#if __STDC_VERSION__ >= 202311L || !defined(__STRICT_ANSI__)220 #ifndef INFINITY221 #error "Mandatory macro INFINITY is missing."222 #endif223 #ifndef NAN224 #error "Mandatory macro NAN is missing."225 #endif226// 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_MAX233 #error "Mandatory macro FLT_NORM_MAX is missing."234#else235 _Static_assert(FLT_NORM_MAX >= 1.0E+37F, "Mandatory macro FLT_NORM_MAX is invalid.");236#endif237#ifndef DBL_NORM_MAX238 #error "Mandatory macro DBL_NORM_MAX is missing."239#else240 _Static_assert(DBL_NORM_MAX >= 1.0E+37, "Mandatory macro DBL_NORM_MAX is invalid.");241#endif242#ifndef LDBL_NORM_MAX243 #error "Mandatory macro LDBL_NORM_MAX is missing."244#else245 _Static_assert(LDBL_NORM_MAX >= 1.0E+37L, "Mandatory macro LDBL_NORM_MAX is invalid.");246#endif247#else248 #ifdef INFINITY249 #error "Macro INFINITY should not be defined."250 #endif251 #ifdef NAN252 #error "Macro NAN should not be defined."253 #endif254#endif255 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 >= 201703L264_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#endif268 269#if __STDC_VERSION__ >= 199901L || !defined(__STRICT_ANSI__) || __cplusplus >= 201103L270_Static_assert(DECIMAL_DIG == __DECIMAL_DIG__, "");271#endif272 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__ == 0299// Ensure INFINITY and NAN are suitable for use in a constant expression.300float f1 = INFINITY;301float f2 = NAN;302#endif303#endif304