1 // RUN: %clang_cc1 -verify -std=c++2a -fsyntax-only -triple x86_64-apple-macosx10.14.0 %s 2 // RUN: %clang_cc1 -verify -std=c++2a -fsyntax-only -triple x86_64-apple-macosx10.14.0 %s -fno-signed-char 3 // RUN: %clang_cc1 -verify -std=c++2a -fsyntax-only -triple aarch64_be-linux-gnu %s 4 5 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ 6 # define LITTLE_END 1 7 #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ 8 # define LITTLE_END 0 9 #else 10 # error "huh?" 11 #endif 12 13 template <class T, class V> struct is_same { 14 static constexpr bool value = false; 15 }; 16 template <class T> struct is_same<T, T> { 17 static constexpr bool value = true; 18 }; 19 20 static_assert(sizeof(int) == 4); 21 static_assert(sizeof(long long) == 8); 22 23 template <class To, class From> 24 constexpr To bit_cast(const From &from) { 25 static_assert(sizeof(To) == sizeof(From)); 26 #ifdef __CHAR_UNSIGNED__ 27 // expected-note@+4 2 {{indeterminate value can only initialize an object of type 'unsigned char', 'char', or 'std::byte'; 'signed char' is invalid}} 28 #else 29 // expected-note@+2 2 {{indeterminate value can only initialize an object of type 'unsigned char' or 'std::byte'; 'signed char' is invalid}} 30 #endif 31 return __builtin_bit_cast(To, from); 32 } 33 34 template <class Intermediate, class Init> 35 constexpr bool round_trip(const Init &init) { 36 return bit_cast<Init>(bit_cast<Intermediate>(init)) == init; 37 } 38 39 void test_int() { 40 static_assert(round_trip<unsigned>((int)-1)); 41 static_assert(round_trip<unsigned>((int)0x12345678)); 42 static_assert(round_trip<unsigned>((int)0x87654321)); 43 static_assert(round_trip<unsigned>((int)0x0C05FEFE)); 44 } 45 46 void test_array() { 47 constexpr unsigned char input[] = {0xCA, 0xFE, 0xBA, 0xBE}; 48 constexpr unsigned expected = LITTLE_END ? 0xBEBAFECA : 0xCAFEBABE; 49 static_assert(bit_cast<unsigned>(input) == expected); 50 } 51 52 void test_record() { 53 struct int_splicer { 54 unsigned x; 55 unsigned y; 56 57 constexpr bool operator==(const int_splicer &other) const { 58 return other.x == x && other.y == y; 59 } 60 }; 61 62 constexpr int_splicer splice{0x0C05FEFE, 0xCAFEBABE}; 63 64 static_assert(bit_cast<unsigned long long>(splice) == (LITTLE_END 65 ? 0xCAFEBABE0C05FEFE 66 : 0x0C05FEFECAFEBABE)); 67 68 static_assert(bit_cast<int_splicer>(0xCAFEBABE0C05FEFE).x == (LITTLE_END 69 ? 0x0C05FEFE 70 : 0xCAFEBABE)); 71 72 static_assert(round_trip<unsigned long long>(splice)); 73 static_assert(round_trip<long long>(splice)); 74 75 struct base2 { 76 }; 77 78 struct base3 { 79 unsigned z; 80 }; 81 82 struct bases : int_splicer, base2, base3 { 83 unsigned doublez; 84 }; 85 86 struct tuple4 { 87 unsigned x, y, z, doublez; 88 89 constexpr bool operator==(tuple4 const &other) const { 90 return x == other.x && y == other.y && 91 z == other.z && doublez == other.doublez; 92 } 93 }; 94 constexpr bases b = {{1, 2}, {}, {3}, 4}; 95 constexpr tuple4 t4 = bit_cast<tuple4>(b); 96 static_assert(t4 == tuple4{1, 2, 3, 4}); 97 static_assert(round_trip<tuple4>(b)); 98 } 99 100 void test_partially_initialized() { 101 struct pad { 102 signed char x; 103 int y; 104 }; 105 106 struct no_pad { 107 signed char x; 108 signed char p1, p2, p3; 109 int y; 110 }; 111 112 static_assert(sizeof(pad) == sizeof(no_pad)); 113 114 constexpr pad pir{4, 4}; 115 // expected-error@+2 {{constexpr variable 'piw' must be initialized by a constant expression}} 116 // expected-note@+1 {{in call to 'bit_cast(pir)'}} 117 constexpr int piw = bit_cast<no_pad>(pir).x; 118 119 // expected-error@+2 {{constexpr variable 'bad' must be initialized by a constant expression}} 120 // expected-note@+1 {{in call to 'bit_cast(pir)'}} 121 constexpr no_pad bad = bit_cast<no_pad>(pir); 122 123 constexpr pad fine = bit_cast<pad>(no_pad{1, 2, 3, 4, 5}); 124 static_assert(fine.x == 1 && fine.y == 5); 125 } 126 127 void no_bitfields() { 128 // FIXME! 129 struct S { 130 unsigned char x : 8; 131 }; 132 133 struct G { 134 unsigned char x : 8; 135 }; 136 137 constexpr S s{0}; 138 // expected-error@+2 {{constexpr variable 'g' must be initialized by a constant expression}} 139 // expected-note@+1 {{constexpr bit_cast involving bit-field is not yet supported}} 140 constexpr G g = __builtin_bit_cast(G, s); 141 } 142 143 void array_members() { 144 struct S { 145 int ar[3]; 146 147 constexpr bool operator==(const S &rhs) { 148 return ar[0] == rhs.ar[0] && ar[1] == rhs.ar[1] && ar[2] == rhs.ar[2]; 149 } 150 }; 151 152 struct G { 153 int a, b, c; 154 155 constexpr bool operator==(const G &rhs) { 156 return a == rhs.a && b == rhs.b && c == rhs.c; 157 } 158 }; 159 160 constexpr S s{{1, 2, 3}}; 161 constexpr G g = bit_cast<G>(s); 162 static_assert(g.a == 1 && g.b == 2 && g.c == 3); 163 164 static_assert(round_trip<G>(s)); 165 static_assert(round_trip<S>(g)); 166 } 167 168 void bad_types() { 169 union X { 170 int x; 171 }; 172 173 struct G { 174 int g; 175 }; 176 // expected-error@+2 {{constexpr variable 'g' must be initialized by a constant expression}} 177 // expected-note@+1 {{bit_cast from a union type is not allowed in a constant expression}} 178 constexpr G g = __builtin_bit_cast(G, X{0}); 179 // expected-error@+2 {{constexpr variable 'x' must be initialized by a constant expression}} 180 // expected-note@+1 {{bit_cast to a union type is not allowed in a constant expression}} 181 constexpr X x = __builtin_bit_cast(X, G{0}); 182 183 struct has_pointer { 184 // expected-note@+1 2 {{invalid type 'int *' is a member of 'has_pointer'}} 185 int *ptr; 186 }; 187 188 // expected-error@+2 {{constexpr variable 'ptr' must be initialized by a constant expression}} 189 // expected-note@+1 {{bit_cast from a pointer type is not allowed in a constant expression}} 190 constexpr unsigned long ptr = __builtin_bit_cast(unsigned long, has_pointer{0}); 191 // expected-error@+2 {{constexpr variable 'hptr' must be initialized by a constant expression}} 192 // expected-note@+1 {{bit_cast to a pointer type is not allowed in a constant expression}} 193 constexpr has_pointer hptr = __builtin_bit_cast(has_pointer, 0ul); 194 } 195 196 void backtrace() { 197 struct A { 198 // expected-note@+1 {{invalid type 'int *' is a member of 'A'}} 199 int *ptr; 200 }; 201 202 struct B { 203 // expected-note@+1 {{invalid type 'A [10]' is a member of 'B'}} 204 A as[10]; 205 }; 206 207 // expected-note@+1 {{invalid type 'B' is a base of 'C'}} 208 struct C : B { 209 }; 210 211 struct E { 212 unsigned long ar[10]; 213 }; 214 215 // expected-error@+2 {{constexpr variable 'e' must be initialized by a constant expression}} 216 // expected-note@+1 {{bit_cast from a pointer type is not allowed in a constant expression}} 217 constexpr E e = __builtin_bit_cast(E, C{}); 218 } 219 220 void test_array_fill() { 221 constexpr unsigned char a[4] = {1, 2}; 222 constexpr unsigned int i = bit_cast<unsigned int>(a); 223 static_assert(i == (LITTLE_END ? 0x00000201 : 0x01020000)); 224 } 225 226 typedef decltype(nullptr) nullptr_t; 227 228 #ifdef __CHAR_UNSIGNED__ 229 // expected-note@+5 {{indeterminate value can only initialize an object of type 'unsigned char', 'char', or 'std::byte'; 'unsigned long' is invalid}} 230 #else 231 // expected-note@+3 {{indeterminate value can only initialize an object of type 'unsigned char' or 'std::byte'; 'unsigned long' is invalid}} 232 #endif 233 // expected-error@+1 {{constexpr variable 'test_from_nullptr' must be initialized by a constant expression}} 234 constexpr unsigned long test_from_nullptr = __builtin_bit_cast(unsigned long, nullptr); 235 236 constexpr int test_from_nullptr_pass = (__builtin_bit_cast(unsigned char[8], nullptr), 0); 237 238 constexpr int test_to_nullptr() { 239 nullptr_t npt = __builtin_bit_cast(nullptr_t, 0ul); 240 241 struct indet_mem { 242 unsigned char data[sizeof(void *)]; 243 }; 244 indet_mem im = __builtin_bit_cast(indet_mem, nullptr); 245 nullptr_t npt2 = __builtin_bit_cast(nullptr_t, im); 246 247 return 0; 248 } 249 250 constexpr int ttn = test_to_nullptr(); 251 252 // expected-warning@+2 {{returning reference to local temporary object}} 253 // expected-note@+1 {{temporary created here}} 254 constexpr const long &returns_local() { return 0L; } 255 256 // expected-error@+2 {{constexpr variable 'test_nullptr_bad' must be initialized by a constant expression}} 257 // expected-note@+1 {{read of temporary whose lifetime has ended}} 258 constexpr nullptr_t test_nullptr_bad = __builtin_bit_cast(nullptr_t, returns_local()); 259 260 constexpr int test_indeterminate(bool read_indet) { 261 struct pad { 262 char a; 263 int b; 264 }; 265 266 struct no_pad { 267 char a; 268 unsigned char p1, p2, p3; 269 int b; 270 }; 271 272 pad p{1, 2}; 273 no_pad np = bit_cast<no_pad>(p); 274 275 int tmp = np.a + np.b; 276 277 unsigned char& indet_ref = np.p1; 278 279 if (read_indet) { 280 // expected-note@+1 {{read of uninitialized object is not allowed in a constant expression}} 281 tmp = indet_ref; 282 } 283 284 indet_ref = 0; 285 286 return 0; 287 } 288 289 constexpr int run_test_indeterminate = test_indeterminate(false); 290 // expected-error@+2 {{constexpr variable 'run_test_indeterminate2' must be initialized by a constant expression}} 291 // expected-note@+1 {{in call to 'test_indeterminate(true)'}} 292 constexpr int run_test_indeterminate2 = test_indeterminate(true); 293 294 struct ref_mem { 295 const int &rm; 296 }; 297 298 constexpr int global_int = 0; 299 300 // expected-error@+2 {{constexpr variable 'run_ref_mem' must be initialized by a constant expression}} 301 // expected-note@+1 {{bit_cast from a type with a reference member is not allowed in a constant expression}} 302 constexpr unsigned long run_ref_mem = __builtin_bit_cast( 303 unsigned long, ref_mem{global_int}); 304 305 union u { 306 int im; 307 }; 308 309 // expected-error@+2 {{constexpr variable 'run_u' must be initialized by a constant expression}} 310 // expected-note@+1 {{bit_cast from a union type is not allowed in a constant expression}} 311 constexpr int run_u = __builtin_bit_cast(int, u{32}); 312 313 struct vol_mem { 314 volatile int x; 315 }; 316 317 // expected-error@+2 {{constexpr variable 'run_vol_mem' must be initialized by a constant expression}} 318 // expected-note@+1 {{non-literal type 'vol_mem' cannot be used in a constant expression}} 319 constexpr int run_vol_mem = __builtin_bit_cast(int, vol_mem{43}); 320 321 struct mem_ptr { 322 int vol_mem::*x; // expected-note{{invalid type 'int vol_mem::*' is a member of 'mem_ptr'}} 323 }; 324 // expected-error@+2 {{constexpr variable 'run_mem_ptr' must be initialized by a constant expression}} 325 // expected-note@+1 {{bit_cast from a member pointer type is not allowed in a constant expression}} 326 constexpr int run_mem_ptr = __builtin_bit_cast(unsigned long, mem_ptr{nullptr}); 327 328 struct A { char c; /* char padding : 8; */ short s; }; 329 struct B { unsigned char x[4]; }; 330 331 constexpr B one() { 332 A a = {1, 2}; 333 return bit_cast<B>(a); 334 } 335 constexpr char good_one = one().x[0] + one().x[2] + one().x[3]; 336 // expected-error@+2 {{constexpr variable 'bad_one' must be initialized by a constant expression}} 337 // expected-note@+1 {{read of uninitialized object is not allowed in a constant expression}} 338 constexpr char bad_one = one().x[1]; 339 340 constexpr A two() { 341 B b = one(); // b.x[1] is indeterminate. 342 b.x[0] = 'a'; 343 b.x[2] = 1; 344 b.x[3] = 2; 345 return bit_cast<A>(b); 346 } 347 constexpr short good_two = two().c + two().s; 348 349 namespace std { 350 enum byte : unsigned char {}; 351 } 352 353 enum my_byte : unsigned char {}; 354 355 struct pad { 356 char a; 357 int b; 358 }; 359 360 constexpr int ok_byte = (__builtin_bit_cast(std::byte[8], pad{1, 2}), 0); 361 constexpr int ok_uchar = (__builtin_bit_cast(unsigned char[8], pad{1, 2}), 0); 362 363 #ifdef __CHAR_UNSIGNED__ 364 // expected-note@+5 {{indeterminate value can only initialize an object of type 'unsigned char', 'char', or 'std::byte'; 'my_byte' is invalid}}}} 365 #else 366 // expected-note@+3 {{indeterminate value can only initialize an object of type 'unsigned char' or 'std::byte'; 'my_byte' is invalid}} 367 #endif 368 // expected-error@+1 {{constexpr variable 'bad_my_byte' must be initialized by a constant expression}} 369 constexpr int bad_my_byte = (__builtin_bit_cast(my_byte[8], pad{1, 2}), 0); 370 #ifndef __CHAR_UNSIGNED__ 371 // expected-error@+3 {{constexpr variable 'bad_char' must be initialized by a constant expression}} 372 // expected-note@+2 {{indeterminate value can only initialize an object of type 'unsigned char' or 'std::byte'; 'char' is invalid}} 373 #endif 374 constexpr int bad_char = (__builtin_bit_cast(char[8], pad{1, 2}), 0); 375 376 struct pad_buffer { unsigned char data[sizeof(pad)]; }; 377 constexpr bool test_pad_buffer() { 378 pad x = {1, 2}; 379 pad_buffer y = __builtin_bit_cast(pad_buffer, x); 380 pad z = __builtin_bit_cast(pad, y); 381 return x.a == z.a && x.b == z.b; 382 } 383 static_assert(test_pad_buffer()); 384 385 constexpr unsigned char identity1a = 42; 386 constexpr unsigned char identity1b = __builtin_bit_cast(unsigned char, identity1a); 387 static_assert(identity1b == 42); 388 389 struct IdentityInStruct { 390 unsigned char n; 391 }; 392 constexpr IdentityInStruct identity2a = {42}; 393 constexpr unsigned char identity2b = __builtin_bit_cast(unsigned char, identity2a.n); 394 395 union IdentityInUnion { 396 unsigned char n; 397 }; 398 constexpr IdentityInUnion identity3a = {42}; 399 constexpr unsigned char identity3b = __builtin_bit_cast(unsigned char, identity3a.n); 400