TestNonMemMovableStd.cpp (5931B)
1 #define MOZ_NEEDS_MEMMOVABLE_TYPE __attribute__((annotate("moz_needs_memmovable_type"))) 2 #define MOZ_RUNINIT __attribute__((annotate("moz_global_var"))) 3 4 template<class T> 5 class MOZ_NEEDS_MEMMOVABLE_TYPE Mover { T mForceInst; }; // expected-error-re 10 {{Cannot instantiate 'Mover<{{.*}}>' with non-memmovable template argument '{{.*}}'}} 6 7 template<class T> 8 struct MOZ_NEEDS_MEMMOVABLE_TYPE PtrMover { T* mForceInst; }; 9 10 namespace std { 11 // In theory defining things in std:: like this invokes undefined 12 // behavior, but in practice it's good enough for this test case. 13 template<class C> class basic_string { // expected-note 2 {{'std::basic_string<char>' is a non-memmove()able type because it is an stl-provided type not guaranteed to be memmove-able}} expected-note {{'std::string' (aka 'basic_string<char>') is a non-memmove()able type because it is an stl-provided type not guaranteed to be memmove-able}} 14 public: 15 basic_string(); 16 basic_string(const basic_string&); 17 basic_string(basic_string&&); 18 basic_string& operator=(const basic_string&); 19 basic_string& operator=(basic_string&&); 20 ~basic_string(); 21 }; 22 typedef basic_string<char> string; 23 template<class T, class U> class pair { T mT; U mU; }; // expected-note-re 4 {{'std::pair<bool, {{.*}}>' is a non-memmove()able type because it has a template argument non-memmove()able type '{{.*}}'}} 24 25 struct has_nontrivial_dtor { // expected-note 2 {{'std::has_nontrivial_dtor' is a non-memmove()able type because it is an stl-provided type not guaranteed to be memmove-able}} 26 has_nontrivial_dtor() = default; 27 ~has_nontrivial_dtor(); 28 }; 29 struct has_nontrivial_copy { // expected-note 2 {{'std::has_nontrivial_copy' is a non-memmove()able type because it is an stl-provided type not guaranteed to be memmove-able}} 30 has_nontrivial_copy() = default; 31 has_nontrivial_copy(const has_nontrivial_copy&); 32 has_nontrivial_copy& operator=(const has_nontrivial_copy&); 33 }; 34 struct has_nontrivial_move { // expected-note 2 {{'std::has_nontrivial_move' is a non-memmove()able type because it is an stl-provided type not guaranteed to be memmove-able}} 35 has_nontrivial_move() = default; 36 has_nontrivial_move(const has_nontrivial_move&); 37 has_nontrivial_move& operator=(const has_nontrivial_move&); 38 }; 39 struct has_trivial_dtor { 40 has_trivial_dtor() = default; 41 ~has_trivial_dtor() = default; 42 }; 43 struct has_trivial_copy { 44 has_trivial_copy() = default; 45 has_trivial_copy(const has_trivial_copy&) = default; 46 has_trivial_copy& operator=(const has_trivial_copy&) = default; 47 }; 48 struct has_trivial_move { 49 has_trivial_move() = default; 50 has_trivial_move(const has_trivial_move&) = default; 51 has_trivial_move& operator=(const has_trivial_move&) = default; 52 }; 53 54 template<class T> 55 struct default_delete { 56 void operator()( T* ptr ) { delete ptr; } 57 }; 58 59 template <typename T, typename D=default_delete<T>> 60 struct unique_ptr { // expected-note {{std::unique_ptr<std::basic_string<char>, custom_deleter<std::basic_string<char>>>' is a non-memmove()able type because it is an stl-provided type not guaranteed to be memmove-able}} 61 T * ptr; 62 D del; 63 unique_ptr() = default; 64 unique_ptr(T *p); 65 unique_ptr(unique_ptr const&) = delete; 66 unique_ptr(unique_ptr &&); 67 ~unique_ptr(); 68 }; 69 } 70 71 class HasString { std::string m; }; // expected-note {{'HasString' is a non-memmove()able type because member 'm' is a non-memmove()able type 'std::string' (aka 'basic_string<char>')}} 72 73 template<class T> 74 struct custom_deleter : std::default_delete<T> { 75 std::string m = {}; 76 }; 77 78 MOZ_RUNINIT static Mover<std::string> bad; // expected-note-re {{instantiation of 'Mover<std::basic_string<char>{{ ?}}>' requested here}} 79 MOZ_RUNINIT static Mover<HasString> bad_mem; // expected-note {{instantiation of 'Mover<HasString>' requested here}} 80 static Mover<std::pair<bool, int>> good; 81 MOZ_RUNINIT static Mover<std::pair<bool, std::string>> not_good; // expected-note-re {{instantiation of 'Mover<std::pair<bool, std::basic_string<char>{{ ?}}>{{ ?}}>' requested here}} 82 83 MOZ_RUNINIT static Mover<std::has_nontrivial_dtor> nontrivial_dtor; // expected-note {{instantiation of 'Mover<std::has_nontrivial_dtor>' requested here}} 84 static Mover<std::has_nontrivial_copy> nontrivial_copy; // expected-note {{instantiation of 'Mover<std::has_nontrivial_copy>' requested here}} 85 static Mover<std::has_nontrivial_move> nontrivial_move; // expected-note {{instantiation of 'Mover<std::has_nontrivial_move>' requested here}} 86 static Mover<std::has_trivial_dtor> trivial_dtor; 87 static Mover<std::has_trivial_copy> trivial_copy; 88 static Mover<std::has_trivial_move> trivial_move; 89 90 MOZ_RUNINIT static Mover<std::pair<bool, std::has_nontrivial_dtor>> pair_nontrivial_dtor; // expected-note {{instantiation of 'Mover<std::pair<bool, std::has_nontrivial_dtor>>' requested here}} 91 static Mover<std::pair<bool, std::has_nontrivial_copy>> pair_nontrivial_copy; // expected-note {{instantiation of 'Mover<std::pair<bool, std::has_nontrivial_copy>>' requested here}} 92 static Mover<std::pair<bool, std::has_nontrivial_move>> pair_nontrivial_move; // expected-note {{instantiation of 'Mover<std::pair<bool, std::has_nontrivial_move>>' requested here}} 93 static Mover<std::pair<bool, std::has_trivial_dtor>> pair_trivial_dtor; 94 static Mover<std::pair<bool, std::has_trivial_copy>> pair_trivial_copy; 95 static Mover<std::pair<bool, std::has_trivial_move>> pair_trivial_move; 96 97 MOZ_RUNINIT static Mover<std::unique_ptr<int>> a_good_unique_ptr; 98 99 // unique_ptr don't require memmove()able 1st template argument 100 MOZ_RUNINIT static Mover<std::unique_ptr<std::string>> another_good_unique_ptr; 101 MOZ_RUNINIT static Mover<std::unique_ptr<std::string, custom_deleter<std::string>>> bad_unique_ptr; // expected-note {{instantiation of 'Mover<std::unique_ptr<std::basic_string<char>, custom_deleter<std::basic_string<char>>>>' requested here}} 102 103 struct Fwd; 104 // Not enough information to complain 105 static PtrMover<std::unique_ptr<Fwd>> bad_fwd_unique_ptr;