1*89a1d03eSRichard // RUN: %check_clang_tidy %s misc-new-delete-overloads %t 2*89a1d03eSRichard 3*89a1d03eSRichard typedef decltype(sizeof(int)) size_t; 4*89a1d03eSRichard 5*89a1d03eSRichard struct S { 6*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE+1]]:9: warning: declaration of 'operator new' has no matching declaration of 'operator delete' at the same scope [misc-new-delete-overloads] 7*89a1d03eSRichard void *operator new(size_t size) noexcept; 8*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE+1]]:9: warning: declaration of 'operator new[]' has no matching declaration of 'operator delete[]' at the same scope 9*89a1d03eSRichard void *operator new[](size_t size) noexcept; 10*89a1d03eSRichard }; 11*89a1d03eSRichard 12*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE+1]]:7: warning: declaration of 'operator new' has no matching declaration of 'operator delete' at the same scope 13*89a1d03eSRichard void *operator new(size_t size) noexcept(false); 14*89a1d03eSRichard 15*89a1d03eSRichard struct U { 16*89a1d03eSRichard void *operator new(size_t size) noexcept; 17*89a1d03eSRichard void operator delete(void *ptr) noexcept; 18*89a1d03eSRichard 19*89a1d03eSRichard void *operator new[](size_t) noexcept; 20*89a1d03eSRichard void operator delete[](void *) noexcept; 21*89a1d03eSRichard }; 22*89a1d03eSRichard 23*89a1d03eSRichard struct Z { 24*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE+1]]:8: warning: declaration of 'operator delete' has no matching declaration of 'operator new' at the same scope 25*89a1d03eSRichard void operator delete(void *ptr) noexcept; 26*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE+1]]:8: warning: declaration of 'operator delete[]' has no matching declaration of 'operator new[]' at the same scope 27*89a1d03eSRichard void operator delete[](void *ptr) noexcept; 28*89a1d03eSRichard }; 29*89a1d03eSRichard 30*89a1d03eSRichard struct A { 31*89a1d03eSRichard void *operator new(size_t size, Z) noexcept; // ok, placement new 32*89a1d03eSRichard }; 33*89a1d03eSRichard 34*89a1d03eSRichard struct B { 35*89a1d03eSRichard void operator delete(void *ptr, A) noexcept; // ok, placement delete 36*89a1d03eSRichard }; 37*89a1d03eSRichard 38*89a1d03eSRichard // It is okay to have a class with an inaccessible free store operator. 39*89a1d03eSRichard struct C { 40*89a1d03eSRichard void *operator new(size_t, A) noexcept; // ok, placement new 41*89a1d03eSRichard private: 42*89a1d03eSRichard void operator delete(void *) noexcept; 43*89a1d03eSRichard }; 44*89a1d03eSRichard 45*89a1d03eSRichard // It is also okay to have a class with a delete free store operator. 46*89a1d03eSRichard struct D { 47*89a1d03eSRichard void *operator new(size_t, A) noexcept; // ok, placement new 48*89a1d03eSRichard void operator delete(void *) noexcept = delete; 49*89a1d03eSRichard }; 50*89a1d03eSRichard 51*89a1d03eSRichard struct E : U { 52*89a1d03eSRichard void *operator new(size_t) noexcept; // okay, we inherit operator delete from U 53*89a1d03eSRichard }; 54*89a1d03eSRichard 55*89a1d03eSRichard struct F : S { 56*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE+1]]:9: warning: declaration of 'operator new' has no matching declaration of 'operator delete' at the same scope 57*89a1d03eSRichard void *operator new(size_t) noexcept; 58*89a1d03eSRichard }; 59*89a1d03eSRichard 60*89a1d03eSRichard class G { 61*89a1d03eSRichard void operator delete(void *) noexcept; 62*89a1d03eSRichard }; 63*89a1d03eSRichard 64*89a1d03eSRichard struct H : G { 65*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE+1]]:9: warning: declaration of 'operator new' has no matching declaration of 'operator delete' at the same scope 66*89a1d03eSRichard void *operator new(size_t) noexcept; // base class operator is inaccessible 67*89a1d03eSRichard }; 68*89a1d03eSRichard 69*89a1d03eSRichard template <typename Base> struct Derived : Base { 70*89a1d03eSRichard void operator delete(void *); 71*89a1d03eSRichard }; 72