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