xref: /llvm-project/clang/test/AST/ByteCode/shifts.cpp (revision 2503a6659621e27e6b4c5946c3acff7a5b9dadca)
1 // RUN: %clang_cc1 -fexperimental-new-constant-interpreter -std=c++20 -verify=expected,all %s
2 // RUN: %clang_cc1 -fexperimental-new-constant-interpreter -std=c++17 -verify=cxx17,all %s
3 // RUN: %clang_cc1 -fexperimental-new-constant-interpreter -std=c++17 -verify=cxx17,all -triple armv8 %s
4 // RUN: %clang_cc1 -std=c++20 -verify=ref,all %s
5 // RUN: %clang_cc1 -std=c++17 -verify=ref-cxx17,all %s
6 // RUN: %clang_cc1 -std=c++17 -verify=ref-cxx17,all -triple armv8 %s
7 
8 #define INT_MIN (~__INT_MAX__)
9 
10 constexpr int a = -1 >> 3;
11 
12 namespace shifts {
13   constexpr void test() { // ref-error {{constexpr function never produces a constant expression}} \
14                           // ref-cxx17-error {{constexpr function never produces a constant expression}} \
15                           // expected-error {{constexpr function never produces a constant expression}} \
16                           // cxx17-error {{constexpr function never produces a constant expression}} \
17 
18     char c; // cxx17-warning {{uninitialized variable}} \
19             // ref-cxx17-warning {{uninitialized variable}}
20 
21     c = 0 << 0;
22     c = 0 << 1;
23     c = 1 << 0;
24     c = 1 << -0;
25     c = 1 >> -0;
26     c = 1 << -1; // all-warning {{shift count is negative}} \
27                  // all-note {{negative shift count -1}}
28 
29     c = 1 >> -1; // expected-warning {{shift count is negative}} \
30                  // cxx17-warning {{shift count is negative}} \
31                  // ref-warning {{shift count is negative}} \
32                  // ref-cxx17-warning {{shift count is negative}}
33     c = 1 << (unsigned)-1; // all-warning {{shift count >= width of type}} \
34                            // all-warning {{implicit conversion from 'int' to 'char' changes value from -2147483648 to 0}}
35     c = 1 >> (unsigned)-1; // expected-warning {{shift count >= width of type}} \
36                            // cxx17-warning {{shift count >= width of type}} \
37                            // ref-warning {{shift count >= width of type}} \
38                            // ref-cxx17-warning {{shift count >= width of type}}
39     c = 1 << c;
40     c <<= 0;
41     c >>= 0;
42     c <<= 1;
43     c >>= 1;
44     c <<= -1; // expected-warning {{shift count is negative}} \
45               // cxx17-warning {{shift count is negative}} \
46               // ref-warning {{shift count is negative}} \
47               // ref-cxx17-warning {{shift count is negative}}
48     c >>= -1; // expected-warning {{shift count is negative}} \
49               // cxx17-warning {{shift count is negative}} \
50               // ref-warning {{shift count is negative}} \
51               // ref-cxx17-warning {{shift count is negative}}
52     c <<= 999999; // expected-warning {{shift count >= width of type}} \
53                   // cxx17-warning {{shift count >= width of type}} \
54                   // ref-warning {{shift count >= width of type}} \
55                   // ref-cxx17-warning {{shift count >= width of type}}
56     c >>= 999999; // expected-warning {{shift count >= width of type}} \
57                   // cxx17-warning {{shift count >= width of type}} \
58                   // ref-warning {{shift count >= width of type}} \
59                   // ref-cxx17-warning {{shift count >= width of type}}
60     c <<= __CHAR_BIT__; // expected-warning {{shift count >= width of type}} \
61                         // cxx17-warning {{shift count >= width of type}} \
62                         // ref-warning {{shift count >= width of type}} \
63                         // ref-cxx17-warning {{shift count >= width of type}}
64     c >>= __CHAR_BIT__; // expected-warning {{shift count >= width of type}} \
65                         // cxx17-warning {{shift count >= width of type}} \
66                         // ref-warning {{shift count >= width of type}} \
67                         // ref-cxx17-warning {{shift count >= width of type}}
68     c <<= __CHAR_BIT__+1; // expected-warning {{shift count >= width of type}} \
69                           // cxx17-warning {{shift count >= width of type}} \
70                           // ref-warning {{shift count >= width of type}} \
71                           // ref-cxx17-warning {{shift count >= width of type}}
72     c >>= __CHAR_BIT__+1; // expected-warning {{shift count >= width of type}} \
73                           // cxx17-warning {{shift count >= width of type}} \
74                           // ref-warning {{shift count >= width of type}} \
75                           // ref-cxx17-warning {{shift count >= width of type}}
76     (void)((long)c << __CHAR_BIT__);
77 
78     int i; // cxx17-warning {{uninitialized variable}} \
79            // ref-cxx17-warning {{uninitialized variable}}
80     i = 1 << (__INT_WIDTH__ - 2);
81     i = 2 << (__INT_WIDTH__ - 1); // cxx17-warning {{bits to represent, but 'int' only has}} \
82                                   // ref-cxx17-warning {{bits to represent, but 'int' only has}}
83     i = 1 << (__INT_WIDTH__ - 1); // cxx17-warning-not {{sets the sign bit of the shift expression}}
84     i = -1 << (__INT_WIDTH__ - 1); // cxx17-warning {{shifting a negative signed value is undefined}} \
85                                    // ref-cxx17-warning {{shifting a negative signed value is undefined}}
86     i = -1 << 0; // cxx17-warning {{shifting a negative signed value is undefined}} \
87                  // ref-cxx17-warning {{shifting a negative signed value is undefined}}
88     i = 0 << (__INT_WIDTH__ - 1);
89     i = (char)1 << (__INT_WIDTH__ - 2);
90 
91     unsigned u; // cxx17-warning {{uninitialized variable}} \
92                 // ref-cxx17-warning {{uninitialized variable}}
93     u = 1U << (__INT_WIDTH__ - 1);
94     u = 5U << (__INT_WIDTH__ - 1);
95 
96     long long int lli; // cxx17-warning {{uninitialized variable}} \
97                        // ref-cxx17-warning {{uninitialized variable}}
98     lli = INT_MIN << 2; // cxx17-warning {{shifting a negative signed value is undefined}} \
99                         // ref-cxx17-warning {{shifting a negative signed value is undefined}}
100     lli = 1LL << (sizeof(long long) * __CHAR_BIT__ - 2);
101   }
102 
103   static_assert(1 << 4 == 16, "");
104   constexpr unsigned m = 2 >> 1;
105   static_assert(m == 1, "");
106   constexpr unsigned char c = 0 << 8;
107   static_assert(c == 0, "");
108   static_assert(true << 1, "");
109   static_assert(1 << (__INT_WIDTH__ +1) == 0, "");  // expected-error {{not an integral constant expression}} \
110                                                     // expected-note {{>= width of type 'int'}} \
111                                                     // cxx17-error {{not an integral constant expression}} \
112                                                     // cxx17-note {{>= width of type 'int'}} \
113                                                     // ref-error {{not an integral constant expression}} \
114                                                     // ref-note {{>= width of type 'int'}} \
115                                                     // ref-cxx17-error {{not an integral constant expression}} \
116                                                     // ref-cxx17-note {{>= width of type 'int'}}
117 
118   constexpr int i1 = 1 << -1; // expected-error {{must be initialized by a constant expression}} \
119                               // expected-note {{negative shift count -1}} \
120                               // cxx17-error {{must be initialized by a constant expression}} \
121                               // cxx17-note {{negative shift count -1}} \
122                               // ref-error {{must be initialized by a constant expression}} \
123                               // ref-note {{negative shift count -1}} \
124                               // ref-cxx17-error {{must be initialized by a constant expression}} \
125                               // ref-cxx17-note {{negative shift count -1}}
126 
127   constexpr int i2 = 1 << (__INT_WIDTH__ + 1); // expected-error {{must be initialized by a constant expression}} \
128                                                // expected-note {{>= width of type}} \
129                                                // cxx17-error {{must be initialized by a constant expression}} \
130                                                // cxx17-note {{>= width of type}} \
131                                                // ref-error {{must be initialized by a constant expression}} \
132                                                // ref-note {{>= width of type}} \
133                                                // ref-cxx17-error {{must be initialized by a constant expression}} \
134                                                // ref-cxx17-note {{>= width of type}}
135 
136   constexpr char c2 = 1;
137   constexpr int i3 = c2 << (__CHAR_BIT__ + 1); // Not ill-formed
138 
139   /// The purpose of these few lines is to test that we can shift more bits
140   /// than an unsigned *of the host* has. There was a bug where we casted
141   /// to host-unsigned. However, we cannot query what a host-unsigned even is
142   /// here, so only test this on platforms where `sizeof(long long) > sizeof(unsigned)`.
143   constexpr long long int L = 1;
144   constexpr signed int R = (sizeof(unsigned) * 8) + 1;
145   constexpr decltype(L) M  = (R > 32 && R < 64) ?  L << R : 0;
146   constexpr decltype(L) M2 = (R > 32 && R < 64) ?  L >> R : 0;
147 
148 
149   constexpr int signedShift() { // cxx17-error {{never produces a constant expression}} \
150                                 // ref-cxx17-error {{never produces a constant expression}}
151     return 1024 << 31; // cxx17-warning {{signed shift result}} \
152                        // ref-cxx17-warning {{signed shift result}} \
153                        // cxx17-note {{signed left shift discards bits}} \
154                        // ref-cxx17-note {{signed left shift discards bits}}
155   }
156 
157   constexpr int negativeShift() { // cxx17-error {{never produces a constant expression}} \
158                                   // ref-cxx17-error {{never produces a constant expression}}
159     return -1 << 2; // cxx17-warning {{shifting a negative signed value is undefined}} \
160                     // ref-cxx17-warning {{shifting a negative signed value is undefined}} \
161                     // cxx17-note {{left shift of negative value -1}} \
162                     // ref-cxx17-note {{left shift of negative value -1}}
163   }
164 
165   constexpr int foo(int a) {
166     return -a << 2; // cxx17-note {{left shift of negative value -10}} \
167                     // ref-cxx17-note {{left shift of negative value -10}} \
168                     // cxx17-note {{left shift of negative value -2}} \
169                     // ref-cxx17-note {{left shift of negative value -2}}
170   }
171   static_assert(foo(10)); // cxx17-error {{not an integral constant expression}} \
172                           // cxx17-note {{in call to 'foo(10)'}} \
173                           // ref-cxx17-error {{not an integral constant expression}} \
174                           // ref-cxx17-note {{in call to 'foo(10)'}}
175 
176   constexpr int a = -2;
177   static_assert(foo(a));
178   static_assert(foo(-a)); // cxx17-error {{not an integral constant expression}} \
179                           // cxx17-note {{in call to 'foo(2)'}} \
180                           // ref-cxx17-error {{not an integral constant expression}} \
181                           // ref-cxx17-note {{in call to 'foo(2)'}}
182 };
183 
184 namespace LongInt {
185   constexpr int f() {
186     int a = 1;
187     a <<= (long)0;
188     return 1;
189   }
190   static_assert(f() == 1, "");
191 };
192 
193 enum shiftof {
194     X = (1<<-29), // all-error {{expression is not an integral constant expression}} \
195                   // all-note {{negative shift count -29}}
196 
197     X2 = (-1<<29), // cxx17-error {{expression is not an integral constant expression}} \
198                    // cxx17-note {{left shift of negative value -1}} \
199                    // ref-cxx17-error {{expression is not an integral constant expression}} \
200                    // ref-cxx17-note {{left shift of negative value -1}}
201 
202     X3 = (1<<32) // all-error {{expression is not an integral constant expression}} \
203                  // all-note {{shift count 32 >= width of type 'int'}}
204 };
205 
206 #if __WCHAR_WIDTH__ == 32
207 #  if !defined(__WCHAR_UNSIGNED__)
208 static_assert(((wchar_t)-1U >> 31) == -1);
209 #  else
210 static_assert(((wchar_t)-1U >> 31) == 1);
211 #  endif
212 #endif
213 
214 #if __INT_WIDTH__ == 32
215 static_assert(((int)-1U >> 32) == -1); // all-error {{not an integral constant expression}} \
216                                        // all-note {{shift count 32 >= width of type 'int' (32 bits)}}
217 #endif
218 
219 static_assert((-4 << 32) == 0); // all-error {{not an integral constant expression}} \
220                                 // all-note {{shift count}}
221 
222 static_assert((-4 << 1) == -8); // ref-cxx17-error {{not an integral constant expression}} \
223                                 // ref-cxx17-note {{left shift of negative value -4}} \
224                                 // cxx17-error {{not an integral constant expression}} \
225                                 // cxx17-note {{left shift of negative value -4}}
226 static_assert((-4 << 31) == 0); // ref-cxx17-error {{not an integral constant expression}} \
227                                 // ref-cxx17-note {{left shift of negative value -4}} \
228                                 // cxx17-error {{not an integral constant expression}} \
229                                 // cxx17-note {{left shift of negative value -4}}
230