xref: /llvm-project/clang/test/AST/ByteCode/intap.cpp (revision 62e7b59f10d9af809dd54fc064e2f60f0b48938c)
1*62e7b59fSTimm Bäder // RUN: %clang_cc1 -fexperimental-new-constant-interpreter -fms-extensions -std=c++11 -verify=expected,both %s
2*62e7b59fSTimm Bäder // RUN: %clang_cc1 -fexperimental-new-constant-interpreter -fms-extensions -std=c++20 -verify=expected,both %s
3*62e7b59fSTimm Bäder // RUN: %clang_cc1 -std=c++11 -fms-extensions -verify=ref,both %s
4*62e7b59fSTimm Bäder // RUN: %clang_cc1 -std=c++20 -fms-extensions -verify=ref,both %s
5a07aba5dSTimm Baeder 
6a07aba5dSTimm Baeder 
7a07aba5dSTimm Baeder using MaxBitInt = _BitInt(128);
8a07aba5dSTimm Baeder #define INT_MIN (~__INT_MAX__)
9a07aba5dSTimm Baeder 
10a07aba5dSTimm Baeder constexpr _BitInt(2) A = 0;
11a07aba5dSTimm Baeder constexpr _BitInt(2) B = A + 1;
12*62e7b59fSTimm Bäder constexpr _BitInt(2) C = B + 1; // both-warning {{from 2 to -2}}
13a07aba5dSTimm Baeder static_assert(C == -2, "");
14*62e7b59fSTimm Bäder static_assert(C - B == A, ""); // both-error {{not an integral constant expression}} \
15*62e7b59fSTimm Bäder                                // both-note {{value -3 is outside the range of representable values}}
16a07aba5dSTimm Baeder 
17a07aba5dSTimm Baeder static_assert(B - 1 == 0, "");
18a07aba5dSTimm Baeder 
19a07aba5dSTimm Baeder constexpr MaxBitInt A_ = 0;
20a07aba5dSTimm Baeder constexpr MaxBitInt B_ = A_ + 1;
21a07aba5dSTimm Baeder static_assert(B_ == 1, "");
22a07aba5dSTimm Baeder 
23a07aba5dSTimm Baeder constexpr MaxBitInt BitIntZero{};
24a07aba5dSTimm Baeder static_assert(BitIntZero == 0, "");
25a07aba5dSTimm Baeder constexpr unsigned _BitInt(128) UBitIntZero{};
26a07aba5dSTimm Baeder static_assert(UBitIntZero == 0, "");
27a07aba5dSTimm Baeder 
28a07aba5dSTimm Baeder constexpr _BitInt(2) BitIntZero2{};
29a07aba5dSTimm Baeder static_assert(BitIntZero2 == 0, "");
30a07aba5dSTimm Baeder constexpr unsigned _BitInt(1) UBitIntZero1{};
31a07aba5dSTimm Baeder static_assert(UBitIntZero1 == 0, "");
32a07aba5dSTimm Baeder 
33a07aba5dSTimm Baeder constexpr unsigned _BitInt(2) BI1 = 3u;
34a07aba5dSTimm Baeder static_assert(BI1 == 3, "");
35a07aba5dSTimm Baeder 
36a07aba5dSTimm Baeder constexpr _BitInt(4) MulA = 5;
37a07aba5dSTimm Baeder constexpr _BitInt(4) MulB = 7;
38*62e7b59fSTimm Bäder static_assert(MulA * MulB == 50, ""); // both-error {{not an integral constant expression}} \
39*62e7b59fSTimm Bäder                                       // both-note {{value 35 is outside the range of representable values of type '_BitInt(4)'}}
40a07aba5dSTimm Baeder static_assert(MulA * 5 == 25, "");
41a07aba5dSTimm Baeder static_assert(-1 * MulB == -7, "");
42a07aba5dSTimm Baeder 
43a07aba5dSTimm Baeder 
44a07aba5dSTimm Baeder constexpr _BitInt(4) DivA = 2;
45a07aba5dSTimm Baeder constexpr _BitInt(2) DivB = 1;
46a07aba5dSTimm Baeder static_assert(DivA / DivB == 2, "");
47a07aba5dSTimm Baeder 
48*62e7b59fSTimm Bäder constexpr _BitInt(4) DivC = DivA / 0; // both-error {{must be initialized by a constant expression}} \
49*62e7b59fSTimm Bäder                                       // both-note {{division by zero}}
50a07aba5dSTimm Baeder 
51a07aba5dSTimm Baeder constexpr _BitInt(7) RemA = 47;
52a07aba5dSTimm Baeder constexpr _BitInt(6) RemB = 9;
53a07aba5dSTimm Baeder static_assert(RemA % RemB == 2, "");
54*62e7b59fSTimm Bäder static_assert(RemA % 0 == 1, ""); // both-error {{not an integral constant expression}} \
55*62e7b59fSTimm Bäder                                   // both-note {{division by zero}}
56a07aba5dSTimm Baeder 
57a07aba5dSTimm Baeder constexpr _BitInt(32) bottom = -1;
58a07aba5dSTimm Baeder constexpr _BitInt(32) top = INT_MIN;
59*62e7b59fSTimm Bäder constexpr _BitInt(32) nope = top / bottom;  // both-error {{must be initialized by a constant expression}} \
60*62e7b59fSTimm Bäder                                             // both-note {{value 2147483648 is outside the range}}
61*62e7b59fSTimm Bäder constexpr _BitInt(32) noooo = top % bottom; // both-error {{must be initialized by a constant expression}} \
62*62e7b59fSTimm Bäder                                             // both-note {{value 2147483648 is outside the range}}
63a07aba5dSTimm Baeder 
64a07aba5dSTimm Baeder namespace APCast {
65a07aba5dSTimm Baeder   constexpr _BitInt(10) A = 1;
66a07aba5dSTimm Baeder   constexpr _BitInt(11) B = A;
67a07aba5dSTimm Baeder   static_assert(B == 1, "");
68a07aba5dSTimm Baeder   constexpr _BitInt(16) B2 = A;
69a07aba5dSTimm Baeder   static_assert(B2 == 1, "");
70a07aba5dSTimm Baeder   constexpr _BitInt(32) B3 = A;
71a07aba5dSTimm Baeder   static_assert(B3 == 1, "");
72a07aba5dSTimm Baeder   constexpr unsigned _BitInt(32) B4 = A;
73a07aba5dSTimm Baeder   static_assert(B4 == 1, "");
74a07aba5dSTimm Baeder }
75a07aba5dSTimm Baeder 
76a07aba5dSTimm Baeder #ifdef __SIZEOF_INT128__
77a07aba5dSTimm Baeder typedef __int128 int128_t;
78a07aba5dSTimm Baeder typedef unsigned __int128 uint128_t;
79a07aba5dSTimm Baeder static const __uint128_t UINT128_MAX =__uint128_t(__int128_t(-1L));
80a07aba5dSTimm Baeder static_assert(UINT128_MAX == -1, "");
81*62e7b59fSTimm Bäder static_assert(UINT128_MAX == 1, ""); // both-error {{static assertion failed}} \
82*62e7b59fSTimm Bäder                                      // both-note {{'340282366920938463463374607431768211455 == 1'}}
83a07aba5dSTimm Baeder 
84a07aba5dSTimm Baeder static const __int128_t INT128_MAX = UINT128_MAX >> (__int128_t)1;
85a07aba5dSTimm Baeder static_assert(INT128_MAX != 0, "");
86*62e7b59fSTimm Bäder static_assert(INT128_MAX == 0, ""); // both-error {{failed}} \
87*62e7b59fSTimm Bäder                                     // both-note {{evaluates to '170141183460469231731687303715884105727 == 0'}}
88a07aba5dSTimm Baeder static const __int128_t INT128_MIN = -INT128_MAX - 1;
89a07aba5dSTimm Baeder 
90c81d6665STimm Baeder 
91c81d6665STimm Baeder namespace PointerArithmeticOverflow {
92c81d6665STimm Baeder   int n;
93*62e7b59fSTimm Bäder   constexpr int *p = (&n + 1) + (unsigned __int128)-1; // both-error {{constant expression}} \
94*62e7b59fSTimm Bäder                                                        // both-note {{cannot refer to element 3402}}
95c81d6665STimm Baeder }
96c81d6665STimm Baeder 
97a07aba5dSTimm Baeder namespace i128 {
98a07aba5dSTimm Baeder 
99a07aba5dSTimm Baeder   constexpr int128_t I128_1 = 12;
100a07aba5dSTimm Baeder   static_assert(I128_1 == 12, "");
101a07aba5dSTimm Baeder   static_assert(I128_1 != 10, "");
102*62e7b59fSTimm Bäder   static_assert(I128_1 != 12, ""); // both-error{{failed}} \
103*62e7b59fSTimm Bäder                                    // both-note{{evaluates to}}
104a07aba5dSTimm Baeder 
105a07aba5dSTimm Baeder   static const __uint128_t UINT128_MAX =__uint128_t(__int128_t(-1L));
106a07aba5dSTimm Baeder   static_assert(UINT128_MAX == -1, "");
107*62e7b59fSTimm Bäder   static_assert(UINT128_MAX == 1, ""); // both-error {{static assertion failed}} \
108*62e7b59fSTimm Bäder                                        // both-note {{'340282366920938463463374607431768211455 == 1'}}
109a07aba5dSTimm Baeder 
110a07aba5dSTimm Baeder   constexpr uint128_t TooMuch = UINT128_MAX * 2;
111a07aba5dSTimm Baeder 
112a07aba5dSTimm Baeder   static const __int128_t INT128_MAX = UINT128_MAX >> (__int128_t)1;
113a07aba5dSTimm Baeder   static_assert(INT128_MAX != 0, "");
114*62e7b59fSTimm Bäder   static_assert(INT128_MAX == 0, ""); // both-error {{failed}} \
115*62e7b59fSTimm Bäder                                       // both-note {{evaluates to '170141183460469231731687303715884105727 == 0'}}
116a07aba5dSTimm Baeder 
117*62e7b59fSTimm Bäder   constexpr int128_t TooMuch2 = INT128_MAX * INT128_MAX; // both-error {{must be initialized by a constant expression}} \
118*62e7b59fSTimm Bäder                                                          // both-note {{value 28948022309329048855892746252171976962977213799489202546401021394546514198529 is outside the range of representable}}
119a07aba5dSTimm Baeder 
120a07aba5dSTimm Baeder   static const __int128_t INT128_MIN = -INT128_MAX - 1;
121*62e7b59fSTimm Bäder   constexpr __int128 A = INT128_MAX + 1; // both-error {{must be initialized by a constant expression}} \
122*62e7b59fSTimm Bäder                                          // both-note {{value 170141183460469231731687303715884105728 is outside the range}}
123a07aba5dSTimm Baeder   constexpr int128_t Two = (int128_t)1 << 1ul;
124a07aba5dSTimm Baeder   static_assert(Two == 2, "");
125a07aba5dSTimm Baeder   static_assert(Two, "");
126a07aba5dSTimm Baeder   constexpr bool CastedToBool = Two;
127a07aba5dSTimm Baeder   static_assert(CastedToBool, "");
128a07aba5dSTimm Baeder 
129a07aba5dSTimm Baeder   constexpr uint128_t AllOnes = ~static_cast<uint128_t>(0);
130a07aba5dSTimm Baeder   static_assert(AllOnes == UINT128_MAX, "");
131a07aba5dSTimm Baeder 
132a07aba5dSTimm Baeder   constexpr uint128_t i128Zero{};
133a07aba5dSTimm Baeder   static_assert(i128Zero == 0, "");
134a07aba5dSTimm Baeder   constexpr uint128_t ui128Zero{};
135a07aba5dSTimm Baeder   static_assert(ui128Zero == 0, "");
136a07aba5dSTimm Baeder 
137a07aba5dSTimm Baeder 
138a07aba5dSTimm Baeder   enum LargeEnum : signed __int128 {
139a07aba5dSTimm Baeder     LV = (signed __int128)1 << 127,
140a07aba5dSTimm Baeder   };
141a07aba5dSTimm Baeder 
142a07aba5dSTimm Baeder   constexpr LargeEnum F = LV;
143a07aba5dSTimm Baeder   static_assert(F ==  (signed __int128)1 << 127, "");
144a07aba5dSTimm Baeder   constexpr LargeEnum getLargeEnum() {
145a07aba5dSTimm Baeder     return LV;
146a07aba5dSTimm Baeder   }
147a07aba5dSTimm Baeder   static_assert(getLargeEnum() ==  (signed __int128)1 << 127, "");
148a07aba5dSTimm Baeder 
149a07aba5dSTimm Baeder 
150a07aba5dSTimm Baeder 
151a07aba5dSTimm Baeder #if __cplusplus >= 201402L
152a07aba5dSTimm Baeder   template <typename T>
153a07aba5dSTimm Baeder   constexpr T CastFrom(__int128_t A) {
154a07aba5dSTimm Baeder     T B = (T)A;
155a07aba5dSTimm Baeder     return B;
156a07aba5dSTimm Baeder   }
157a07aba5dSTimm Baeder   static_assert(CastFrom<char>(12) == 12, "");
158a07aba5dSTimm Baeder   static_assert(CastFrom<unsigned char>(12) == 12, "");
159a07aba5dSTimm Baeder   static_assert(CastFrom<long>(12) == 12, "");
160a07aba5dSTimm Baeder   static_assert(CastFrom<unsigned short>(12) == 12, "");
161a07aba5dSTimm Baeder   static_assert(CastFrom<int128_t>(12) == 12, "");
162a07aba5dSTimm Baeder   static_assert(CastFrom<float>(12) == 12, "");
163a07aba5dSTimm Baeder   static_assert(CastFrom<double>(12) == 12, "");
164a07aba5dSTimm Baeder   static_assert(CastFrom<long double>(12) == 12, "");
165a07aba5dSTimm Baeder 
166a07aba5dSTimm Baeder   static_assert(CastFrom<char>(AllOnes) == -1, "");
167a07aba5dSTimm Baeder   static_assert(CastFrom<unsigned char>(AllOnes) == 0xFF, "");
168a07aba5dSTimm Baeder   static_assert(CastFrom<long>(AllOnes) == -1, "");
169a07aba5dSTimm Baeder   static_assert(CastFrom<unsigned short>(AllOnes) == 0xFFFF, "");
170a07aba5dSTimm Baeder   static_assert(CastFrom<int>(AllOnes) == -1, "");
171a07aba5dSTimm Baeder   static_assert(CastFrom<int128_t>(AllOnes) == -1, "");
172a07aba5dSTimm Baeder   static_assert(CastFrom<uint128_t>(AllOnes) == AllOnes, "");
173a07aba5dSTimm Baeder 
174a07aba5dSTimm Baeder   template <typename T>
175a07aba5dSTimm Baeder   constexpr __int128 CastTo(T A) {
176a07aba5dSTimm Baeder     int128_t B = (int128_t)A;
177a07aba5dSTimm Baeder     return B;
178a07aba5dSTimm Baeder   }
179a07aba5dSTimm Baeder   static_assert(CastTo<char>(12) == 12, "");
180a07aba5dSTimm Baeder   static_assert(CastTo<unsigned char>(12) == 12, "");
181a07aba5dSTimm Baeder   static_assert(CastTo<long>(12) == 12, "");
182a07aba5dSTimm Baeder   static_assert(CastTo<unsigned long long>(12) == 12, "");
183a07aba5dSTimm Baeder   static_assert(CastTo<float>(12) == 12, "");
184a07aba5dSTimm Baeder   static_assert(CastTo<double>(12) == 12, "");
185a07aba5dSTimm Baeder   static_assert(CastTo<long double>(12) == 12, "");
186a07aba5dSTimm Baeder #endif
187a07aba5dSTimm Baeder 
188*62e7b59fSTimm Bäder   constexpr int128_t Error = __LDBL_MAX__; // both-warning {{implicit conversion of out of range value}} \
189*62e7b59fSTimm Bäder                                            // both-error {{must be initialized by a constant expression}} \
190*62e7b59fSTimm Bäder                                            // both-note {{is outside the range of representable values of type}}
191a07aba5dSTimm Baeder 
192a07aba5dSTimm Baeder   constexpr uint128_t Zero = 0;
193a07aba5dSTimm Baeder   static_assert((Zero -1) == -1, "");
194a07aba5dSTimm Baeder   constexpr int128_t Five = 5;
195a07aba5dSTimm Baeder   static_assert(Five - Zero == Five, "");
196a07aba5dSTimm Baeder 
197*62e7b59fSTimm Bäder   constexpr int128_t Sub1 = INT128_MIN - 1; // both-error {{must be initialized by a constant expression}} \
198*62e7b59fSTimm Bäder                                             // both-note {{-170141183460469231731687303715884105729 is outside the range}}
199a07aba5dSTimm Baeder }
200a07aba5dSTimm Baeder 
201a07aba5dSTimm Baeder namespace AddSubOffset {
202a07aba5dSTimm Baeder   constexpr __int128 A = 1;
203a07aba5dSTimm Baeder   constexpr int arr[] = {1,2,3};
204a07aba5dSTimm Baeder   constexpr const int *P = arr + A;
205a07aba5dSTimm Baeder   static_assert(*P == 2, "");
206a07aba5dSTimm Baeder   constexpr const int *P2 = P - A;
207a07aba5dSTimm Baeder   static_assert(*P2 == 1,"");
208a07aba5dSTimm Baeder }
209a07aba5dSTimm Baeder 
210a07aba5dSTimm Baeder namespace Bitfields {
211a07aba5dSTimm Baeder   struct S1 {
212a07aba5dSTimm Baeder     unsigned _BitInt(128) a : 2;
213a07aba5dSTimm Baeder   };
214*62e7b59fSTimm Bäder   constexpr S1 s1{100}; // both-warning {{changes value from 100 to 0}}
215a07aba5dSTimm Baeder   constexpr S1 s12{3};
216a07aba5dSTimm Baeder   static_assert(s12.a == 3, "");
217a07aba5dSTimm Baeder 
218a07aba5dSTimm Baeder   struct S2 {
219a07aba5dSTimm Baeder     unsigned __int128 a : 2;
220a07aba5dSTimm Baeder   };
221*62e7b59fSTimm Bäder   constexpr S2 s2{100}; // both-warning {{changes value from 100 to 0}}
222a07aba5dSTimm Baeder }
223a07aba5dSTimm Baeder 
224a07aba5dSTimm Baeder namespace BitOps {
225a07aba5dSTimm Baeder   constexpr unsigned __int128 UZero = 0;
226a07aba5dSTimm Baeder   constexpr unsigned __int128 Max = ~UZero;
227a07aba5dSTimm Baeder   static_assert(Max == ~0, "");
228a07aba5dSTimm Baeder   static_assert((Max & 0) == 0, "");
229a07aba5dSTimm Baeder   static_assert((UZero | 0) == 0, "");
230a07aba5dSTimm Baeder   static_assert((Max ^ Max) == 0, "");
231a07aba5dSTimm Baeder   static_assert((Max & 1) == 1, "");
232a07aba5dSTimm Baeder   static_assert((UZero | 1) == 1, "");
233a07aba5dSTimm Baeder   static_assert((Max ^ UZero) == Max, "");
234a07aba5dSTimm Baeder }
235a07aba5dSTimm Baeder 
236a07aba5dSTimm Baeder namespace IncDec {
237a07aba5dSTimm Baeder #if __cplusplus >= 201402L
238a07aba5dSTimm Baeder   constexpr int128_t maxPlus1(bool Pre) {
239a07aba5dSTimm Baeder     int128_t a = INT128_MAX;
240a07aba5dSTimm Baeder 
241a07aba5dSTimm Baeder     if (Pre)
242*62e7b59fSTimm Bäder       ++a; // both-note {{value 170141183460469231731687303715884105728 is outside the range}}
243a07aba5dSTimm Baeder     else
244*62e7b59fSTimm Bäder       a++; // both-note {{value 170141183460469231731687303715884105728 is outside the range}}
245a07aba5dSTimm Baeder     return a;
246a07aba5dSTimm Baeder   }
247*62e7b59fSTimm Bäder   static_assert(maxPlus1(true) == 0, ""); // both-error {{not an integral constant expression}} \
248*62e7b59fSTimm Bäder                                           // both-note {{in call to}}
249*62e7b59fSTimm Bäder   static_assert(maxPlus1(false) == 0, ""); // both-error {{not an integral constant expression}} \
250*62e7b59fSTimm Bäder                                            // both-note {{in call to}}
251a07aba5dSTimm Baeder 
252a07aba5dSTimm Baeder   constexpr int128_t inc1(bool Pre) {
253a07aba5dSTimm Baeder     int128_t A = 0;
254a07aba5dSTimm Baeder     if (Pre)
255a07aba5dSTimm Baeder       ++A;
256a07aba5dSTimm Baeder     else
257a07aba5dSTimm Baeder       A++;
258a07aba5dSTimm Baeder     return A;
259a07aba5dSTimm Baeder   }
260a07aba5dSTimm Baeder   static_assert(inc1(true) == 1, "");
261a07aba5dSTimm Baeder   static_assert(inc1(false) == 1, "");
262a07aba5dSTimm Baeder 
263a07aba5dSTimm Baeder   constexpr int128_t dec1(bool Pre) {
264a07aba5dSTimm Baeder     int128_t A = 2;
265a07aba5dSTimm Baeder     if (Pre)
266a07aba5dSTimm Baeder       --A;
267a07aba5dSTimm Baeder     else
268a07aba5dSTimm Baeder       A--;
269a07aba5dSTimm Baeder     return A;
270a07aba5dSTimm Baeder   }
271a07aba5dSTimm Baeder   static_assert(dec1(true) == 1, "");
272a07aba5dSTimm Baeder   static_assert(dec1(false) == 1, "");
273a07aba5dSTimm Baeder #endif
274a07aba5dSTimm Baeder }
275a07aba5dSTimm Baeder 
276a07aba5dSTimm Baeder #endif
277