xref: /llvm-project/clang-tools-extra/test/clang-tidy/checkers/modernize/use-override.cpp (revision 5992b3272b29e071f6f5a4807a4e0c23e88c310d)
189a1d03eSRichard // RUN: %check_clang_tidy %s modernize-use-override,cppcoreguidelines-explicit-virtual-functions %t -- -- -fexceptions
289a1d03eSRichard 
389a1d03eSRichard #define ABSTRACT = 0
489a1d03eSRichard 
589a1d03eSRichard #define OVERRIDE override
689a1d03eSRichard #define VIRTUAL virtual
789a1d03eSRichard #define NOT_VIRTUAL
889a1d03eSRichard #define NOT_OVERRIDE
989a1d03eSRichard 
1089a1d03eSRichard #define MUST_USE_RESULT __attribute__((warn_unused_result))
1189a1d03eSRichard #define UNUSED __attribute__((unused))
1289a1d03eSRichard 
1389a1d03eSRichard struct MUST_USE_RESULT MustUseResultObject {};
1489a1d03eSRichard 
1589a1d03eSRichard struct IntPair {
1689a1d03eSRichard   int First, Second;
1789a1d03eSRichard };
1889a1d03eSRichard 
1989a1d03eSRichard struct Base {
~BaseBase2089a1d03eSRichard   virtual ~Base() {}
2189a1d03eSRichard   virtual void a();
2289a1d03eSRichard   virtual void b();
2389a1d03eSRichard   virtual void c();
2489a1d03eSRichard   virtual void d();
2589a1d03eSRichard   virtual void d2();
2689a1d03eSRichard   virtual void e() = 0;
2789a1d03eSRichard   virtual void f() = 0;
2889a1d03eSRichard   virtual void f2() const = 0;
2989a1d03eSRichard   virtual void g() = 0;
30*5992b327SKevin Joseph   virtual void g2() = 0;
3189a1d03eSRichard 
3289a1d03eSRichard   virtual void j() const;
3389a1d03eSRichard   virtual MustUseResultObject k();
3489a1d03eSRichard   virtual bool l() MUST_USE_RESULT UNUSED;
3589a1d03eSRichard   virtual bool n() MUST_USE_RESULT UNUSED;
3689a1d03eSRichard 
3789a1d03eSRichard   virtual void m();
3889a1d03eSRichard   virtual void m2();
3989a1d03eSRichard   virtual void o() __attribute__((unused));
4089a1d03eSRichard 
4189a1d03eSRichard   virtual void r() &;
4289a1d03eSRichard   virtual void rr() &&;
4389a1d03eSRichard 
4489a1d03eSRichard   virtual void cv() const volatile;
4589a1d03eSRichard   virtual void cv2() const volatile;
4689a1d03eSRichard 
4789a1d03eSRichard   virtual void ne() noexcept(false);
4889a1d03eSRichard   virtual void t() throw();
4989a1d03eSRichard 
5089a1d03eSRichard   virtual void il(IntPair);
5189a1d03eSRichard };
5289a1d03eSRichard 
5389a1d03eSRichard struct SimpleCases : public Base {
5489a1d03eSRichard public:
5589a1d03eSRichard   virtual ~SimpleCases();
5689a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: prefer using 'override' or (rarely) 'final' instead of 'virtual'
5789a1d03eSRichard   // CHECK-FIXES: {{^}}  ~SimpleCases() override;
5889a1d03eSRichard 
5989a1d03eSRichard   void a();
6089a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: annotate this
6189a1d03eSRichard   // CHECK-FIXES: {{^}}  void a() override;
6289a1d03eSRichard 
6389a1d03eSRichard   void b() override;
6489a1d03eSRichard   // CHECK-MESSAGES-NOT: warning:
6589a1d03eSRichard   // CHECK-FIXES: {{^}}  void b() override;
6689a1d03eSRichard 
6789a1d03eSRichard   virtual void c();
6889a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using
6989a1d03eSRichard   // CHECK-FIXES: {{^}}  void c() override;
7089a1d03eSRichard 
7189a1d03eSRichard   virtual void d() override;
7289a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'virtual' is redundant since the function is already declared 'override'
7389a1d03eSRichard   // CHECK-FIXES: {{^}}  void d() override;
7489a1d03eSRichard 
7589a1d03eSRichard   virtual void d2() final;
7689a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'virtual' is redundant since the function is already declared 'final'
7789a1d03eSRichard   // CHECK-FIXES: {{^}}  void d2() final;
7889a1d03eSRichard 
7989a1d03eSRichard   virtual void e() = 0;
8089a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using
8189a1d03eSRichard   // CHECK-FIXES: {{^}}  void e() override = 0;
8289a1d03eSRichard 
8389a1d03eSRichard   virtual void f()=0;
8489a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using
8589a1d03eSRichard   // CHECK-FIXES: {{^}}  void f() override =0;
8689a1d03eSRichard 
8789a1d03eSRichard   virtual void f2() const=0;
8889a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using
8989a1d03eSRichard   // CHECK-FIXES: {{^}}  void f2() const override =0;
9089a1d03eSRichard 
9189a1d03eSRichard   virtual void g() ABSTRACT;
9289a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using
9389a1d03eSRichard   // CHECK-FIXES: {{^}}  void g() override ABSTRACT;
9489a1d03eSRichard 
9589a1d03eSRichard   virtual void j() const;
9689a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using
9789a1d03eSRichard   // CHECK-FIXES: {{^}}  void j() const override;
9889a1d03eSRichard 
9989a1d03eSRichard   virtual MustUseResultObject k();  // Has an implicit attribute.
10089a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: prefer using
10189a1d03eSRichard   // CHECK-FIXES: {{^}}  MustUseResultObject k() override;
10289a1d03eSRichard 
10389a1d03eSRichard   virtual bool l() MUST_USE_RESULT UNUSED;
10489a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using
10589a1d03eSRichard   // CHECK-FIXES: {{^}}  bool l() override MUST_USE_RESULT UNUSED;
10689a1d03eSRichard 
10789a1d03eSRichard   virtual bool n() UNUSED MUST_USE_RESULT;
10889a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using
10989a1d03eSRichard   // CHECK-FIXES: {{^}}  bool n() override UNUSED MUST_USE_RESULT;
11089a1d03eSRichard 
11189a1d03eSRichard   void m() override final;
11289a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: 'override' is redundant since the function is already declared 'final'
11389a1d03eSRichard   // CHECK-FIXES: {{^}}  void m() final;
11489a1d03eSRichard 
11589a1d03eSRichard   virtual void m2() override final;
11689a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'virtual' and 'override' are redundant since the function is already declared 'final'
11789a1d03eSRichard   // CHECK-FIXES: {{^}}  void m2() final;
11889a1d03eSRichard 
11989a1d03eSRichard   virtual void o() __attribute__((unused));
12089a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using
12189a1d03eSRichard   // CHECK-FIXES: {{^}}  void o() override __attribute__((unused));
12289a1d03eSRichard 
12389a1d03eSRichard   virtual void ne() noexcept(false);
12489a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using
12589a1d03eSRichard   // CHECK-FIXES: {{^}}  void ne() noexcept(false) override;
12689a1d03eSRichard 
12789a1d03eSRichard   virtual void t() throw();
12889a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using
12989a1d03eSRichard   // CHECK-FIXES: {{^}}  void t() throw() override;
130*5992b327SKevin Joseph 
131*5992b327SKevin Joseph   virtual       /*      */ void g2();
132*5992b327SKevin Joseph   // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: prefer using 'override' or (rarely) 'final' instead of 'virtual'
133*5992b327SKevin Joseph   // CHECK-FIXES: {{^}}  /*      */ void g2() override;
13489a1d03eSRichard };
13589a1d03eSRichard 
13689a1d03eSRichard // CHECK-MESSAGES-NOT: warning:
13789a1d03eSRichard 
c()13889a1d03eSRichard void SimpleCases::c() {}
13989a1d03eSRichard // CHECK-FIXES: {{^}}void SimpleCases::c() {}
14089a1d03eSRichard 
~SimpleCases()14189a1d03eSRichard SimpleCases::~SimpleCases() {}
14289a1d03eSRichard // CHECK-FIXES: {{^}}SimpleCases::~SimpleCases() {}
14389a1d03eSRichard 
14489a1d03eSRichard struct DefaultedDestructor : public Base {
DefaultedDestructorDefaultedDestructor14589a1d03eSRichard   DefaultedDestructor() {}
14689a1d03eSRichard   virtual ~DefaultedDestructor() = default;
14789a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: prefer using
14889a1d03eSRichard   // CHECK-FIXES: {{^}}  ~DefaultedDestructor() override = default;
14989a1d03eSRichard };
15089a1d03eSRichard 
15189a1d03eSRichard struct FinalSpecified : public Base {
15289a1d03eSRichard public:
15389a1d03eSRichard   virtual ~FinalSpecified() final;
15489a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: 'virtual' is redundant since the function is already declared 'final'
15589a1d03eSRichard   // CHECK-FIXES: {{^}}  ~FinalSpecified() final;
15689a1d03eSRichard 
15789a1d03eSRichard   void b() final;
15889a1d03eSRichard   // CHECK-MESSAGES-NOT: warning:
15989a1d03eSRichard   // CHECK-FIXES: {{^}}  void b() final;
16089a1d03eSRichard 
16189a1d03eSRichard   virtual void d() final;
16289a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'virtual' is redundant
16389a1d03eSRichard   // CHECK-FIXES: {{^}}  void d() final;
16489a1d03eSRichard 
16589a1d03eSRichard   virtual void e() final = 0;
16689a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'virtual' is redundant
16789a1d03eSRichard   // CHECK-FIXES: {{^}}  void e() final = 0;
16889a1d03eSRichard 
16989a1d03eSRichard   virtual void j() const final;
17089a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'virtual' is redundant
17189a1d03eSRichard   // CHECK-FIXES: {{^}}  void j() const final;
17289a1d03eSRichard 
17389a1d03eSRichard   virtual bool l() final MUST_USE_RESULT UNUSED;
17489a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'virtual' is redundant
17589a1d03eSRichard   // CHECK-FIXES: {{^}}  bool l() final MUST_USE_RESULT UNUSED;
17689a1d03eSRichard };
17789a1d03eSRichard 
17889a1d03eSRichard struct InlineDefinitions : public Base {
17989a1d03eSRichard public:
~InlineDefinitionsInlineDefinitions18089a1d03eSRichard   virtual ~InlineDefinitions() {}
18189a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: prefer using
18289a1d03eSRichard   // CHECK-FIXES: {{^}}  ~InlineDefinitions() override {}
18389a1d03eSRichard 
aInlineDefinitions18489a1d03eSRichard   void a() {}
18589a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: annotate this
18689a1d03eSRichard   // CHECK-FIXES: {{^}}  void a() override {}
18789a1d03eSRichard 
bInlineDefinitions18889a1d03eSRichard   void b() override {}
18989a1d03eSRichard   // CHECK-MESSAGES-NOT: warning:
19089a1d03eSRichard   // CHECK-FIXES: {{^}}  void b() override {}
19189a1d03eSRichard 
cInlineDefinitions19289a1d03eSRichard   virtual void c()
19389a1d03eSRichard   {}
19489a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-2]]:16: warning: prefer using
19589a1d03eSRichard   // CHECK-FIXES: {{^}}  void c() override
19689a1d03eSRichard 
dInlineDefinitions19789a1d03eSRichard   virtual void d() override {}
19889a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'virtual' is redundant
19989a1d03eSRichard   // CHECK-FIXES: {{^}}  void d() override {}
20089a1d03eSRichard 
jInlineDefinitions20189a1d03eSRichard   virtual void j() const
20289a1d03eSRichard   {}
20389a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-2]]:16: warning: prefer using
20489a1d03eSRichard   // CHECK-FIXES: {{^}}  void j() const override
20589a1d03eSRichard 
kInlineDefinitions20689a1d03eSRichard   virtual MustUseResultObject k() {}  // Has an implicit attribute.
20789a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: prefer using
20889a1d03eSRichard   // CHECK-FIXES: {{^}}  MustUseResultObject k() override {}
20989a1d03eSRichard 
lInlineDefinitions21089a1d03eSRichard   virtual bool l() MUST_USE_RESULT UNUSED {}
21189a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using
21289a1d03eSRichard   // CHECK-FIXES: {{^}}  bool l() override MUST_USE_RESULT UNUSED {}
21389a1d03eSRichard 
rInlineDefinitions21489a1d03eSRichard   virtual void r() &
21589a1d03eSRichard   {}
21689a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-2]]:16: warning: prefer using
21789a1d03eSRichard   // CHECK-FIXES: {{^}}  void r() & override
21889a1d03eSRichard 
rrInlineDefinitions21989a1d03eSRichard   virtual void rr() &&
22089a1d03eSRichard   {}
22189a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-2]]:16: warning: prefer using
22289a1d03eSRichard   // CHECK-FIXES: {{^}}  void rr() && override
22389a1d03eSRichard 
cvInlineDefinitions22489a1d03eSRichard   virtual void cv() const volatile
22589a1d03eSRichard   {}
22689a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-2]]:16: warning: prefer using
22789a1d03eSRichard   // CHECK-FIXES: {{^}}  void cv() const volatile override
22889a1d03eSRichard 
cv2InlineDefinitions22989a1d03eSRichard   virtual void cv2() const volatile // some comment
23089a1d03eSRichard   {}
23189a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-2]]:16: warning: prefer using
23289a1d03eSRichard   // CHECK-FIXES: {{^}}  void cv2() const volatile override // some comment
23389a1d03eSRichard };
23489a1d03eSRichard 
23589a1d03eSRichard struct DefaultArguments : public Base {
23689a1d03eSRichard   // Tests for default arguments (with initializer lists).
23789a1d03eSRichard   // Make sure the override fix is placed after the argument list.
ilDefaultArguments23889a1d03eSRichard   void il(IntPair p = {1, (2 + (3))}) {}
23989a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: annotate this
24089a1d03eSRichard   // CHECK-FIXES: {{^}}  void il(IntPair p = {1, (2 + (3))}) override {}
24189a1d03eSRichard };
24289a1d03eSRichard 
24389a1d03eSRichard struct Macros : public Base {
24489a1d03eSRichard   // Tests for 'virtual' and 'override' being defined through macros. Basically
24589a1d03eSRichard   // give up for now.
24689a1d03eSRichard   NOT_VIRTUAL void a() NOT_OVERRIDE;
24789a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: annotate this
24889a1d03eSRichard   // CHECK-FIXES: {{^}}  NOT_VIRTUAL void a() override NOT_OVERRIDE;
24989a1d03eSRichard 
25089a1d03eSRichard   VIRTUAL void b() NOT_OVERRIDE;
25189a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using
25289a1d03eSRichard   // CHECK-FIXES: {{^}}  VIRTUAL void b() override NOT_OVERRIDE;
25389a1d03eSRichard 
25489a1d03eSRichard   NOT_VIRTUAL void c() OVERRIDE;
25589a1d03eSRichard   // CHECK-MESSAGES-NOT: warning:
25689a1d03eSRichard   // CHECK-FIXES: {{^}}  NOT_VIRTUAL void c() OVERRIDE;
25789a1d03eSRichard 
25889a1d03eSRichard   VIRTUAL void d() OVERRIDE;
25989a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'virtual' is redundant
26089a1d03eSRichard   // CHECK-FIXES: {{^}}  VIRTUAL void d() OVERRIDE;
26189a1d03eSRichard 
26289a1d03eSRichard #define FUNC(return_type, name) return_type name()
26389a1d03eSRichard   FUNC(void, e);
26489a1d03eSRichard   // CHECK-FIXES: {{^}}  FUNC(void, e);
26589a1d03eSRichard 
26689a1d03eSRichard #define F virtual void f();
26789a1d03eSRichard   F
26889a1d03eSRichard   // CHECK-FIXES: {{^}}  F
26989a1d03eSRichard 
27089a1d03eSRichard   VIRTUAL void g() OVERRIDE final;
27189a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'virtual' and 'override' are redundant
27289a1d03eSRichard   // CHECK-FIXES: {{^}}  VIRTUAL void g() final;
27389a1d03eSRichard };
27489a1d03eSRichard 
27589a1d03eSRichard // Tests for templates.
27689a1d03eSRichard template <typename T> struct TemplateBase {
27789a1d03eSRichard   virtual void f(T t);
27889a1d03eSRichard };
27989a1d03eSRichard 
28089a1d03eSRichard template <typename T> struct DerivedFromTemplate : public TemplateBase<T> {
28189a1d03eSRichard   virtual void f(T t);
28289a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using
28389a1d03eSRichard   // CHECK-FIXES: {{^}}  void f(T t) override;
28489a1d03eSRichard };
f()28589a1d03eSRichard void f() { DerivedFromTemplate<int>().f(2); }
28689a1d03eSRichard 
28789a1d03eSRichard template <class C>
28889a1d03eSRichard struct UnusedMemberInstantiation : public C {
~UnusedMemberInstantiationUnusedMemberInstantiation28989a1d03eSRichard   virtual ~UnusedMemberInstantiation() {}
29089a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: prefer using
29189a1d03eSRichard   // CHECK-FIXES: {{^}}  ~UnusedMemberInstantiation() override {}
29289a1d03eSRichard };
29389a1d03eSRichard struct IntantiateWithoutUse : public UnusedMemberInstantiation<Base> {};
29489a1d03eSRichard 
29589a1d03eSRichard struct Base2 {
~Base2Base229689a1d03eSRichard   virtual ~Base2() {}
29789a1d03eSRichard   virtual void a();
29889a1d03eSRichard };
29989a1d03eSRichard 
30089a1d03eSRichard // The OverrideAttr isn't propagated to specializations in all cases. Make sure
30189a1d03eSRichard // we don't add "override" a second time.
30289a1d03eSRichard template <int I>
30389a1d03eSRichard struct MembersOfSpecializations : public Base2 {
30489a1d03eSRichard   void a() override;
30589a1d03eSRichard   // CHECK-MESSAGES-NOT: warning:
30689a1d03eSRichard   // CHECK-FIXES: {{^}}  void a() override;
30789a1d03eSRichard };
a()30889a1d03eSRichard template <> void MembersOfSpecializations<3>::a() {}
ff()30989a1d03eSRichard void ff() { MembersOfSpecializations<3>().a(); };
31089a1d03eSRichard 
31189a1d03eSRichard // In case try statement is used as a method body,
31289a1d03eSRichard // make sure that override fix is placed before try keyword.
31389a1d03eSRichard struct TryStmtAsBody : public Base {
aTryStmtAsBody31489a1d03eSRichard   void a() try
31589a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: annotate this
31689a1d03eSRichard   // CHECK-FIXES: {{^}}  void a() override try
31789a1d03eSRichard   { b(); } catch(...) { c(); }
31889a1d03eSRichard 
dTryStmtAsBody31989a1d03eSRichard   virtual void d() try
32089a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using
32189a1d03eSRichard   // CHECK-FIXES: {{^}}  void d() override try
32289a1d03eSRichard   { e(); } catch(...) { f(); }
32389a1d03eSRichard };
324