230 lines · cpp
1// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -std=c++20 -verify=expected,all %s2// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -std=c++17 -verify=cxx17,all %s3// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -std=c++17 -verify=cxx17,all -triple armv8 %s4// RUN: %clang_cc1 -std=c++20 -verify=ref,all %s5// RUN: %clang_cc1 -std=c++17 -verify=ref-cxx17,all %s6// RUN: %clang_cc1 -std=c++17 -verify=ref-cxx17,all -triple armv8 %s7 8#define INT_MIN (~__INT_MAX__)9 10constexpr int a = -1 >> 3;11 12namespace 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-formed138 139 /// The purpose of these few lines is to test that we can shift more bits140 /// than an unsigned *of the host* has. There was a bug where we casted141 /// to host-unsigned. However, we cannot query what a host-unsigned even is142 /// 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 184namespace LongInt {185 constexpr int f() {186 int a = 1;187 a <<= (long)0;188 return 1;189 }190 static_assert(f() == 1, "");191};192 193enum 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__ == 32207# if !defined(__WCHAR_UNSIGNED__)208static_assert(((wchar_t)-1U >> 31) == -1);209# else210static_assert(((wchar_t)-1U >> 31) == 1);211# endif212#endif213 214#if __INT_WIDTH__ == 32215static_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#endif218 219static_assert((-4 << 32) == 0); // all-error {{not an integral constant expression}} \220 // all-note {{shift count}}221 222static_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}}226static_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