xref: /llvm-project/clang-tools-extra/test/clang-tidy/checkers/modernize/use-override.cpp (revision 5992b3272b29e071f6f5a4807a4e0c23e88c310d)
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 {
~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   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 
c()138 void SimpleCases::c() {}
139 // CHECK-FIXES: {{^}}void SimpleCases::c() {}
140 
~SimpleCases()141 SimpleCases::~SimpleCases() {}
142 // CHECK-FIXES: {{^}}SimpleCases::~SimpleCases() {}
143 
144 struct DefaultedDestructor : public Base {
DefaultedDestructorDefaultedDestructor145   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:
~InlineDefinitionsInlineDefinitions180   virtual ~InlineDefinitions() {}
181   // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: prefer using
182   // CHECK-FIXES: {{^}}  ~InlineDefinitions() override {}
183 
aInlineDefinitions184   void a() {}
185   // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: annotate this
186   // CHECK-FIXES: {{^}}  void a() override {}
187 
bInlineDefinitions188   void b() override {}
189   // CHECK-MESSAGES-NOT: warning:
190   // CHECK-FIXES: {{^}}  void b() override {}
191 
cInlineDefinitions192   virtual void c()
193   {}
194   // CHECK-MESSAGES: :[[@LINE-2]]:16: warning: prefer using
195   // CHECK-FIXES: {{^}}  void c() override
196 
dInlineDefinitions197   virtual void d() override {}
198   // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'virtual' is redundant
199   // CHECK-FIXES: {{^}}  void d() override {}
200 
jInlineDefinitions201   virtual void j() const
202   {}
203   // CHECK-MESSAGES: :[[@LINE-2]]:16: warning: prefer using
204   // CHECK-FIXES: {{^}}  void j() const override
205 
kInlineDefinitions206   virtual MustUseResultObject k() {}  // Has an implicit attribute.
207   // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: prefer using
208   // CHECK-FIXES: {{^}}  MustUseResultObject k() override {}
209 
lInlineDefinitions210   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 
rInlineDefinitions214   virtual void r() &
215   {}
216   // CHECK-MESSAGES: :[[@LINE-2]]:16: warning: prefer using
217   // CHECK-FIXES: {{^}}  void r() & override
218 
rrInlineDefinitions219   virtual void rr() &&
220   {}
221   // CHECK-MESSAGES: :[[@LINE-2]]:16: warning: prefer using
222   // CHECK-FIXES: {{^}}  void rr() && override
223 
cvInlineDefinitions224   virtual void cv() const volatile
225   {}
226   // CHECK-MESSAGES: :[[@LINE-2]]:16: warning: prefer using
227   // CHECK-FIXES: {{^}}  void cv() const volatile override
228 
cv2InlineDefinitions229   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.
ilDefaultArguments238   void il(IntPair p = {1, (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 };
f()285 void f() { DerivedFromTemplate<int>().f(2); }
286 
287 template <class C>
288 struct UnusedMemberInstantiation : public C {
~UnusedMemberInstantiationUnusedMemberInstantiation289   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 {
~Base2Base2296   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 };
a()308 template <> void MembersOfSpecializations<3>::a() {}
ff()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 {
aTryStmtAsBody314   void a() try
315   // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: annotate this
316   // CHECK-FIXES: {{^}}  void a() override try
317   { b(); } catch(...) { c(); }
318 
dTryStmtAsBody319   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