1 // RUN: %clang_cc1 -x c++ -verify=no-inf-no-nan \ 2 // RUN: -triple powerpc64le-unknown-unknown %s \ 3 // RUN: -menable-no-infs -menable-no-nans -std=c++23 4 5 // RUN: %clang_cc1 -x c++ -verify=no-inf-no-nan \ 6 // RUN: -triple powerpc64le-unknown-unknown %s \ 7 // RUN: -menable-no-infs -menable-no-nans -funsafe-math-optimizations \ 8 // RUN: -std=c++23 9 10 // RUN: %clang_cc1 -x c++ -verify=no-fast -triple powerpc64le-unknown-unknown \ 11 // RUN: %s -std=c++23 12 13 // RUN: %clang_cc1 -x c++ -verify=no-inf -triple powerpc64le-unknown-unknown %s \ 14 // RUN: -menable-no-infs -std=c++23 15 16 // RUN: %clang_cc1 -x c++ -verify=no-inf -triple powerpc64le-unknown-unknown %s \ 17 // RUN: -menable-no-infs -funsafe-math-optimizations -std=c++23 18 19 // RUN: %clang_cc1 -x c++ -verify=no-nan -triple powerpc64le-unknown-unknown %s \ 20 // RUN: -menable-no-nans -std=c++23 21 22 // RUN: %clang_cc1 -x c++ -verify=no-nan -triple powerpc64le-unknown-unknown %s \ 23 // RUN: -funsafe-math-optimizations -menable-no-nans -std=c++23 24 25 // RUN: %clang_cc1 -x c++ -verify=no-fast -triple powerpc64le-unknown-unknown \ 26 // RUN: %s -Wno-nan-infinity-disabled -menable-no-infs -std=c++23 27 28 // RUN: %clang_cc1 -x c++ -verify=no-fast -triple powerpc64le-unknown-unknown \ 29 // RUN: %s -Wno-nan-infinity-disabled -menable-no-nans -std=c++23 30 31 // no-fast-no-diagnostics 32 33 int isunorderedf (float x, float y); 34 extern "C++" { 35 namespace std __attribute__((__visibility__("default"))) { 36 bool 37 isinf(float __x); 38 bool 39 isinf(double __x); 40 bool 41 isinf(long double __x); 42 bool 43 isnan(float __x); 44 bool 45 isnan(double __x); 46 bool 47 isnan(long double __x); 48 bool 49 isfinite(float __x); 50 bool 51 isfinite(double __x); 52 bool 53 isfinte(long double __x); 54 bool 55 isunordered(float __x, float __y); 56 bool 57 isunordered(double __x, double __y); 58 bool 59 isunordered(long double __x, long double __y); 60 61 template <class _Ty> 62 class numeric_limits { 63 public: 64 [[nodiscard]] static constexpr _Ty infinity() noexcept { 65 return _Ty(); 66 } 67 }; 68 } // namespace ) 69 } 70 71 #define NAN (__builtin_nanf("")) 72 #define INFINITY (__builtin_inff()) 73 74 template <> 75 class std::numeric_limits<float> { 76 public: 77 [[nodiscard]] static constexpr float infinity() noexcept { 78 return __builtin_huge_val(); 79 } 80 }; 81 82 template <> 83 class std::numeric_limits<double> { 84 public: 85 [[nodiscard]] static constexpr double infinity() noexcept { 86 return __builtin_huge_val(); 87 } 88 }; 89 90 template <class _Ty> 91 class numeric_limits { 92 public: 93 [[nodiscard]] static constexpr _Ty infinity() noexcept { 94 return _Ty(); 95 } 96 }; 97 98 template <> 99 class numeric_limits<float> { 100 public: 101 [[nodiscard]] static constexpr float infinity() noexcept { 102 return __builtin_huge_val(); 103 } 104 }; 105 106 template <> 107 class numeric_limits<double> { 108 public: 109 [[nodiscard]] static constexpr double infinity() noexcept { 110 return __builtin_huge_val(); 111 } 112 }; 113 114 double infinity() { return 0; } 115 116 int compareit(float a, float b) { 117 volatile int i, j, k, l, m, n, o, p; 118 // no-inf-no-nan-warning@+4 {{use of infinity is undefined behavior due to the currently enabled floating-point options}} 119 // no-inf-no-nan-warning@+3 {{use of infinity via a macro is undefined behavior due to the currently enabled floating-point options}} 120 // no-inf-warning@+2 {{use of infinity is undefined behavior due to the currently enabled floating-point options}} 121 // no-inf-warning@+1 {{use of infinity via a macro is undefined behavior due to the currently enabled floating-point options}} 122 i = a == INFINITY; 123 124 // no-inf-no-nan-warning@+4 {{use of infinity is undefined behavior due to the currently enabled floating-point options}} 125 // no-inf-no-nan-warning@+3 {{use of infinity via a macro is undefined behavior due to the currently enabled floating-point options}} 126 // no-inf-warning@+2 {{use of infinity is undefined behavior due to the currently enabled floating-point options}} 127 // no-inf-warning@+1 {{use of infinity via a macro is undefined behavior due to the currently enabled floating-point options}} 128 j = INFINITY == a; 129 130 // no-inf-no-nan-warning@+4 {{use of NaN is undefined behavior due to the currently enabled floating-point options}} 131 // no-inf-no-nan-warning@+3 {{use of NaN via a macro is undefined behavior due to the currently enabled floating-point options}} 132 // no-nan-warning@+2 {{use of NaN via a macro is undefined behavior due to the currently enabled floating-point options}} 133 // no-nan-warning@+1 {{use of NaN is undefined behavior due to the currently enabled floating-point options}} 134 i = a == NAN; 135 136 // no-inf-no-nan-warning@+4 {{use of NaN via a macro is undefined behavior due to the currently enabled floating-point options}} 137 // no-inf-no-nan-warning@+3 {{use of NaN is undefined behavior due to the currently enabled floating-point options}} 138 // no-nan-warning@+2 {{use of NaN is undefined behavior due to the currently enabled floating-point options}} 139 // no-nan-warning@+1 {{use of NaN via a macro is undefined behavior due to the currently enabled floating-point options}} 140 j = NAN == a; 141 142 // no-inf-no-nan-warning@+4 {{use of infinity is undefined behavior due to the currently enabled floating-point options}} 143 // no-inf-no-nan-warning@+3 {{use of infinity via a macro is undefined behavior due to the currently enabled floating-point options}} 144 // no-inf-warning@+2 {{use of infinity is undefined behavior due to the currently enabled floating-point options}} 145 // no-inf-warning@+1 {{use of infinity via a macro is undefined behavior due to the currently enabled floating-point options}} 146 j = INFINITY <= a; 147 148 // no-inf-no-nan-warning@+4 {{use of infinity is undefined behavior due to the currently enabled floating-point options}} 149 // no-inf-no-nan-warning@+3 {{use of infinity via a macro is undefined behavior due to the currently enabled floating-point options}} 150 // no-inf-warning@+2 {{use of infinity is undefined behavior due to the currently enabled floating-point options}} 151 // no-inf-warning@+1 {{use of infinity via a macro is undefined behavior due to the currently enabled floating-point options}} 152 j = INFINITY < a; 153 154 // no-inf-no-nan-warning@+4 {{use of NaN via a macro is undefined behavior due to the currently enabled floating-point options}} 155 // no-inf-no-nan-warning@+3 {{use of NaN is undefined behavior due to the currently enabled floating-point options}} 156 // no-nan-warning@+2 {{use of NaN via a macro is undefined behavior due to the currently enabled floating-point options}} 157 // no-nan-warning@+1 {{use of NaN is undefined behavior due to the currently enabled floating-point options}} 158 j = a > NAN; 159 160 // no-inf-no-nan-warning@+4 {{use of NaN via a macro is undefined behavior due to the currently enabled floating-point options}} 161 // no-inf-no-nan-warning@+3 {{use of NaN is undefined behavior due to the currently enabled floating-point options}} 162 // no-nan-warning@+2 {{use of NaN is undefined behavior due to the currently enabled floating-point options}} 163 // no-nan-warning@+1 {{use of NaN via a macro is undefined behavior due to the currently enabled floating-point options}} 164 j = a >= NAN; 165 166 // no-inf-no-nan-warning@+2 {{use of infinity is undefined behavior due to the currently enabled floating-point options}} 167 // no-inf-warning@+1 {{use of infinity is undefined behavior due to the currently enabled floating-point options}} 168 k = std::isinf(a); 169 170 // no-inf-no-nan-warning@+2 {{use of NaN is undefined behavior due to the currently enabled floating-point option}} 171 // no-nan-warning@+1 {{use of NaN is undefined behavior due to the currently enabled floating-point options}} 172 l = std::isnan(a); 173 174 // no-inf-no-nan-warning@+2 {{use of infinity is undefined behavior due to the currently enabled floating-point options}} 175 // no-inf-warning@+1 {{use of infinity is undefined behavior due to the currently enabled floating-point options}} 176 o = std::isfinite(a); 177 178 // no-inf-no-nan-warning@+2 {{use of infinity is undefined behavior due to the currently enabled floating-point options}} 179 // no-inf-warning@+1 {{use of infinity is undefined behavior due to the currently enabled floating-point options}} 180 m = __builtin_isinf(a); 181 182 // no-inf-no-nan-warning@+2 {{use of NaN is undefined behavior due to the currently enabled floating-point options}} 183 // no-nan-warning@+1 {{use of NaN is undefined behavior due to the currently enabled floating-point options}} 184 n = __builtin_isnan(a); 185 186 // no-inf-no-nan-warning@+2 {{use of infinity is undefined behavior due to the currently enabled floating-point options}} 187 // no-inf-warning@+1 {{use of infinity is undefined behavior due to the currently enabled floating-point options}} 188 p = __builtin_isfinite(a); 189 190 // These should NOT warn, since they are not using NaN or infinity. 191 j = a > 1.1; 192 j = b < 1.1; 193 j = a >= 1.1; 194 j = b <= 1.1; 195 j = isunorderedf(a, b); 196 197 #ifndef INFINITY 198 j = a; 199 #endif 200 #ifndef NAN 201 j = b; 202 #endif 203 #ifdef INFINITY 204 j = a; 205 #endif 206 #ifdef NAN 207 j = b; 208 #endif 209 #if defined(INFINITY) 210 j = a; 211 #elifndef(INFINITY) 212 j = b; 213 #endif 214 #if defined(INFINITY) 215 j = a; 216 #elifndef(NAN) 217 j = b; 218 #endif 219 #if defined(NAN) 220 j = a; 221 #elifndef(INFINITY) 222 j = b; 223 #endif 224 225 // no-inf-no-nan-warning@+4 {{use of NaN via a macro is undefined behavior due to the currently enabled floating-point options}} 226 // no-inf-no-nan-warning@+3 {{use of NaN is undefined behavior due to the currently enabled floating-point options}} 227 // no-nan-warning@+2 {{use of NaN via a macro is undefined behavior due to the currently enabled floating-point options}} 228 // no-nan-warning@+1 {{use of NaN is undefined behavior due to the currently enabled floating-point options}} 229 j = isunorderedf(a, NAN); 230 231 // no-inf-no-nan-warning@+4 {{use of infinity is undefined behavior due to the currently enabled floating-point options}} 232 // no-inf-no-nan-warning@+3 {{use of infinity via a macro is undefined behavior due to the currently enabled floating-point options}} 233 // no-inf-warning@+2 {{use of infinity is undefined behavior due to the currently enabled floating-point options}} 234 // no-inf-warning@+1 {{use of infinity via a macro is undefined behavior due to the currently enabled floating-point options}} 235 j = isunorderedf(a, INFINITY); 236 237 // no-inf-no-nan-warning@+6 {{use of NaN via a macro is undefined behavior due to the currently enabled floating-point options}} 238 // no-inf-no-nan-warning@+5 {{use of NaN is undefined behavior due to the currently enabled floating-point options}} 239 // no-inf-no-nan-warning@+4 {{use of NaN is undefined behavior due to the currently enabled floating-point options}} 240 // no-nan-warning@+3 {{use of NaN via a macro is undefined behavior due to the currently enabled floating-point options}} 241 // no-nan-warning@+2 {{use of NaN is undefined behavior due to the currently enabled floating-point options}} 242 // no-nan-warning@+1 {{use of NaN is undefined behavior due to the currently enabled floating-point options}} 243 i = std::isunordered(a, NAN); 244 245 // no-inf-no-nan-warning@+6 {{use of infinity is undefined behavior due to the currently enabled floating-point options}} 246 // no-inf-no-nan-warning@+5 {{use of infinity via a macro is undefined behavior due to the currently enabled floating-point options}} 247 // no-inf-no-nan-warning@+4 {{use of NaN is undefined behavior due to the currently enabled floating-point options}} 248 // no-inf-warning@+3 {{use of infinity via a macro is undefined behavior due to the currently enabled floating-point options}} 249 // no-inf-warning@+2 {{use of infinity is undefined behavior due to the currently enabled floating-point options}} 250 // no-nan-warning@+1 {{use of NaN is undefined behavior due to the currently enabled floating-point options}} 251 i = std::isunordered(a, INFINITY); 252 253 // no-inf-no-nan-warning@+2 {{use of infinity is undefined behavior due to the currently enabled floating-point options}} 254 // no-inf-warning@+1 {{use of infinity is undefined behavior due to the currently enabled floating-point options}} 255 double y = i * std::numeric_limits<double>::infinity(); 256 257 y = i * numeric_limits<double>::infinity(); // expected-no-diagnostics 258 259 // no-inf-no-nan-warning@+2 {{use of infinity is undefined behavior due to the currently enabled floating-point options}} 260 // no-inf-warning@+1 {{use of infinity is undefined behavior due to the currently enabled floating-point options}} 261 j = std::numeric_limits<float>::infinity(); 262 263 j = numeric_limits<float>::infinity(); // expected-no-diagnostics 264 265 y = infinity(); // expected-no-diagnostics 266 267 return 0; 268 269 } 270