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