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
13struct MUST_USE_RESULT MustUseResultObject {};
14
15struct IntPair {
16 int First, Second;
17};
18
19struct 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
53struct SimpleCases : public Base {
54public:
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
138void SimpleCases::c() {}
139// CHECK-FIXES: {{^}}void SimpleCases::c() {}
140
141SimpleCases::~SimpleCases() {}
142// CHECK-FIXES: {{^}}SimpleCases::~SimpleCases() {}
143
144struct 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
151struct FinalSpecified : public Base {
152public:
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
178struct InlineDefinitions : public Base {
179public:
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
235struct 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
243struct 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.
276template <typename T> struct TemplateBase {
277 virtual void f(T t);
278};
279
280template <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};
285void f() { DerivedFromTemplate<int>().f(t: 2); }
286
287template <class C>
288struct UnusedMemberInstantiation : public C {
289 virtual ~UnusedMemberInstantiation() {}
290 // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: prefer using
291 // CHECK-FIXES: {{^}} ~UnusedMemberInstantiation() override {}
292};
293struct IntantiateWithoutUse : public UnusedMemberInstantiation<Base> {};
294
295struct 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.
302template <int I>
303struct MembersOfSpecializations : public Base2 {
304 void a() override;
305 // CHECK-MESSAGES-NOT: warning:
306 // CHECK-FIXES: {{^}} void a() override;
307};
308template <> void MembersOfSpecializations<3>::a() {}
309void 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.
313struct 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

source code of clang-tools-extra/test/clang-tidy/checkers/modernize/use-override.cpp