1 | // RUN: %check_clang_tidy %s bugprone-virtual-near-miss %t |
2 | |
3 | class NoDefinedClass1; |
4 | class NoDefinedClass2; |
5 | |
6 | struct Base { |
7 | virtual void func(); |
8 | virtual void gunk(); |
9 | virtual ~Base(); |
10 | virtual Base &operator=(const Base &); |
11 | virtual NoDefinedClass1 *f(); |
12 | }; |
13 | |
14 | struct Derived : Base { |
15 | // Should not warn "do you want to override 'gunk'?", because gunk is already |
16 | // overriden by this class. |
17 | virtual void funk(); |
18 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: method 'Derived::funk' has a similar name and the same signature as virtual method 'Base::func'; did you mean to override it? [bugprone-virtual-near-miss] |
19 | // CHECK-FIXES: virtual void func(); |
20 | |
21 | void func2(); |
22 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: method 'Derived::func2' has {{.*}} 'Base::func' |
23 | // CHECK-FIXES: void func(); |
24 | |
25 | void func22(); // Should not warn. |
26 | |
27 | void gunk(); // Should not warn: gunk is override. |
28 | |
29 | void fun(); |
30 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: method 'Derived::fun' has {{.*}} 'Base::func' |
31 | // CHECK-FIXES: void func(); |
32 | |
33 | Derived &operator==(const Base &); // Should not warn: operators are ignored. |
34 | |
35 | virtual NoDefinedClass2 *f1(); // Should not crash: non-defined class return type is ignored. |
36 | }; |
37 | |
38 | template <typename T> |
39 | struct TBase { |
40 | virtual void tfunc(T t); |
41 | }; |
42 | |
43 | template <typename T> |
44 | struct TDerived : TBase<T> { |
45 | virtual void tfunk(T t); |
46 | // Should not apply fix for template. |
47 | // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: method 'TDerived<double>::tfunk' has {{.*}} 'TBase<double>::tfunc' |
48 | // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: method 'TDerived<int>::tfunk' has {{.*}} 'TBase<int>::tfunc' |
49 | // CHECK-FIXES: virtual void tfunk(T t); |
50 | }; |
51 | |
52 | TDerived<int> T1; |
53 | TDerived<double> T2; |
54 | |
55 | // Should not fix macro definition |
56 | #define MACRO1 void funcM() |
57 | // CHECK-FIXES: #define MACRO1 void funcM() |
58 | #define MACRO2(m) void m() |
59 | // CHECK-FIXES: #define MACRO2(m) void m() |
60 | |
61 | struct DerivedMacro : Base { |
62 | MACRO1; |
63 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: method 'DerivedMacro::funcM' has {{.*}} 'Base::func' |
64 | // CHECK-FIXES: MACRO1; |
65 | |
66 | MACRO2(func3); |
67 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: method 'DerivedMacro::func3' has {{.*}} 'Base::func' |
68 | // CHECK-FIXES: MACRO2(func); |
69 | }; |
70 | |
71 | typedef Derived derived_type; |
72 | |
73 | class Father { |
74 | public: |
75 | Father(); |
76 | virtual void func(); |
77 | virtual Father *create(int i); |
78 | virtual Base &&generate(); |
79 | virtual Base *canonical(Derived D); |
80 | }; |
81 | |
82 | class Mother { |
83 | public: |
84 | Mother(); |
85 | static void method(); |
86 | virtual int method(int argc, const char **argv); |
87 | virtual int method(int argc) const; |
88 | virtual int decay(const char *str); |
89 | }; |
90 | |
91 | class Child : private Father, private Mother { |
92 | public: |
93 | Child(); |
94 | |
95 | virtual void func2(); |
96 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: method 'Child::func2' has {{.*}} 'Father::func' |
97 | // CHECK-FIXES: virtual void func(); |
98 | |
99 | int methoe(int x, char **strs); // Should not warn: parameter types don't match. |
100 | |
101 | int methoe(int x); |
102 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: method 'Child::methoe' has {{.*}} 'Mother::method' |
103 | // CHECK-FIXES: int method(int x); |
104 | |
105 | void methof(int x, const char **strs); // Should not warn: return types don't match. |
106 | |
107 | int methoh(int x, const char **strs); |
108 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: method 'Child::methoh' has {{.*}} 'Mother::method' |
109 | // CHECK-FIXES: int method(int x, const char **strs); |
110 | |
111 | virtual Child *creat(int i); |
112 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: method 'Child::creat' has {{.*}} 'Father::create' |
113 | // CHECK-FIXES: virtual Child *create(int i); |
114 | |
115 | virtual Derived &&generat(); |
116 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: method 'Child::generat' has {{.*}} 'Father::generate' |
117 | // CHECK-FIXES: virtual Derived &&generate(); |
118 | |
119 | int decaz(const char str[]); |
120 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: method 'Child::decaz' has {{.*}} 'Mother::decay' |
121 | // CHECK-FIXES: int decay(const char str[]); |
122 | |
123 | operator bool(); |
124 | |
125 | derived_type *canonica(derived_type D); |
126 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: method 'Child::canonica' has {{.*}} 'Father::canonical' |
127 | // CHECK-FIXES: derived_type *canonical(derived_type D); |
128 | |
129 | private: |
130 | void funk(); |
131 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: method 'Child::funk' has {{.*}} 'Father::func' |
132 | // CHECK-FIXES: void func(); |
133 | }; |
134 | |