449 lines · cpp
1// RUN: %clang_cc1 -std=c++2c -verify %s2// RUN: %clang_cc1 -triple aarch64-linux-gnu -fptrauth-intrinsics -fptrauth-calls -std=c++2c -verify %s3 4class Trivial {};5static_assert(__builtin_is_cpp_trivially_relocatable(Trivial));6struct NonRelocatable {7 ~NonRelocatable();8};9static NonRelocatable NonRelocatable_g;10 11class A trivially_relocatable_if_eligible {};12static_assert(__builtin_is_cpp_trivially_relocatable(A));13 14 15class B trivially_relocatable_if_eligible : Trivial{};16static_assert(__builtin_is_cpp_trivially_relocatable(B));17 18class C trivially_relocatable_if_eligible {19 int a;20 void* b;21 int c[3];22 Trivial d[3];23 NonRelocatable& e = NonRelocatable_g;24};25static_assert(__builtin_is_cpp_trivially_relocatable(C));26 27 28class D trivially_relocatable_if_eligible : Trivial {};29static_assert(__builtin_is_cpp_trivially_relocatable(D));30 31 32class E trivially_relocatable_if_eligible : virtual Trivial {};33static_assert(!__builtin_is_cpp_trivially_relocatable(E));34 35 36class F trivially_relocatable_if_eligible : NonRelocatable {};37static_assert(!__builtin_is_cpp_trivially_relocatable(F));38 39class G trivially_relocatable_if_eligible {40 G(G&&);41};42static_assert(__builtin_is_cpp_trivially_relocatable(G));43 44class H trivially_relocatable_if_eligible {45 ~H();46};47static_assert(__builtin_is_cpp_trivially_relocatable(H));48 49class I trivially_relocatable_if_eligible {50 NonRelocatable a;51 NonRelocatable b[1];52 const NonRelocatable c;53 const NonRelocatable d[1];54};55static_assert(!__builtin_is_cpp_trivially_relocatable(I));56 57 58class J trivially_relocatable_if_eligible: virtual Trivial, NonRelocatable {59 NonRelocatable a;60};61static_assert(!__builtin_is_cpp_trivially_relocatable(J));62 63 64struct Incomplete; // expected-note {{forward declaration of 'Incomplete'}}65static_assert(__builtin_is_cpp_trivially_relocatable(Incomplete)); // expected-error {{incomplete type 'Incomplete' used in type trait expression}}66static_assert(__builtin_is_cpp_trivially_relocatable(int));67static_assert(__builtin_is_cpp_trivially_relocatable(void*));68static_assert(!__builtin_is_cpp_trivially_relocatable(int&));69static_assert(!__builtin_is_cpp_trivially_relocatable(Trivial&));70static_assert(__builtin_is_cpp_trivially_relocatable(const Trivial));71static_assert(__builtin_is_cpp_trivially_relocatable(Trivial[1]));72static_assert(__builtin_is_cpp_trivially_relocatable(Trivial[]));73 74struct WithConst {75 const int i;76};77static_assert(!__builtin_is_cpp_trivially_relocatable(WithConst));78 79struct WithConstExplicit trivially_relocatable_if_eligible {80 const int i;81};82static_assert(__builtin_is_cpp_trivially_relocatable(WithConstExplicit));83 84struct UserDtr {85 ~UserDtr();86};87 88struct DefaultedDtr {89 ~DefaultedDtr() = default;90};91struct UserMoveWithDefaultCopy {92 UserMoveWithDefaultCopy(UserMoveWithDefaultCopy&&);93 UserMoveWithDefaultCopy(const UserMoveWithDefaultCopy&) = default;94};95 96struct UserMove{97 UserMove(UserMove&&);98};99 100struct UserMoveDefault{101 UserMoveDefault(UserMoveDefault&&) = default;102};103 104struct UserMoveAssignDefault {105 UserMoveAssignDefault(UserMoveAssignDefault&&) = default;106 UserMoveAssignDefault& operator=(UserMoveAssignDefault&&) = default;107};108 109struct UserCopy{110 UserCopy(const UserCopy&);111};112 113struct UserCopyDefault{114 UserCopyDefault(const UserCopyDefault&) = default;115};116 117 118struct UserDeletedMove{119 UserDeletedMove(UserDeletedMove&&) = delete;120 UserDeletedMove(const UserDeletedMove&) = default;121};122 123static_assert(!__builtin_is_cpp_trivially_relocatable(UserDtr));124static_assert(__builtin_is_cpp_trivially_relocatable(DefaultedDtr));125static_assert(!__builtin_is_cpp_trivially_relocatable(UserMoveWithDefaultCopy));126static_assert(!__builtin_is_cpp_trivially_relocatable(UserMove));127static_assert(!__builtin_is_cpp_trivially_relocatable(UserCopy));128static_assert(!__builtin_is_cpp_trivially_relocatable(UserMoveDefault));129static_assert(__builtin_is_cpp_trivially_relocatable(UserMoveAssignDefault));130static_assert(__builtin_is_cpp_trivially_relocatable(UserCopyDefault));131static_assert(!__builtin_is_cpp_trivially_relocatable(UserDeletedMove));132 133template <typename T>134class TestDependentErrors trivially_relocatable_if_eligible : T {};135TestDependentErrors<Trivial> Ok;136TestDependentErrors<NonRelocatable> Err;137 138struct DeletedMove {139 DeletedMove(DeletedMove&&) = delete;140};141struct DeletedCopy {142 DeletedCopy(const DeletedCopy&) = delete;143};144struct DeletedMoveAssign {145 DeletedMoveAssign& operator=(DeletedMoveAssign&&) = delete;146};147 148struct DeletedDtr {149 ~DeletedDtr() = delete;150};151 152static_assert(!__builtin_is_cpp_trivially_relocatable(DeletedMove));153static_assert(!__builtin_is_cpp_trivially_relocatable(DeletedCopy));154static_assert(!__builtin_is_cpp_trivially_relocatable(DeletedMoveAssign));155static_assert(!__builtin_is_cpp_trivially_relocatable(DeletedDtr));156 157 158union U {159 G g;160};161static_assert(!__is_trivially_copyable(U));162static_assert(__builtin_is_cpp_trivially_relocatable(U));163 164 165template <typename T>166struct S {167 T t;168};169static_assert(__builtin_is_cpp_trivially_relocatable(S<int>));170static_assert(__builtin_is_cpp_trivially_relocatable(S<volatile int>));171static_assert(!__builtin_is_cpp_trivially_relocatable(S<const int>));172static_assert(!__builtin_is_cpp_trivially_relocatable(S<const int&>));173static_assert(!__builtin_is_cpp_trivially_relocatable(S<int&>));174static_assert(__builtin_is_cpp_trivially_relocatable(S<int[2]>));175static_assert(!__builtin_is_cpp_trivially_relocatable(S<const int[2]>));176static_assert(__builtin_is_cpp_trivially_relocatable(S<int[]>));177 178 179template <typename T>180struct SExplicit trivially_relocatable_if_eligible{181 T t;182};183static_assert(__builtin_is_cpp_trivially_relocatable(SExplicit<int>));184static_assert(__builtin_is_cpp_trivially_relocatable(SExplicit<volatile int>));185static_assert(__builtin_is_cpp_trivially_relocatable(SExplicit<const int>));186static_assert(__builtin_is_cpp_trivially_relocatable(SExplicit<const int&>));187static_assert(__builtin_is_cpp_trivially_relocatable(SExplicit<int&>));188static_assert(__builtin_is_cpp_trivially_relocatable(SExplicit<int[2]>));189static_assert(__builtin_is_cpp_trivially_relocatable(SExplicit<const int[2]>));190static_assert(__builtin_is_cpp_trivially_relocatable(SExplicit<int[]>));191 192 193namespace replaceable {194 195struct DeletedMove {196 DeletedMove(DeletedMove&&) = delete;197};198struct DeletedCopy {199 DeletedCopy(const DeletedCopy&) = delete;200};201struct DeletedMoveAssign {202 DeletedMoveAssign& operator=(DeletedMoveAssign&&) = delete;203};204 205struct DefaultedMove {206 DefaultedMove(DefaultedMove&&) = default;207 DefaultedMove& operator=(DefaultedMove&&) = default;208};209struct DefaultedCopy {210 DefaultedCopy(const DefaultedCopy&) = default;211 DefaultedCopy(DefaultedCopy&&) = default;212 DefaultedCopy& operator=(DefaultedCopy&&) = default;213};214struct DefaultedMoveAssign {215 DefaultedMoveAssign(DefaultedMoveAssign&&) = default;216 DefaultedMoveAssign& operator=(DefaultedMoveAssign&&) = default;217};218 219struct UserProvidedMove {220 UserProvidedMove(UserProvidedMove&&){};221};222struct UserProvidedCopy {223 UserProvidedCopy(const UserProvidedCopy&) {};224};225struct UserProvidedMoveAssign {226 UserProvidedMoveAssign& operator=(const UserProvidedMoveAssign&){return *this;};227};228 229struct Empty{};230static_assert(__builtin_is_replaceable(Empty));231struct S1 replaceable_if_eligible{};232static_assert(__builtin_is_replaceable(S1));233 234static_assert(__builtin_is_replaceable(DefaultedMove));235static_assert(__builtin_is_replaceable(DefaultedCopy));236static_assert(__builtin_is_replaceable(DefaultedMoveAssign));237 238static_assert(!__builtin_is_replaceable(DeletedMove));239static_assert(!__builtin_is_replaceable(DeletedCopy));240static_assert(!__builtin_is_replaceable(DeletedMoveAssign));241static_assert(!__builtin_is_replaceable(DeletedDtr));242 243static_assert(!__builtin_is_replaceable(UserProvidedMove));244static_assert(!__builtin_is_replaceable(UserProvidedCopy));245static_assert(!__builtin_is_replaceable(UserProvidedMoveAssign));246 247struct DeletedCopyTpl {248 template <typename U>249 DeletedCopyTpl(const U&) = delete;250};251static_assert(__builtin_is_replaceable(DeletedCopyTpl));252 253 254using NotReplaceable = DeletedMove;255 256template <typename T>257struct WithBase : T{};258 259template <typename T>260struct WithVBase : virtual T{};261 262struct WithVirtual {263 virtual ~WithVirtual() = default;264 WithVirtual(WithVirtual&&) = default;265 WithVirtual& operator=(WithVirtual&&) = default;266};267 268static_assert(__builtin_is_replaceable(S<int>));269static_assert(!__builtin_is_replaceable(S<volatile int>));270static_assert(!__builtin_is_replaceable(S<const int>));271static_assert(!__builtin_is_replaceable(S<const int&>));272static_assert(!__builtin_is_replaceable(S<int&>));273static_assert(__builtin_is_replaceable(S<int[2]>));274static_assert(!__builtin_is_replaceable(S<const int[2]>));275static_assert(__builtin_is_replaceable(WithBase<S<int>>));276static_assert(!__builtin_is_replaceable(WithBase<S<const int>>));277static_assert(!__builtin_is_replaceable(WithBase<UserProvidedMove>));278static_assert(__builtin_is_replaceable(WithVBase<S<int>>));279static_assert(!__builtin_is_replaceable(WithVBase<S<const int>>));280static_assert(!__builtin_is_replaceable(WithVBase<UserProvidedMove>));281static_assert(__builtin_is_replaceable(WithVirtual));282 283int n = 4; // expected-note 2{{declared here}}284static_assert(!__builtin_is_cpp_trivially_relocatable(int[n]));285// expected-warning@-1 {{variable length arrays in C++ are a Clang extension}}286// expected-note@-2 {{read of non-const variable 'n' is not allowed in a constant expression}}287static_assert(!__builtin_is_replaceable(int[n]));288// expected-warning@-1 {{variable length arrays in C++ are a Clang extension}}289// expected-note@-2 {{read of non-const variable 'n' is not allowed in a constant expression}}290 291 292struct U1 replaceable_if_eligible {293 ~U1() = delete;294 U1(U1&&) = default;295 U1& operator=(U1&&) = default;296 297};298static_assert(!__builtin_is_replaceable(U1));299 300struct U2 replaceable_if_eligible {301 U2(const U2&) = delete;302};303static_assert(!__builtin_is_replaceable(U2));304 305 306template <typename T>307struct WithVBaseExplicit replaceable_if_eligible : virtual T{};308static_assert(__builtin_is_replaceable(WithVBaseExplicit<S<int>>));309 310struct S42 trivially_relocatable_if_eligible replaceable_if_eligible {311 S42(S42&&);312 S42& operator=(S42&&) = default;313};314struct S43 trivially_relocatable_if_eligible replaceable_if_eligible {315 S43(S43&&) = default;316 S43& operator=(S43&&);317};318 319 320struct Copyable1Explicit replaceable_if_eligible {321 Copyable1Explicit(Copyable1Explicit const &) = default;322};323 324struct Copyable1 {325 Copyable1(Copyable1 const &) = default;326};327 328 329struct CopyAssign1Explicit replaceable_if_eligible {330 CopyAssign1Explicit & operator=(const CopyAssign1Explicit&) = default;331};332 333struct CopyAssign1 {334 CopyAssign1 & operator=(CopyAssign1 const &) = default;335};336 337struct UserDeleted1 {338 UserDeleted1(const UserDeleted1&) = delete;339};340static_assert(!__builtin_is_cpp_trivially_relocatable(UserDeleted1));341static_assert(!__builtin_is_replaceable(UserDeleted1));342 343struct UserDeleted2 {344 UserDeleted2(UserDeleted2&&) = delete;345};346static_assert(!__builtin_is_cpp_trivially_relocatable(UserDeleted2));347static_assert(!__builtin_is_replaceable(UserDeleted2));348 349 350struct UserDeleted3 {351 UserDeleted3 operator=(UserDeleted3);352};353static_assert(!__builtin_is_cpp_trivially_relocatable(UserDeleted3));354static_assert(!__builtin_is_replaceable(UserDeleted3));355 356struct UserDeleted4 {357 UserDeleted4 operator=(UserDeleted4&&);358};359static_assert(!__builtin_is_cpp_trivially_relocatable(UserDeleted4));360static_assert(!__builtin_is_replaceable(UserDeleted4));361 362}363 364 365void test__builtin_trivially_relocate() {366 struct S{ ~S();};367 struct R {};368 __builtin_trivially_relocate(); //expected-error {{too few arguments to function call, expected 3, have 0}}369 __builtin_trivially_relocate(0, 0, 0, 0); //expected-error {{too many arguments to function call, expected 3, have 4}}370 __builtin_trivially_relocate(0, 0, 0); //expected-error {{argument to '__builtin_trivially_relocate' must be a pointer}}371 __builtin_trivially_relocate((const int*)0, 0, 0); //expected-error {{argument to '__builtin_trivially_relocate' must be non-const}}372 __builtin_trivially_relocate((S*)0, 0, 0); //expected-error {{argument to '__builtin_trivially_relocate' must be relocatable}}373 __builtin_trivially_relocate((int*)0, 0, 0); //expected-error {{first and second arguments to '__builtin_trivially_relocate' must be of the same type}}374 375 __builtin_trivially_relocate((int*)0, (int*)0, (int*)0); // expected-error-re {{cannot initialize a value of type '__size_t' (aka '{{.*}}') with an rvalue of type 'int *'}}376 __builtin_trivially_relocate((int*)0, (int*)0, 0);377 __builtin_trivially_relocate((R*)0, (R*)0, 0);378}379 380void test__builtin_trivially_relocate(auto&& src, auto&&dest, auto size) {381 __builtin_trivially_relocate(src, dest, size); // #reloc1382}383 384void do_test__builtin_trivially_relocate() {385 struct S{ ~S();};386 struct R {};387 test__builtin_trivially_relocate((R*)0, (R*)0, 0);388 test__builtin_trivially_relocate((S*)0, (S*)0, 0);389 // expected-note@-1 {{'test__builtin_trivially_relocate<S *, S *, int>' requested here}}390 // expected-error@#reloc1 {{first argument to '__builtin_trivially_relocate' must be relocatable}}391}392 393 394namespace GH143599 {395struct A { ~A (); };396A::~A () = default;397 398static_assert (!__builtin_is_cpp_trivially_relocatable(A));399static_assert (!__builtin_is_replaceable(A));400 401struct B { B(const B&); };402B::B (const B&) = default;403 404static_assert (!__builtin_is_cpp_trivially_relocatable(B));405static_assert (!__builtin_is_replaceable(B));406 407struct C { C& operator=(const C&); };408C& C::operator=(const C&) = default;409 410static_assert (!__builtin_is_cpp_trivially_relocatable(C));411static_assert (!__builtin_is_replaceable(C));412}413 414namespace GH144232 {415 416struct E trivially_relocatable_if_eligible replaceable_if_eligible {417 E (E &&);418 E &operator= (E &&) = default;419};420 421struct F trivially_relocatable_if_eligible replaceable_if_eligible {422 F (F &&) = default;423 F &operator= (F &&);424};425 426struct G trivially_relocatable_if_eligible replaceable_if_eligible { G (G const &) = default; };427 428struct I trivially_relocatable_if_eligible replaceable_if_eligible { I &operator= (const I &) = default; };429 430struct J trivially_relocatable_if_eligible replaceable_if_eligible { J (J const &); };431struct K trivially_relocatable_if_eligible replaceable_if_eligible { K (K const &); };432 433 434 435static_assert (__builtin_is_replaceable (E));436static_assert (__builtin_is_cpp_trivially_relocatable(E));437static_assert (__builtin_is_replaceable (F));438static_assert (__builtin_is_cpp_trivially_relocatable(F));439static_assert (__builtin_is_replaceable (G));440static_assert (__builtin_is_cpp_trivially_relocatable(G));441static_assert (__builtin_is_replaceable (I));442static_assert (__builtin_is_cpp_trivially_relocatable(I));443static_assert (__builtin_is_replaceable (J));444static_assert (__builtin_is_cpp_trivially_relocatable(J));445static_assert (__builtin_is_replaceable (K));446static_assert (__builtin_is_cpp_trivially_relocatable(K));447 448}449