1 // RUN: %clang_cc1 -fexperimental-new-constant-interpreter -verify=both,expected -Wno-unused-value %s 2 // RUN: %clang_cc1 -verify=both,ref -Wno-unused-value %s 3 4 constexpr _Complex double z1 = {1.0, 2.0}; 5 static_assert(__real(z1) == 1.0, ""); 6 static_assert(__imag(z1) == 2.0, ""); 7 8 static_assert(&__imag z1 == &__real z1 + 1, ""); 9 static_assert((*(&__imag z1)) == __imag z1, ""); 10 static_assert((*(&__real z1)) == __real z1, ""); 11 12 13 static_assert(((1.25 + 0.5j) * (0.25 - 0.75j)) == (0.6875 - 0.8125j), ""); 14 static_assert(((1.25 + 0.5j) * 0.25) == (0.3125 + 0.125j), ""); 15 static_assert((1.25 * (0.25 - 0.75j)) == (0.3125 - 0.9375j), ""); 16 constexpr _Complex float InfC = {1.0, __builtin_inf()}; 17 constexpr _Complex float InfInf = __builtin_inf() + InfC; 18 static_assert(__real__(InfInf) == __builtin_inf()); 19 static_assert(__imag__(InfInf) == __builtin_inf()); 20 static_assert(__builtin_isnan(__real__(InfInf * InfInf))); 21 static_assert(__builtin_isinf_sign(__imag__(InfInf * InfInf)) == 1); 22 23 static_assert(__builtin_isinf_sign(__real__((__builtin_inf() + 1.0j) * 1.0)) == 1); 24 static_assert(__builtin_isinf_sign(__imag__((1.0 + InfC) * 1.0)) == 1); 25 static_assert(__builtin_isinf_sign(__real__(1.0 * (__builtin_inf() + 1.0j))) == 1); 26 static_assert(__builtin_isinf_sign(__imag__(1.0 * (1.0 + InfC))) == 1); 27 static_assert(__builtin_isinf_sign(__real__((__builtin_inf() + 1.0j) * (1.0 + 1.0j))) == 1); 28 static_assert(__builtin_isinf_sign(__real__((1.0 + 1.0j) * (__builtin_inf() + 1.0j))) == 1); 29 static_assert(__builtin_isinf_sign(__real__((__builtin_inf() + 1.0j) * (__builtin_inf() + 1.0j))) == 1); 30 static_assert(__builtin_isinf_sign(__real__((1.0 + InfC) * (1.0 + 1.0j))) == -1); 31 static_assert(__builtin_isinf_sign(__imag__((1.0 + InfC) * (1.0 + 1.0j))) == 1); 32 static_assert(__builtin_isinf_sign(__real__((1.0 + 1.0j) * (1.0 + InfC))) == -1); 33 static_assert(__builtin_isinf_sign(__imag__((1.0 + 1.0j) * (1.0 + InfC))) == 1); 34 static_assert(__builtin_isinf_sign(__real__((1.0 + InfC) * (1.0 + InfC))) == -1); 35 static_assert(__builtin_isinf_sign(__real__(InfInf * InfInf)) == 0); 36 37 constexpr _Complex int IIMA = {1,2}; 38 constexpr _Complex int IIMB = {10,20}; 39 constexpr _Complex int IIMC = IIMA * IIMB; 40 static_assert(__real(IIMC) == -30, ""); 41 static_assert(__imag(IIMC) == 40, ""); 42 43 static_assert(1.0j / 0.0 == 1); // both-error {{static assertion}} \ 44 // both-note {{division by zero}} 45 static_assert(__builtin_isinf_sign(__real__((1.0 + 1.0j) / (0.0 + 0.0j))) == 1); 46 static_assert(__builtin_isinf_sign(__real__((1.0 + 1.0j) / 0.0)) == 1); // both-error {{static assertion}} \ 47 // both-note {{division by zero}} 48 static_assert(__builtin_isinf_sign(__real__((__builtin_inf() + 1.0j) / (0.0 + 0.0j))) == 1); 49 static_assert(__builtin_isinf_sign(__imag__((1.0 + InfC) / (0.0 + 0.0j))) == 1); 50 static_assert(__builtin_isinf_sign(__imag__((InfInf) / (0.0 + 0.0j))) == 1); 51 52 constexpr _Complex int IIDA = {10,20}; 53 constexpr _Complex int IIDB = {1,2}; 54 constexpr _Complex int IIDC = IIDA / IIDB; 55 static_assert(__real(IIDC) == 10, ""); 56 static_assert(__imag(IIDC) == 0, ""); 57 58 constexpr _Complex int Comma1 = {1, 2}; 59 constexpr _Complex int Comma2 = (0, Comma1); 60 static_assert(Comma1 == Comma1, ""); 61 62 constexpr double setter() { 63 _Complex float d = {1.0, 2.0}; 64 65 __imag(d) = 4.0; 66 return __imag(d); 67 } 68 static_assert(setter() == 4, ""); 69 70 constexpr _Complex double getter() { 71 return {1.0, 3.0}; 72 } 73 constexpr _Complex double D = getter(); 74 static_assert(__real(D) == 1.0, ""); 75 static_assert(__imag(D) == 3.0, ""); 76 77 78 constexpr _Complex int I1 = {1, 2}; 79 static_assert(__real(I1) == 1, ""); 80 static_assert(__imag(I1) == 2, ""); 81 82 83 constexpr _Complex double D1 = {}; 84 static_assert(__real(D1) == 0, ""); 85 static_assert(__imag(D1) == 0, ""); 86 87 constexpr _Complex int I2 = {}; 88 static_assert(__real(I2) == 0, ""); 89 static_assert(__imag(I2) == 0, ""); 90 91 static_assert(__real(4.0) == 4.0, ""); 92 static_assert(__real(12u) == 12u, ""); 93 static_assert(__imag(4.0) == 0.0, ""); 94 static_assert(__imag(13) == 0, ""); 95 96 97 constexpr _Complex long L1 = D; 98 static_assert(__real(L1) == 1.0, ""); 99 static_assert(__imag(L1) == 3.0, ""); 100 101 constexpr _Complex short I4 = L1; 102 static_assert(__real(I4) == 1, ""); 103 static_assert(__imag(I4) == 3, ""); 104 105 constexpr _Complex float D3 = D; 106 static_assert(__real(D3) == 1.0, ""); 107 static_assert(__imag(D3) == 3.0, ""); 108 109 110 constexpr _Complex int a = 2i; 111 static_assert(__real(a) == 0, ""); 112 static_assert(__imag(a) == 2, ""); 113 114 constexpr _Complex double b = 4.0i; 115 static_assert(__real(b) == 0, ""); 116 static_assert(__imag(b) == 4, ""); 117 118 constexpr int ignored() { 119 I2; 120 (int)I2; 121 (float)I2; 122 D1; 123 (int)D1; 124 (double)D1; 125 (_Complex float)I2; 126 (bool)D1; 127 (bool)I2; 128 return 0; 129 } 130 static_assert(ignored() == 0, ""); 131 static_assert((int)I1 == 1, ""); 132 static_assert((float)D == 1.0f, ""); 133 134 static_assert(__real((_Complex unsigned)5) == 5); 135 static_assert(__imag((_Complex unsigned)5) == 0); 136 137 /// Standalone complex expressions. 138 static_assert(__real((_Complex float){1.0, 3.0}) == 1.0, ""); 139 140 141 constexpr _Complex double D2 = {12}; 142 static_assert(__real(D2) == 12, ""); 143 static_assert(__imag(D2) == 0, ""); 144 145 constexpr _Complex int I3 = {15}; 146 static_assert(__real(I3) == 15, ""); 147 static_assert(__imag(I3) == 0, ""); 148 149 constexpr _Complex double Doubles[4] = {{1.0, 2.0}}; 150 static_assert(__real(Doubles[0]) == 1.0, ""); 151 static_assert(__imag(Doubles[0]) == 2.0, ""); 152 static_assert(__real(Doubles[1]) == 0.0, ""); 153 static_assert(__imag(Doubles[1]) == 0.0, ""); 154 static_assert(__real(Doubles[2]) == 0.0, ""); 155 static_assert(__imag(Doubles[2]) == 0.0, ""); 156 static_assert(__real(Doubles[3]) == 0.0, ""); 157 static_assert(__imag(Doubles[3]) == 0.0, ""); 158 159 static_assert(~(0.5 + 1.5j) == (0.5 + -1.5j), ""); 160 161 void func(void) { 162 __complex__ int arr; 163 _Complex int result; 164 int ii = 0; 165 int bb = 0; 166 /// The following line will call into the constant interpreter. 167 result = arr * ii; 168 } 169 170 constexpr _Complex float getComplexFloat() { 171 return {1,2}; 172 } 173 static_assert(__real(getComplexFloat()) == 1, ""); 174 static_assert(__imag(getComplexFloat()) == 2, ""); 175 176 constexpr auto GH55390 = 1 / 65536j; // both-note {{division by zero}} \ 177 // both-error {{constexpr variable 'GH55390' must be initialized by a constant expression}} 178 179 namespace CastToBool { 180 constexpr _Complex int F = {0, 1}; 181 static_assert(F, ""); 182 constexpr _Complex int F2 = {1, 0}; 183 static_assert(F2, ""); 184 constexpr _Complex int F3 = {0, 0}; 185 static_assert(!F3, ""); 186 187 constexpr _Complex unsigned char F4 = {0, 1}; 188 static_assert(F4, ""); 189 constexpr _Complex unsigned char F5 = {1, 0}; 190 static_assert(F5, ""); 191 constexpr _Complex unsigned char F6 = {0, 0}; 192 static_assert(!F6, ""); 193 194 constexpr _Complex float F7 = {0, 1}; 195 static_assert(F7, ""); 196 constexpr _Complex float F8 = {1, 0}; 197 static_assert(F8, ""); 198 constexpr _Complex double F9 = {0, 0}; 199 static_assert(!F9, ""); 200 } 201 202 namespace BinOps { 203 namespace Add { 204 constexpr _Complex float A = { 13.0, 2.0 }; 205 constexpr _Complex float B = { 2.0, 1.0 }; 206 constexpr _Complex float C = A + B; 207 static_assert(__real(C) == 15.0, ""); 208 static_assert(__imag(C) == 3.0, ""); 209 210 constexpr _Complex float D = B + A; 211 static_assert(__real(D) == 15.0, ""); 212 static_assert(__imag(D) == 3.0, ""); 213 214 constexpr _Complex unsigned int I1 = { 5, 10 }; 215 constexpr _Complex unsigned int I2 = { 40, 2 }; 216 constexpr _Complex unsigned int I3 = I1 + I2; 217 static_assert(__real(I3) == 45, ""); 218 static_assert(__imag(I3) == 12, ""); 219 220 static_assert(__real(A + 2.0) == 15, ""); 221 static_assert(__imag(A + 2.0) == 2, ""); 222 static_assert(__real(2.0 + A) == 15, ""); 223 static_assert(__imag(2.0 + A) == 2, ""); 224 225 static_assert(__real(D + 1) == 16, ""); 226 static_assert(__real(D + 1.0) == 16, ""); 227 constexpr _Complex double D2 = D + 3.0; 228 static_assert(__real(D2) == 18.0, ""); 229 static_assert(__imag(D2) == 3.0, ""); 230 constexpr _Complex double D3 = 3.0 + D; 231 static_assert(__real(D3) == 18.0, ""); 232 static_assert(__imag(D3) == 3.0, ""); 233 } 234 235 namespace Sub { 236 constexpr _Complex float A = { 13.0, 2.0 }; 237 constexpr _Complex float B = { 2.0, 1.0 }; 238 constexpr _Complex float C = A - B; 239 static_assert(__real(C) == 11.0, ""); 240 static_assert(__imag(C) == 1.0, ""); 241 static_assert(__real(A - 2.0) == 11, ""); 242 static_assert(__real(2.0 - A) == -11, ""); 243 244 constexpr _Complex float D = B - A; 245 static_assert(__real(D) == -11.0, ""); 246 static_assert(__imag(D) == -1.0, ""); 247 248 constexpr _Complex unsigned int I1 = { 5, 10 }; 249 constexpr _Complex unsigned int I2 = { 40, 2 }; 250 constexpr _Complex unsigned int I3 = I1 - I2; 251 static_assert(__real(I3) == -35, ""); 252 static_assert(__imag(I3) == 8, ""); 253 254 using Bobble = _Complex float; 255 constexpr _Complex float A_ = { 13.0, 2.0 }; 256 constexpr Bobble B_ = { 2.0, 1.0 }; 257 constexpr _Complex float D_ = A_ - B_; 258 static_assert(__real(D_) == 11.0, ""); 259 static_assert(__imag(D_) == 1.0, ""); 260 261 static_assert(__real(D - 1) == -12, ""); 262 static_assert(__real(D - 1.0) == -12, ""); 263 constexpr _Complex double D2 = D - 3.0; 264 static_assert(__real(D2) == -14.0, ""); 265 static_assert(__imag(D2) == -1.0, ""); 266 constexpr _Complex double D3 = 3.0 - D; 267 static_assert(__real(D3) == 14.0, ""); 268 static_assert(__imag(D3) == 1.0, ""); 269 } 270 271 } 272 273 namespace ZeroInit { 274 typedef _Complex float fcomplex; 275 typedef _Complex unsigned icomplex; 276 277 constexpr fcomplex test7 = fcomplex(); 278 static_assert(__real(test7) == 0.0f, ""); 279 static_assert(__imag(test7) == 0.0f, ""); 280 281 constexpr icomplex test8 = icomplex(); 282 static_assert(__real(test8) == 0, ""); 283 static_assert(__imag(test8) == 0, ""); 284 285 constexpr int ignored = (fcomplex(), 0); 286 } 287 288 namespace DeclRefCopy { 289 constexpr _Complex int ComplexInt = 42 + 24i; 290 291 constexpr _Complex int B = ComplexInt; 292 constexpr _Complex int ArrayOfComplexInt[4] = {ComplexInt, ComplexInt, ComplexInt, ComplexInt}; 293 static_assert(__real(ArrayOfComplexInt[0]) == 42, ""); 294 static_assert(__imag(ArrayOfComplexInt[0]) == 24, ""); 295 static_assert(__real(ArrayOfComplexInt[3]) == 42, ""); 296 static_assert(__imag(ArrayOfComplexInt[3]) == 24, ""); 297 298 constexpr int localComplexArray() { 299 _Complex int A = 42 + 24i; 300 _Complex int ArrayOfComplexInt[4] = {A, A, A, A}; 301 return __real(ArrayOfComplexInt[0]) + __imag(ArrayOfComplexInt[3]); 302 } 303 static_assert(localComplexArray() == (24 + 42), ""); 304 } 305 306 namespace Builtin { 307 constexpr _Complex float A = __builtin_complex(10.0f, 20.0f); 308 static_assert(__real(A) == 10, ""); 309 static_assert(__imag(A) == 20, ""); 310 311 constexpr _Complex double B = __builtin_complex(10.0, 20.0); 312 static_assert(__real(B) == 10, ""); 313 static_assert(__imag(B) == 20, ""); 314 315 316 constexpr _Complex float C = __builtin_complex(10.0f, 20.0); // both-error {{arguments are of different types}} 317 } 318 319 namespace Cmp { 320 static_assert((0.0 + 0.0j) == (0.0 + 0.0j)); 321 static_assert((0.0 + 0.0j) != (0.0 + 0.0j)); // both-error {{static assertion}} \ 322 // both-note {{evaluates to}} 323 324 static_assert((0.0 + 0.0j) == 0.0); 325 static_assert(0.0 == (0.0 + 0.0j)); 326 static_assert(0.0 == 0.0j); 327 static_assert((0.0 + 1.0j) != 0.0); 328 static_assert(1.0 != (0.0 + 0.0j)); 329 static_assert(0.0 != 1.0j); 330 331 // Walk around the complex plane stepping between angular differences and 332 // equality. 333 static_assert((1.0 + 0.0j) == (0.0 + 0.0j)); // both-error {{static assertion}} \ 334 // both-note {{evaluates to}} 335 static_assert((1.0 + 0.0j) == (1.0 + 0.0j)); 336 static_assert((1.0 + 1.0j) == (1.0 + 0.0j)); // both-error {{static assertion}} \ 337 // both-note {{evaluates to}} 338 static_assert((1.0 + 1.0j) == (1.0 + 1.0j)); 339 static_assert((0.0 + 1.0j) == (1.0 + 1.0j)); // both-error {{static assertion}} \ 340 // both-note {{evaluates to}} 341 static_assert((0.0 + 1.0j) == (0.0 + 1.0j)); 342 static_assert((-1.0 + 1.0j) == (0.0 + 1.0j)); // both-error {{static assertion}} \ 343 // both-note {{evaluates to}} 344 static_assert((-1.0 + 1.0j) == (-1.0 + 1.0j)); 345 static_assert((-1.0 + 0.0j) == (-1.0 + 1.0j)); // both-error {{static assertion}} \ 346 // both-note {{evaluates to}} 347 static_assert((-1.0 + 0.0j) == (-1.0 + 0.0j)); 348 static_assert((-1.0 - 1.0j) == (-1.0 + 0.0j)); // both-error {{static assertion}} \ 349 // both-note {{evaluates to}} 350 static_assert((-1.0 - 1.0j) == (-1.0 - 1.0j)); 351 static_assert((0.0 - 1.0j) == (-1.0 - 1.0j)); // both-error {{static assertion}} \ 352 // both-note {{evaluates to}} 353 static_assert((0.0 - 1.0j) == (0.0 - 1.0j)); 354 static_assert((1.0 - 1.0j) == (0.0 - 1.0j)); // both-error {{static assertion}} \ 355 // both-note {{evaluates to}} 356 static_assert((1.0 - 1.0j) == (1.0 - 1.0j)); 357 358 /// Make sure these are rejected before reaching the constexpr interpreter. 359 static_assert((0.0 + 0.0j) & (0.0 + 0.0j)); // both-error {{invalid operands to binary expression}} 360 static_assert((0.0 + 0.0j) | (0.0 + 0.0j)); // both-error {{invalid operands to binary expression}} 361 static_assert((0.0 + 0.0j) < (0.0 + 0.0j)); // both-error {{invalid operands to binary expression}} 362 static_assert((0.0 + 0.0j) > (0.0 + 0.0j)); // both-error {{invalid operands to binary expression}} 363 static_assert((0.0 + 0.0j) ^ (0.0 + 0.0j)); // both-error {{invalid operands to binary expression}} 364 } 365 366 /// From test/SemaCXX/constant-expression-cxx11.cpp 367 /// 368 /// Some of the diagnostics we emit are different than the one of the 369 /// current interpreter. 370 /// 371 /// FIXME: For the '&test3 + 1' test, we are _not_ creating an explicit pointer variable 372 /// anywhere and so the &test3+1 is the same as __imag(test3) for us. 373 namespace ComplexConstexpr { 374 constexpr _Complex float test1 = {}; 375 constexpr _Complex float test2 = {1}; 376 constexpr _Complex double test3 = {1,2}; 377 constexpr _Complex int test4 = {4}; 378 constexpr _Complex int test5 = 4; 379 constexpr _Complex int test6 = {5,6}; 380 typedef _Complex float fcomplex; 381 constexpr fcomplex test7 = fcomplex(); 382 383 constexpr const double &t2r = __real test3; 384 constexpr const double &t2i = __imag test3; 385 static_assert(&t2r + 1 == &t2i, ""); 386 static_assert(t2r == 1.0, ""); 387 static_assert(t2i == 2.0, ""); 388 constexpr const double *t2p = &t2r; 389 static_assert(t2p[-1] == 0.0, ""); // both-error {{constant expr}} \ 390 // both-note {{cannot refer to element -1 of array of 2 elements}} 391 static_assert(t2p[0] == 1.0, ""); 392 static_assert(t2p[1] == 2.0, ""); 393 static_assert(t2p[2] == 0.0, ""); // both-error {{constant expr}} \ 394 // both-note {{one-past-the-end pointer}} 395 static_assert(t2p[3] == 0.0, ""); // both-error {{constant expr}} \ 396 // both-note {{cannot refer to element 3 of array of 2 elements}} 397 constexpr _Complex float *p = 0; 398 constexpr float pr = __real *p; // both-error {{constant expr}} \ 399 // ref-note {{cannot access real component of null}} \ 400 // expected-note {{read of dereferenced null pointer}} 401 constexpr float pi = __imag *p; // both-error {{constant expr}} \ 402 // ref-note {{cannot access imaginary component of null}} 403 constexpr const _Complex double *q = &test3 + 1; 404 constexpr double qr = __real *q; // ref-error {{constant expr}} \ 405 // ref-note {{cannot access real component of pointer past the end}} 406 constexpr double qi = __imag *q; // both-error {{constant expr}} \ 407 // ref-note {{cannot access imaginary component of pointer past the end}} \ 408 // expected-note {{read of dereferenced one-past-the-end pointer}} 409 410 static_assert(__real test6 == 5, ""); 411 static_assert(__imag test6 == 6, ""); 412 static_assert(&__imag test6 == &__real test6 + 1, ""); 413 } 414