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
5 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
7 #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
13 template <class T
, class V
> struct is_same
{
14 static constexpr bool value
= false;
16 template <class T
> struct is_same
<T
, T
> {
17 static constexpr bool value
= true;
20 static_assert(sizeof(int) == 4);
21 static_assert(sizeof(long long) == 8);
23 template <class To
, class From
>
24 constexpr To
bit_cast(const From
&from
) {
25 static_assert(sizeof(To
) == sizeof(From
));
26 // expected-note@+9 {{cannot be represented in type 'bool'}}
28 // expected-note@+7 {{or 'std::byte'; '__int128' is invalid}}
30 #ifdef __CHAR_UNSIGNED__
31 // expected-note@+4 2 {{indeterminate value can only initialize an object of type 'unsigned char', 'char', or 'std::byte'; 'signed char' is invalid}}
33 // expected-note@+2 2 {{indeterminate value can only initialize an object of type 'unsigned char' or 'std::byte'; 'signed char' is invalid}}
35 return __builtin_bit_cast(To
, from
);
38 template <class Intermediate
, class Init
>
39 constexpr bool round_trip(const Init
&init
) {
40 return bit_cast
<Init
>(bit_cast
<Intermediate
>(init
)) == init
;
44 static_assert(round_trip
<unsigned>((int)-1));
45 static_assert(round_trip
<unsigned>((int)0x12345678));
46 static_assert(round_trip
<unsigned>((int)0x87654321));
47 static_assert(round_trip
<unsigned>((int)0x0C05FEFE));
51 constexpr unsigned char input
[] = {0xCA, 0xFE, 0xBA, 0xBE};
52 constexpr unsigned expected
= LITTLE_END
? 0xBEBAFECA : 0xCAFEBABE;
53 static_assert(bit_cast
<unsigned>(input
) == expected
);
61 constexpr bool operator==(const int_splicer
&other
) const {
62 return other
.x
== x
&& other
.y
== y
;
66 constexpr int_splicer splice
{0x0C05FEFE, 0xCAFEBABE};
68 static_assert(bit_cast
<unsigned long long>(splice
) == (LITTLE_END
70 : 0x0C05FEFECAFEBABE));
72 static_assert(bit_cast
<int_splicer
>(0xCAFEBABE0C05FEFE).x
== (LITTLE_END
76 static_assert(round_trip
<unsigned long long>(splice
));
77 static_assert(round_trip
<long long>(splice
));
86 struct bases
: int_splicer
, base2
, base3
{
91 unsigned x
, y
, z
, doublez
;
93 constexpr bool operator==(tuple4
const &other
) const {
94 return x
== other
.x
&& y
== other
.y
&&
95 z
== other
.z
&& doublez
== other
.doublez
;
98 constexpr bases b
= {{1, 2}, {}, {3}, 4};
99 constexpr tuple4 t4
= bit_cast
<tuple4
>(b
);
100 static_assert(t4
== tuple4
{1, 2, 3, 4});
101 static_assert(round_trip
<tuple4
>(b
));
104 void test_partially_initialized() {
112 signed char p1
, p2
, p3
;
116 static_assert(sizeof(pad
) == sizeof(no_pad
));
118 constexpr pad pir
{4, 4};
119 // expected-error@+2 {{constexpr variable 'piw' must be initialized by a constant expression}}
120 // expected-note@+1 {{in call to 'bit_cast(pir)'}}
121 constexpr int piw
= bit_cast
<no_pad
>(pir
).x
;
123 // expected-error@+2 {{constexpr variable 'bad' must be initialized by a constant expression}}
124 // expected-note@+1 {{in call to 'bit_cast(pir)'}}
125 constexpr no_pad bad
= bit_cast
<no_pad
>(pir
);
127 constexpr pad fine
= bit_cast
<pad
>(no_pad
{1, 2, 3, 4, 5});
128 static_assert(fine
.x
== 1 && fine
.y
== 5);
131 void no_bitfields() {
142 // expected-error@+2 {{constexpr variable 'g' must be initialized by a constant expression}}
143 // expected-note@+1 {{constexpr bit_cast involving bit-field is not yet supported}}
144 constexpr G g
= __builtin_bit_cast(G
, s
);
147 void array_members() {
151 constexpr bool operator==(const S
&rhs
) {
152 return ar
[0] == rhs
.ar
[0] && ar
[1] == rhs
.ar
[1] && ar
[2] == rhs
.ar
[2];
159 constexpr bool operator==(const G
&rhs
) {
160 return a
== rhs
.a
&& b
== rhs
.b
&& c
== rhs
.c
;
164 constexpr S s
{{1, 2, 3}};
165 constexpr G g
= bit_cast
<G
>(s
);
166 static_assert(g
.a
== 1 && g
.b
== 2 && g
.c
== 3);
168 static_assert(round_trip
<G
>(s
));
169 static_assert(round_trip
<S
>(g
));
180 // expected-error@+2 {{constexpr variable 'g' must be initialized by a constant expression}}
181 // expected-note@+1 {{bit_cast from a union type is not allowed in a constant expression}}
182 constexpr G g
= __builtin_bit_cast(G
, X
{0});
183 // expected-error@+2 {{constexpr variable 'x' must be initialized by a constant expression}}
184 // expected-note@+1 {{bit_cast to a union type is not allowed in a constant expression}}
185 constexpr X x
= __builtin_bit_cast(X
, G
{0});
188 // expected-note@+1 2 {{invalid type 'int *' is a member of 'has_pointer'}}
192 // expected-error@+2 {{constexpr variable 'ptr' must be initialized by a constant expression}}
193 // expected-note@+1 {{bit_cast from a pointer type is not allowed in a constant expression}}
194 constexpr unsigned long ptr
= __builtin_bit_cast(unsigned long, has_pointer
{0});
195 // expected-error@+2 {{constexpr variable 'hptr' must be initialized by a constant expression}}
196 // expected-note@+1 {{bit_cast to a pointer type is not allowed in a constant expression}}
197 constexpr has_pointer hptr
= __builtin_bit_cast(has_pointer
, 0ul);
202 // expected-note@+1 {{invalid type 'int *' is a member of 'A'}}
207 // expected-note@+1 {{invalid type 'A[10]' is a member of 'B'}}
211 // expected-note@+1 {{invalid type 'B' is a base of 'C'}}
216 unsigned long ar
[10];
219 // expected-error@+2 {{constexpr variable 'e' must be initialized by a constant expression}}
220 // expected-note@+1 {{bit_cast from a pointer type is not allowed in a constant expression}}
221 constexpr E e
= __builtin_bit_cast(E
, C
{});
224 void test_array_fill() {
225 constexpr unsigned char a
[4] = {1, 2};
226 constexpr unsigned int i
= bit_cast
<unsigned int>(a
);
227 static_assert(i
== (LITTLE_END
? 0x00000201 : 0x01020000));
230 typedef decltype(nullptr) nullptr_t
;
232 #ifdef __CHAR_UNSIGNED__
233 // expected-note@+5 {{indeterminate value can only initialize an object of type 'unsigned char', 'char', or 'std::byte'; 'unsigned long' is invalid}}
235 // expected-note@+3 {{indeterminate value can only initialize an object of type 'unsigned char' or 'std::byte'; 'unsigned long' is invalid}}
237 // expected-error@+1 {{constexpr variable 'test_from_nullptr' must be initialized by a constant expression}}
238 constexpr unsigned long test_from_nullptr
= __builtin_bit_cast(unsigned long, nullptr);
240 constexpr int test_from_nullptr_pass
= (__builtin_bit_cast(unsigned char[8], nullptr), 0);
242 constexpr int test_to_nullptr() {
243 nullptr_t npt
= __builtin_bit_cast(nullptr_t
, 0ul);
246 unsigned char data
[sizeof(void *)];
248 indet_mem im
= __builtin_bit_cast(indet_mem
, nullptr);
249 nullptr_t npt2
= __builtin_bit_cast(nullptr_t
, im
);
254 constexpr int ttn
= test_to_nullptr();
256 // expected-warning@+2 {{returning reference to local temporary object}}
257 // expected-note@+1 {{temporary created here}}
258 constexpr const long &returns_local() { return 0L; }
260 // expected-error@+2 {{constexpr variable 'test_nullptr_bad' must be initialized by a constant expression}}
261 // expected-note@+1 {{read of temporary whose lifetime has ended}}
262 constexpr nullptr_t test_nullptr_bad
= __builtin_bit_cast(nullptr_t
, returns_local());
264 constexpr int test_indeterminate(bool read_indet
) {
272 unsigned char p1
, p2
, p3
;
277 no_pad np
= bit_cast
<no_pad
>(p
);
279 int tmp
= np
.a
+ np
.b
;
281 unsigned char& indet_ref
= np
.p1
;
284 // expected-note@+1 {{read of uninitialized object is not allowed in a constant expression}}
293 constexpr int run_test_indeterminate
= test_indeterminate(false);
294 // expected-error@+2 {{constexpr variable 'run_test_indeterminate2' must be initialized by a constant expression}}
295 // expected-note@+1 {{in call to 'test_indeterminate(true)'}}
296 constexpr int run_test_indeterminate2
= test_indeterminate(true);
302 constexpr int global_int
= 0;
304 // expected-error@+2 {{constexpr variable 'run_ref_mem' must be initialized by a constant expression}}
305 // expected-note@+1 {{bit_cast from a type with a reference member is not allowed in a constant expression}}
306 constexpr unsigned long run_ref_mem
= __builtin_bit_cast(
307 unsigned long, ref_mem
{global_int
});
313 // expected-error@+2 {{constexpr variable 'run_u' must be initialized by a constant expression}}
314 // expected-note@+1 {{bit_cast from a union type is not allowed in a constant expression}}
315 constexpr int run_u
= __builtin_bit_cast(int, u
{32});
321 // expected-error@+2 {{constexpr variable 'run_vol_mem' must be initialized by a constant expression}}
322 // expected-note@+1 {{non-literal type 'vol_mem' cannot be used in a constant expression}}
323 constexpr int run_vol_mem
= __builtin_bit_cast(int, vol_mem
{43});
326 int vol_mem::*x
; // expected-note{{invalid type 'int vol_mem::*' is a member of 'mem_ptr'}}
328 // expected-error@+2 {{constexpr variable 'run_mem_ptr' must be initialized by a constant expression}}
329 // expected-note@+1 {{bit_cast from a member pointer type is not allowed in a constant expression}}
330 constexpr int run_mem_ptr
= __builtin_bit_cast(unsigned long, mem_ptr
{nullptr});
332 struct A
{ char c
; /* char padding : 8; */ short s
; };
333 struct B
{ unsigned char x
[4]; };
337 return bit_cast
<B
>(a
);
339 constexpr char good_one
= one().x
[0] + one().x
[2] + one().x
[3];
340 // expected-error@+2 {{constexpr variable 'bad_one' must be initialized by a constant expression}}
341 // expected-note@+1 {{read of uninitialized object is not allowed in a constant expression}}
342 constexpr char bad_one
= one().x
[1];
345 B b
= one(); // b.x[1] is indeterminate.
349 return bit_cast
<A
>(b
);
351 constexpr short good_two
= two().c
+ two().s
;
354 enum byte
: unsigned char {};
357 enum my_byte
: unsigned char {};
364 constexpr int ok_byte
= (__builtin_bit_cast(std::byte
[8], pad
{1, 2}), 0);
365 constexpr int ok_uchar
= (__builtin_bit_cast(unsigned char[8], pad
{1, 2}), 0);
367 #ifdef __CHAR_UNSIGNED__
368 // expected-note@+5 {{indeterminate value can only initialize an object of type 'unsigned char', 'char', or 'std::byte'; 'my_byte' is invalid}}}}
370 // expected-note@+3 {{indeterminate value can only initialize an object of type 'unsigned char' or 'std::byte'; 'my_byte' is invalid}}
372 // expected-error@+1 {{constexpr variable 'bad_my_byte' must be initialized by a constant expression}}
373 constexpr int bad_my_byte
= (__builtin_bit_cast(my_byte
[8], pad
{1, 2}), 0);
374 #ifndef __CHAR_UNSIGNED__
375 // expected-error@+3 {{constexpr variable 'bad_char' must be initialized by a constant expression}}
376 // expected-note@+2 {{indeterminate value can only initialize an object of type 'unsigned char' or 'std::byte'; 'char' is invalid}}
378 constexpr int bad_char
= (__builtin_bit_cast(char[8], pad
{1, 2}), 0);
380 struct pad_buffer
{ unsigned char data
[sizeof(pad
)]; };
381 constexpr bool test_pad_buffer() {
383 pad_buffer y
= __builtin_bit_cast(pad_buffer
, x
);
384 pad z
= __builtin_bit_cast(pad
, y
);
385 return x
.a
== z
.a
&& x
.b
== z
.b
;
387 static_assert(test_pad_buffer());
389 constexpr unsigned char identity1a
= 42;
390 constexpr unsigned char identity1b
= __builtin_bit_cast(unsigned char, identity1a
);
391 static_assert(identity1b
== 42);
393 struct IdentityInStruct
{
396 constexpr IdentityInStruct identity2a
= {42};
397 constexpr unsigned char identity2b
= __builtin_bit_cast(unsigned char, identity2a
.n
);
399 union IdentityInUnion
{
402 constexpr IdentityInUnion identity3a
= {42};
403 constexpr unsigned char identity3b
= __builtin_bit_cast(unsigned char, identity3a
.n
);
405 namespace test_bool
{
407 constexpr bool test_bad_bool
= bit_cast
<bool>('A'); // expected-error {{must be initialized by a constant expression}} expected-note{{in call}}
409 static_assert(round_trip
<signed char>(true), "");
410 static_assert(round_trip
<unsigned char>(false), "");
411 static_assert(round_trip
<bool>(false), "");
413 static_assert(round_trip
<bool>((char)0), "");
414 static_assert(round_trip
<bool>((char)1), "");
417 namespace test_long_double
{
419 constexpr __int128_t test_cast_to_int128
= bit_cast
<__int128_t
>((long double)0); // expected-error{{must be initialized by a constant expression}} expected-note{{in call}}
421 constexpr long double ld
= 3.1425926539;
427 static_assert(round_trip
<bytes
>(ld
), "");
429 static_assert(round_trip
<long double>(10.0L));
431 constexpr bool f(bool read_uninit
) {
432 bytes b
= bit_cast
<bytes
>(ld
);
433 unsigned char ld_bytes
[10] = {
434 0x0, 0x48, 0x9f, 0x49, 0xf0,
435 0x3c, 0x20, 0xc9, 0x0, 0x40,
438 for (int i
= 0; i
!= 10; ++i
)
439 if (ld_bytes
[i
] != b
.d
[i
])
442 if (read_uninit
&& b
.d
[10]) // expected-note{{read of uninitialized object is not allowed in a constant expression}}
448 static_assert(f(/*read_uninit=*/false), "");
449 static_assert(f(/*read_uninit=*/true), ""); // expected-error{{static assertion expression is not an integral constant expression}} expected-note{{in call to 'f(true)'}}
451 constexpr bytes ld539
= {
453 0x0, 0x0, 0xc0, 0x86,
458 constexpr long double fivehundredandthirtynine
= 539.0;
460 static_assert(bit_cast
<long double>(ld539
) == fivehundredandthirtynine
, "");
463 static_assert(round_trip
<__int128_t
>(34.0L));