1 // RUN: %check_clang_tidy %s misc-new-delete-overloads %t
2 
3 typedef decltype(sizeof(int)) size_t;
4 
5 struct S {
6   // 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   void *operator new(size_t size) noexcept;
8   // CHECK-MESSAGES: :[[@LINE+1]]:9: warning: declaration of 'operator new[]' has no matching declaration of 'operator delete[]' at the same scope
9   void *operator new[](size_t size) noexcept;
10 };
11 
12 // CHECK-MESSAGES: :[[@LINE+1]]:7: warning: declaration of 'operator new' has no matching declaration of 'operator delete' at the same scope
13 void *operator new(size_t size) noexcept(false);
14 
15 struct T {
16   // Sized deallocations are not enabled by default, and so this new/delete pair
17   // does not match. However, we expect only one warning, for the new, because
18   // the operator delete is a placement delete and we do not warn on mismatching
19   // placement operations.
20   // CHECK-MESSAGES: :[[@LINE+1]]:9: warning: declaration of 'operator new' has no matching declaration of 'operator delete' at the same scope
21   void *operator new(size_t size) noexcept;
22   void operator delete(void *ptr, size_t) noexcept; // ok only if sized deallocation is enabled
23 };
24 
25 struct U {
26   void *operator new(size_t size) noexcept;
27   void operator delete(void *ptr) noexcept;
28 
29   void *operator new[](size_t) noexcept;
30   void operator delete[](void *) noexcept;
31 };
32 
33 struct Z {
34   // CHECK-MESSAGES: :[[@LINE+1]]:8: warning: declaration of 'operator delete' has no matching declaration of 'operator new' at the same scope
35   void operator delete(void *ptr) noexcept;
36   // CHECK-MESSAGES: :[[@LINE+1]]:8: warning: declaration of 'operator delete[]' has no matching declaration of 'operator new[]' at the same scope
37   void operator delete[](void *ptr) noexcept;
38 };
39 
40 struct A {
41   void *operator new(size_t size, Z) noexcept; // ok, placement new
42 };
43 
44 struct B {
45   void operator delete(void *ptr, A) noexcept; // ok, placement delete
46 };
47 
48 // It is okay to have a class with an inaccessible free store operator.
49 struct C {
50   void *operator new(size_t, A) noexcept; // ok, placement new
51 private:
52   void operator delete(void *) noexcept;
53 };
54 
55 // It is also okay to have a class with a delete free store operator.
56 struct D {
57   void *operator new(size_t, A) noexcept; // ok, placement new
58   void operator delete(void *) noexcept = delete;
59 };
60 
61 struct E : U {
62   void *operator new(size_t) noexcept; // okay, we inherit operator delete from U
63 };
64 
65 struct F : S {
66   // CHECK-MESSAGES: :[[@LINE+1]]:9: warning: declaration of 'operator new' has no matching declaration of 'operator delete' at the same scope
67   void *operator new(size_t) noexcept;
68 };
69 
70 class G {
71   void operator delete(void *) noexcept;
72 };
73 
74 struct H : G {
75   // CHECK-MESSAGES: :[[@LINE+1]]:9: warning: declaration of 'operator new' has no matching declaration of 'operator delete' at the same scope
76   void *operator new(size_t) noexcept; // base class operator is inaccessible
77 };
78 
79 template <typename Base> struct Derived : Base {
80   void operator delete(void *);
81 };
82