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()13889a1d03eSRichardvoid SimpleCases::c() {} 13989a1d03eSRichard // CHECK-FIXES: {{^}}void SimpleCases::c() {} 14089a1d03eSRichard ~SimpleCases()14189a1d03eSRichardSimpleCases::~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()28589a1d03eSRichardvoid 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()30889a1d03eSRichardtemplate <> void MembersOfSpecializations<3>::a() {} ff()30989a1d03eSRichardvoid 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