1 // RUN: %clang_cc1 -std=c++1z -fsyntax-only -verify %s 2 // RUN: %clang_cc1 -std=c++03 -fsyntax-only -verify %s 3 // RUN: %clang_cc1 -std=c++03 -faligned-allocation -fsyntax-only -verify %s 4 // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s 5 // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -fsized-deallocation %s 6 7 #if !__has_builtin(__builtin_operator_new) || !__has_builtin(__builtin_operator_delete) 8 #error builtins should always be available 9 #endif 10 11 #if __has_builtin(__builtin_operator_new) != 201802L || \ 12 __has_builtin(__builtin_operator_delete) != 201802L 13 #error builtin should report updated value 14 #endif 15 16 typedef __SIZE_TYPE__ size_t; 17 namespace std { 18 struct nothrow_t {}; 19 #if __cplusplus >= 201103L 20 enum class align_val_t : size_t {}; 21 #else 22 enum align_val_t { 23 // We can't force an underlying type when targeting windows. 24 # ifndef _WIN32 25 __zero = 0, __max = (size_t)-1 26 # endif 27 }; 28 #endif 29 } 30 std::nothrow_t nothrow; 31 32 void *operator new(size_t); // expected-note 1+ {{candidate function}} 33 void operator delete(void *); // expected-note 1+ {{candidate function}} 34 35 // Declare the reserved placement operators. 36 void *operator new(size_t, void*) throw(); // expected-note 1+ {{candidate function}} 37 void operator delete(void *, void *)throw(); // expected-note 1+ {{candidate function}} 38 void *operator new[](size_t, void*) throw(); 39 void operator delete[](void*, void*) throw(); 40 41 // Declare the replaceable global allocation operators. 42 void *operator new(size_t, const std::nothrow_t &) throw(); // expected-note 1+ {{candidate function}} 43 void *operator new[](size_t, const std::nothrow_t &) throw(); 44 void operator delete(void *, const std::nothrow_t &)throw(); // expected-note 1+ {{candidate function}} 45 void operator delete[](void *, const std::nothrow_t &) throw(); 46 47 // aligned allocation and deallocation functions. 48 void* operator new ( size_t count, std::align_val_t al); // expected-note 1+ {{candidate function}} 49 void operator delete(void *, std::align_val_t); // expected-note 1+ {{candidate}} 50 #ifndef __cpp_aligned_new 51 // expected-note@-3 1+ {{non-usual 'operator new' declared here}} 52 // expected-note@-3 1+ {{non-usual 'operator delete' declared here}} 53 #endif 54 void *operator new[](size_t count, std::align_val_t al); 55 void operator delete[](void*, std::align_val_t); 56 57 void operator delete(void *, size_t); // expected-note 1+ {{candidate}} 58 #ifndef __cpp_sized_deallocation 59 // expected-note@-2 1+ {{non-usual 'operator delete' declared here}} 60 #endif 61 void operator delete[](void*, size_t); 62 63 // Declare some other placemenet operators. 64 void *operator new(size_t, void*, bool) throw(); // expected-note 1+ {{candidate function}} 65 void *operator new[](size_t, void*, bool) throw(); 66 67 void *NP = 0; 68 69 void test_typo_in_args() { 70 __builtin_operator_new(DNE); // expected-error {{undeclared identifier 'DNE'}} 71 __builtin_operator_new(DNE, DNE2); // expected-error {{undeclared identifier 'DNE'}} expected-error {{'DNE2'}} 72 __builtin_operator_delete(DNE); // expected-error {{'DNE'}} 73 __builtin_operator_delete(DNE, DNE2); // expected-error {{'DNE'}} expected-error {{'DNE2'}} 74 } 75 76 void test_arg_types() { 77 __builtin_operator_new(NP); // expected-error {{no matching function for call to 'operator new'}} 78 __builtin_operator_new(NP, std::align_val_t(0)); // expected-error {{no matching function for call to 'operator new'}}} 79 } 80 void test_return_type() { 81 int w = __builtin_operator_new(42); // expected-error {{cannot initialize a variable of type 'int' with an rvalue of type 'void *'}} 82 int y = __builtin_operator_delete(NP); // expected-error {{cannot initialize a variable of type 'int' with an rvalue of type 'void'}} 83 } 84 85 void test_aligned_new() { 86 #ifdef __cpp_aligned_new 87 void *p = __builtin_operator_new(42, std::align_val_t(2)); 88 __builtin_operator_delete(p, std::align_val_t(2)); 89 #else 90 // FIXME: We've manually declared the aligned new/delete overloads, 91 // but LangOpts::AlignedAllocation is false. Should our overloads be considered 92 // usual allocation/deallocation functions? 93 void *p = __builtin_operator_new(42, std::align_val_t(2)); // expected-error {{call to '__builtin_operator_new' selects non-usual allocation function}} 94 __builtin_operator_delete(p, std::align_val_t(2)); // expected-error {{call to '__builtin_operator_delete' selects non-usual deallocation function}} 95 #endif 96 } 97 98 void test_sized_delete() { 99 #ifdef __cpp_sized_deallocation 100 __builtin_operator_delete(NP, 4); 101 #else 102 __builtin_operator_delete(NP, 4); // expected-error {{call to '__builtin_operator_delete' selects non-usual deallocation function}} 103 #endif 104 } 105 106 void *operator new(size_t, bool); // expected-note 1+ {{candidate}} 107 // expected-note@-1 {{non-usual 'operator new' declared here}} 108 void operator delete(void *, bool); // expected-note 1+ {{candidate}} 109 // expected-note@-1 {{non-usual 'operator delete' declared here}} 110 111 void test_non_usual() { 112 __builtin_operator_new(42, true); // expected-error {{call to '__builtin_operator_new' selects non-usual allocation function}} 113 __builtin_operator_delete(NP, false); // expected-error {{call to '__builtin_operator_delete' selects non-usual deallocation function}} 114 } 115 116 template <int ID> 117 struct Tag {}; 118 struct ConvertsToTypes { 119 operator std::align_val_t() const; 120 operator Tag<0>() const; 121 }; 122 123 void *operator new(size_t, Tag<0>); // expected-note 0+ {{candidate}} 124 void operator delete(void *, Tag<0>); // expected-note 0+ {{candidate}} 125 126 void test_ambiguous() { 127 #ifdef __cpp_aligned_new 128 ConvertsToTypes cvt; 129 __builtin_operator_new(42, cvt); // expected-error {{call to 'operator new' is ambiguous}} 130 __builtin_operator_delete(NP, cvt); // expected-error {{call to 'operator delete' is ambiguous}} 131 #endif 132 } 133 134 void test_no_args() { 135 __builtin_operator_new(); // expected-error {{no matching function for call to 'operator new'}} 136 __builtin_operator_delete(); // expected-error {{no matching function for call to 'operator delete'}} 137 } 138 139 void test_no_matching_fn() { 140 Tag<1> tag; 141 __builtin_operator_new(42, tag); // expected-error {{no matching function for call to 'operator new'}} 142 __builtin_operator_delete(NP, tag); // expected-error {{no matching function for call to 'operator delete'}} 143 } 144 145 template <class Tp, class Up, class RetT> 146 void test_dependent_call(Tp new_arg, Up delete_arg, RetT) { 147 RetT ret = __builtin_operator_new(new_arg); 148 __builtin_operator_delete(delete_arg); 149 } 150 template void test_dependent_call(int, int*, void*); 151 152 void test_const_attribute() { 153 __builtin_operator_new(42); // expected-warning {{ignoring return value of function declared with const attribute}} 154 #ifdef __cpp_aligned_new 155 __builtin_operator_new(42, std::align_val_t(8)); // expected-warning {{ignoring return value of function declared with const attribute}} 156 #endif 157 } 158