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