1 | // RUN: %check_clang_tidy %s modernize-use-override,cppcoreguidelines-explicit-virtual-functions %t -- -- -fexceptions |
2 | |
3 | #define ABSTRACT = 0 |
4 | |
5 | #define OVERRIDE override |
6 | #define VIRTUAL virtual |
7 | #define NOT_VIRTUAL |
8 | #define NOT_OVERRIDE |
9 | |
10 | #define MUST_USE_RESULT __attribute__((warn_unused_result)) |
11 | #define UNUSED __attribute__((unused)) |
12 | |
13 | struct MUST_USE_RESULT MustUseResultObject {}; |
14 | |
15 | struct IntPair { |
16 | int First, Second; |
17 | }; |
18 | |
19 | struct Base { |
20 | virtual ~Base() {} |
21 | virtual void a(); |
22 | virtual void b(); |
23 | virtual void c(); |
24 | virtual void d(); |
25 | virtual void d2(); |
26 | virtual void e() = 0; |
27 | virtual void f() = 0; |
28 | virtual void f2() const = 0; |
29 | virtual void g() = 0; |
30 | virtual void g2() = 0; |
31 | |
32 | virtual void j() const; |
33 | virtual MustUseResultObject k(); |
34 | virtual bool l() MUST_USE_RESULT UNUSED; |
35 | virtual bool n() MUST_USE_RESULT UNUSED; |
36 | |
37 | virtual void m(); |
38 | virtual void m2(); |
39 | virtual void o() __attribute__((unused)); |
40 | |
41 | virtual void r() &; |
42 | virtual void rr() &&; |
43 | |
44 | virtual void cv() const volatile; |
45 | virtual void cv2() const volatile; |
46 | |
47 | virtual void ne() noexcept(false); |
48 | virtual void t() throw(); |
49 | |
50 | virtual void il(IntPair); |
51 | }; |
52 | |
53 | struct SimpleCases : public Base { |
54 | public: |
55 | virtual ~SimpleCases(); |
56 | // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: prefer using 'override' or (rarely) 'final' instead of 'virtual' |
57 | // CHECK-FIXES: {{^}} ~SimpleCases() override; |
58 | |
59 | void a(); |
60 | // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: annotate this |
61 | // CHECK-FIXES: {{^}} void a() override; |
62 | |
63 | void b() override; |
64 | // CHECK-MESSAGES-NOT: warning: |
65 | // CHECK-FIXES: {{^}} void b() override; |
66 | |
67 | virtual void c(); |
68 | // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using |
69 | // CHECK-FIXES: {{^}} void c() override; |
70 | |
71 | virtual void d() override; |
72 | // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'virtual' is redundant since the function is already declared 'override' |
73 | // CHECK-FIXES: {{^}} void d() override; |
74 | |
75 | virtual void d2() final; |
76 | // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'virtual' is redundant since the function is already declared 'final' |
77 | // CHECK-FIXES: {{^}} void d2() final; |
78 | |
79 | virtual void e() = 0; |
80 | // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using |
81 | // CHECK-FIXES: {{^}} void e() override = 0; |
82 | |
83 | virtual void f()=0; |
84 | // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using |
85 | // CHECK-FIXES: {{^}} void f() override =0; |
86 | |
87 | virtual void f2() const=0; |
88 | // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using |
89 | // CHECK-FIXES: {{^}} void f2() const override =0; |
90 | |
91 | virtual void g() ABSTRACT; |
92 | // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using |
93 | // CHECK-FIXES: {{^}} void g() override ABSTRACT; |
94 | |
95 | virtual void j() const; |
96 | // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using |
97 | // CHECK-FIXES: {{^}} void j() const override; |
98 | |
99 | virtual MustUseResultObject k(); // Has an implicit attribute. |
100 | // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: prefer using |
101 | // CHECK-FIXES: {{^}} MustUseResultObject k() override; |
102 | |
103 | virtual bool l() MUST_USE_RESULT UNUSED; |
104 | // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using |
105 | // CHECK-FIXES: {{^}} bool l() override MUST_USE_RESULT UNUSED; |
106 | |
107 | virtual bool n() UNUSED MUST_USE_RESULT; |
108 | // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using |
109 | // CHECK-FIXES: {{^}} bool n() override UNUSED MUST_USE_RESULT; |
110 | |
111 | void m() override final; |
112 | // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: 'override' is redundant since the function is already declared 'final' |
113 | // CHECK-FIXES: {{^}} void m() final; |
114 | |
115 | virtual void m2() override final; |
116 | // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'virtual' and 'override' are redundant since the function is already declared 'final' |
117 | // CHECK-FIXES: {{^}} void m2() final; |
118 | |
119 | virtual void o() __attribute__((unused)); |
120 | // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using |
121 | // CHECK-FIXES: {{^}} void o() override __attribute__((unused)); |
122 | |
123 | virtual void ne() noexcept(false); |
124 | // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using |
125 | // CHECK-FIXES: {{^}} void ne() noexcept(false) override; |
126 | |
127 | virtual void t() throw(); |
128 | // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using |
129 | // CHECK-FIXES: {{^}} void t() throw() override; |
130 | |
131 | virtual /* */ void g2(); |
132 | // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: prefer using 'override' or (rarely) 'final' instead of 'virtual' |
133 | // CHECK-FIXES: {{^}} /* */ void g2() override; |
134 | }; |
135 | |
136 | // CHECK-MESSAGES-NOT: warning: |
137 | |
138 | void SimpleCases::c() {} |
139 | // CHECK-FIXES: {{^}}void SimpleCases::c() {} |
140 | |
141 | SimpleCases::~SimpleCases() {} |
142 | // CHECK-FIXES: {{^}}SimpleCases::~SimpleCases() {} |
143 | |
144 | struct DefaultedDestructor : public Base { |
145 | DefaultedDestructor() {} |
146 | virtual ~DefaultedDestructor() = default; |
147 | // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: prefer using |
148 | // CHECK-FIXES: {{^}} ~DefaultedDestructor() override = default; |
149 | }; |
150 | |
151 | struct FinalSpecified : public Base { |
152 | public: |
153 | virtual ~FinalSpecified() final; |
154 | // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: 'virtual' is redundant since the function is already declared 'final' |
155 | // CHECK-FIXES: {{^}} ~FinalSpecified() final; |
156 | |
157 | void b() final; |
158 | // CHECK-MESSAGES-NOT: warning: |
159 | // CHECK-FIXES: {{^}} void b() final; |
160 | |
161 | virtual void d() final; |
162 | // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'virtual' is redundant |
163 | // CHECK-FIXES: {{^}} void d() final; |
164 | |
165 | virtual void e() final = 0; |
166 | // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'virtual' is redundant |
167 | // CHECK-FIXES: {{^}} void e() final = 0; |
168 | |
169 | virtual void j() const final; |
170 | // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'virtual' is redundant |
171 | // CHECK-FIXES: {{^}} void j() const final; |
172 | |
173 | virtual bool l() final MUST_USE_RESULT UNUSED; |
174 | // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'virtual' is redundant |
175 | // CHECK-FIXES: {{^}} bool l() final MUST_USE_RESULT UNUSED; |
176 | }; |
177 | |
178 | struct InlineDefinitions : public Base { |
179 | public: |
180 | virtual ~InlineDefinitions() {} |
181 | // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: prefer using |
182 | // CHECK-FIXES: {{^}} ~InlineDefinitions() override {} |
183 | |
184 | void a() {} |
185 | // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: annotate this |
186 | // CHECK-FIXES: {{^}} void a() override {} |
187 | |
188 | void b() override {} |
189 | // CHECK-MESSAGES-NOT: warning: |
190 | // CHECK-FIXES: {{^}} void b() override {} |
191 | |
192 | virtual void c() |
193 | {} |
194 | // CHECK-MESSAGES: :[[@LINE-2]]:16: warning: prefer using |
195 | // CHECK-FIXES: {{^}} void c() override |
196 | |
197 | virtual void d() override {} |
198 | // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'virtual' is redundant |
199 | // CHECK-FIXES: {{^}} void d() override {} |
200 | |
201 | virtual void j() const |
202 | {} |
203 | // CHECK-MESSAGES: :[[@LINE-2]]:16: warning: prefer using |
204 | // CHECK-FIXES: {{^}} void j() const override |
205 | |
206 | virtual MustUseResultObject k() {} // Has an implicit attribute. |
207 | // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: prefer using |
208 | // CHECK-FIXES: {{^}} MustUseResultObject k() override {} |
209 | |
210 | virtual bool l() MUST_USE_RESULT UNUSED {} |
211 | // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using |
212 | // CHECK-FIXES: {{^}} bool l() override MUST_USE_RESULT UNUSED {} |
213 | |
214 | virtual void r() & |
215 | {} |
216 | // CHECK-MESSAGES: :[[@LINE-2]]:16: warning: prefer using |
217 | // CHECK-FIXES: {{^}} void r() & override |
218 | |
219 | virtual void rr() && |
220 | {} |
221 | // CHECK-MESSAGES: :[[@LINE-2]]:16: warning: prefer using |
222 | // CHECK-FIXES: {{^}} void rr() && override |
223 | |
224 | virtual void cv() const volatile |
225 | {} |
226 | // CHECK-MESSAGES: :[[@LINE-2]]:16: warning: prefer using |
227 | // CHECK-FIXES: {{^}} void cv() const volatile override |
228 | |
229 | virtual void cv2() const volatile // some comment |
230 | {} |
231 | // CHECK-MESSAGES: :[[@LINE-2]]:16: warning: prefer using |
232 | // CHECK-FIXES: {{^}} void cv2() const volatile override // some comment |
233 | }; |
234 | |
235 | struct DefaultArguments : public Base { |
236 | // Tests for default arguments (with initializer lists). |
237 | // Make sure the override fix is placed after the argument list. |
238 | void il(IntPair p = {.First: 1, .Second: (2 + (3))}) {} |
239 | // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: annotate this |
240 | // CHECK-FIXES: {{^}} void il(IntPair p = {1, (2 + (3))}) override {} |
241 | }; |
242 | |
243 | struct Macros : public Base { |
244 | // Tests for 'virtual' and 'override' being defined through macros. Basically |
245 | // give up for now. |
246 | NOT_VIRTUAL void a() NOT_OVERRIDE; |
247 | // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: annotate this |
248 | // CHECK-FIXES: {{^}} NOT_VIRTUAL void a() override NOT_OVERRIDE; |
249 | |
250 | VIRTUAL void b() NOT_OVERRIDE; |
251 | // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using |
252 | // CHECK-FIXES: {{^}} VIRTUAL void b() override NOT_OVERRIDE; |
253 | |
254 | NOT_VIRTUAL void c() OVERRIDE; |
255 | // CHECK-MESSAGES-NOT: warning: |
256 | // CHECK-FIXES: {{^}} NOT_VIRTUAL void c() OVERRIDE; |
257 | |
258 | VIRTUAL void d() OVERRIDE; |
259 | // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'virtual' is redundant |
260 | // CHECK-FIXES: {{^}} VIRTUAL void d() OVERRIDE; |
261 | |
262 | #define FUNC(return_type, name) return_type name() |
263 | FUNC(void, e); |
264 | // CHECK-FIXES: {{^}} FUNC(void, e); |
265 | |
266 | #define F virtual void f(); |
267 | F |
268 | // CHECK-FIXES: {{^}} F |
269 | |
270 | VIRTUAL void g() OVERRIDE final; |
271 | // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'virtual' and 'override' are redundant |
272 | // CHECK-FIXES: {{^}} VIRTUAL void g() final; |
273 | }; |
274 | |
275 | // Tests for templates. |
276 | template <typename T> struct TemplateBase { |
277 | virtual void f(T t); |
278 | }; |
279 | |
280 | template <typename T> struct DerivedFromTemplate : public TemplateBase<T> { |
281 | virtual void f(T t); |
282 | // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using |
283 | // CHECK-FIXES: {{^}} void f(T t) override; |
284 | }; |
285 | void f() { DerivedFromTemplate<int>().f(t: 2); } |
286 | |
287 | template <class C> |
288 | struct UnusedMemberInstantiation : public C { |
289 | virtual ~UnusedMemberInstantiation() {} |
290 | // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: prefer using |
291 | // CHECK-FIXES: {{^}} ~UnusedMemberInstantiation() override {} |
292 | }; |
293 | struct IntantiateWithoutUse : public UnusedMemberInstantiation<Base> {}; |
294 | |
295 | struct Base2 { |
296 | virtual ~Base2() {} |
297 | virtual void a(); |
298 | }; |
299 | |
300 | // The OverrideAttr isn't propagated to specializations in all cases. Make sure |
301 | // we don't add "override" a second time. |
302 | template <int I> |
303 | struct MembersOfSpecializations : public Base2 { |
304 | void a() override; |
305 | // CHECK-MESSAGES-NOT: warning: |
306 | // CHECK-FIXES: {{^}} void a() override; |
307 | }; |
308 | template <> void MembersOfSpecializations<3>::a() {} |
309 | void ff() { MembersOfSpecializations<3>().a(); }; |
310 | |
311 | // In case try statement is used as a method body, |
312 | // make sure that override fix is placed before try keyword. |
313 | struct TryStmtAsBody : public Base { |
314 | void a() try |
315 | // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: annotate this |
316 | // CHECK-FIXES: {{^}} void a() override try |
317 | { b(); } catch(...) { c(); } |
318 | |
319 | virtual void d() try |
320 | // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using |
321 | // CHECK-FIXES: {{^}} void d() override try |
322 | { e(); } catch(...) { f(); } |
323 | }; |
324 | |