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