|
1 | 1 | // RUN: %clang_cc1 -std=c++2c -verify %s |
2 | 2 |
|
3 | 3 | class Trivial {}; |
| 4 | +static_assert(__builtin_is_cpp_trivially_relocatable(Trivial)); |
4 | 5 | struct NonRelocatable { |
5 | 6 | ~NonRelocatable(); |
6 | 7 | }; |
7 | 8 | static NonRelocatable NonRelocatable_g; |
8 | 9 |
|
9 | 10 | class A trivially_relocatable_if_eligible {}; |
| 11 | +static_assert(__builtin_is_cpp_trivially_relocatable(A)); |
| 12 | + |
| 13 | + |
10 | 14 | class B trivially_relocatable_if_eligible : Trivial{}; |
| 15 | +static_assert(__builtin_is_cpp_trivially_relocatable(B)); |
| 16 | + |
11 | 17 | class C trivially_relocatable_if_eligible { |
12 | 18 | int a; |
13 | 19 | void* b; |
14 | 20 | int c[3]; |
15 | 21 | Trivial d[3]; |
16 | 22 | NonRelocatable& e = NonRelocatable_g; |
17 | 23 | }; |
| 24 | +static_assert(__builtin_is_cpp_trivially_relocatable(C)); |
| 25 | + |
| 26 | + |
18 | 27 | class D trivially_relocatable_if_eligible : Trivial {}; |
| 28 | +static_assert(__builtin_is_cpp_trivially_relocatable(D)); |
| 29 | + |
| 30 | + |
19 | 31 | class E trivially_relocatable_if_eligible : virtual Trivial {}; |
| 32 | +static_assert(!__builtin_is_cpp_trivially_relocatable(E)); |
| 33 | + |
20 | 34 |
|
21 | 35 | class F trivially_relocatable_if_eligible : NonRelocatable {}; |
| 36 | +static_assert(!__builtin_is_cpp_trivially_relocatable(F)); |
| 37 | + |
| 38 | +class G trivially_relocatable_if_eligible { |
| 39 | + G(G&&); |
| 40 | +}; |
| 41 | +static_assert(__builtin_is_cpp_trivially_relocatable(G)); |
| 42 | + |
| 43 | +class H trivially_relocatable_if_eligible { |
| 44 | + ~H(); |
| 45 | +}; |
| 46 | +static_assert(__builtin_is_cpp_trivially_relocatable(H)); |
22 | 47 |
|
23 | 48 | class I trivially_relocatable_if_eligible { |
24 | 49 | NonRelocatable a; |
25 | 50 | NonRelocatable b[1]; |
26 | 51 | const NonRelocatable c; |
27 | 52 | const NonRelocatable d[1]; |
28 | 53 | }; |
| 54 | +static_assert(!__builtin_is_cpp_trivially_relocatable(I)); |
| 55 | + |
29 | 56 |
|
30 | 57 | class J trivially_relocatable_if_eligible: virtual Trivial, NonRelocatable { |
31 | 58 | NonRelocatable a; |
32 | 59 | }; |
| 60 | +static_assert(!__builtin_is_cpp_trivially_relocatable(J)); |
33 | 61 |
|
34 | | -class G trivially_relocatable_if_eligible { |
35 | | - G(G&&); |
36 | | -}; |
37 | | - |
38 | | -class H trivially_relocatable_if_eligible { |
39 | | - ~H(); |
40 | | -}; |
41 | 62 |
|
42 | 63 | struct Incomplete; // expected-note {{forward declaration of 'Incomplete'}} |
43 | 64 | static_assert(__builtin_is_cpp_trivially_relocatable(Incomplete)); // expected-error {{incomplete type 'Incomplete' used in type trait expression}} |
44 | | -static_assert(__builtin_is_cpp_trivially_relocatable(Trivial)); |
45 | | -static_assert(__builtin_is_cpp_trivially_relocatable(G)); |
46 | | -static_assert(__builtin_is_cpp_trivially_relocatable(H)); |
47 | 65 | static_assert(__builtin_is_cpp_trivially_relocatable(int)); |
48 | 66 | static_assert(__builtin_is_cpp_trivially_relocatable(void*)); |
49 | 67 | static_assert(!__builtin_is_cpp_trivially_relocatable(int&)); |
50 | 68 | static_assert(!__builtin_is_cpp_trivially_relocatable(Trivial&)); |
51 | 69 | static_assert(__builtin_is_cpp_trivially_relocatable(const Trivial)); |
52 | 70 | static_assert(__builtin_is_cpp_trivially_relocatable(Trivial[1])); |
| 71 | +static_assert(__builtin_is_cpp_trivially_relocatable(Trivial[])); |
| 72 | + |
| 73 | +struct WithConst { |
| 74 | + const int i; |
| 75 | +}; |
| 76 | +static_assert(__builtin_is_cpp_trivially_relocatable(WithConst)); |
53 | 77 |
|
54 | 78 | struct UserDtr { |
55 | 79 | ~UserDtr(); |
@@ -115,9 +139,15 @@ struct DeletedMoveAssign { |
115 | 139 | DeletedMoveAssign& operator=(DeletedMoveAssign&&) = delete; |
116 | 140 | }; |
117 | 141 |
|
| 142 | +struct DeletedDtr { |
| 143 | + ~DeletedDtr() = delete; |
| 144 | +}; |
| 145 | + |
118 | 146 | static_assert(!__builtin_is_cpp_trivially_relocatable(DeletedMove)); |
119 | 147 | static_assert(!__builtin_is_cpp_trivially_relocatable(DeletedCopy)); |
120 | 148 | static_assert(!__builtin_is_cpp_trivially_relocatable(DeletedMoveAssign)); |
| 149 | +static_assert(!__builtin_is_cpp_trivially_relocatable(DeletedDtr)); |
| 150 | + |
121 | 151 |
|
122 | 152 | union U { |
123 | 153 | G g; |
@@ -174,6 +204,7 @@ static_assert(__builtin_is_replaceable(DefaultedMoveAssign)); |
174 | 204 | static_assert(!__builtin_is_replaceable(DeletedMove)); |
175 | 205 | static_assert(!__builtin_is_replaceable(DeletedCopy)); |
176 | 206 | static_assert(!__builtin_is_replaceable(DeletedMoveAssign)); |
| 207 | +static_assert(!__builtin_is_replaceable(DeletedDtr)); |
177 | 208 |
|
178 | 209 | static_assert(!__builtin_is_replaceable(UserProvidedMove)); |
179 | 210 | static_assert(!__builtin_is_replaceable(UserProvidedCopy)); |
@@ -276,3 +307,16 @@ void test__builtin_trivially_relocate() { |
276 | 307 | __builtin_trivially_relocate((int*)0, (int*)0, 0); |
277 | 308 | __builtin_trivially_relocate((R*)0, (R*)0, 0); |
278 | 309 | } |
| 310 | + |
| 311 | +void test__builtin_trivially_relocate(auto&& src, auto&&dest, auto size) { |
| 312 | + __builtin_trivially_relocate(src, dest, size); // #reloc1 |
| 313 | +} |
| 314 | + |
| 315 | +void do_test__builtin_trivially_relocate() { |
| 316 | + struct S{ ~S();}; |
| 317 | + struct R {}; |
| 318 | + test__builtin_trivially_relocate((R*)0, (R*)0, 0); |
| 319 | + test__builtin_trivially_relocate((S*)0, (S*)0, 0); |
| 320 | + // expected-note@-1 {{'test__builtin_trivially_relocate<S *, S *, int>' requested here}} |
| 321 | + // expected-error@#reloc1 {{first argument to '__builtin_trivially_relocate' must be relocatable}} |
| 322 | +} |
0 commit comments