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