// RUN: %check_clang_tidy %s modernize-use-override %t -- -- -fexceptions #define ABSTRACT = 0 #define OVERRIDE override #define VIRTUAL virtual #define NOT_VIRTUAL #define NOT_OVERRIDE #define MUST_USE_RESULT __attribute__((warn_unused_result)) #define UNUSED __attribute__((unused)) struct MUST_USE_RESULT MustUseResultObject {}; struct IntPair { int First, Second; }; struct Base { virtual ~Base() {} virtual void a(); virtual void b(); virtual void c(); virtual void d(); virtual void d2(); virtual void e() = 0; virtual void f() = 0; virtual void f2() const = 0; virtual void g() = 0; virtual void j() const; virtual MustUseResultObject k(); virtual bool l() MUST_USE_RESULT UNUSED; virtual bool n() MUST_USE_RESULT UNUSED; virtual void m(); virtual void m2(); virtual void o() __attribute__((unused)); virtual void r() &; virtual void rr() &&; virtual void cv() const volatile; virtual void cv2() const volatile; virtual void ne() noexcept(false); virtual void t() throw(); virtual void il(IntPair); }; struct SimpleCases : public Base { public: virtual ~SimpleCases(); // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: prefer using 'override' or (rarely) 'final' instead of 'virtual' [modernize-use-override] // CHECK-FIXES: {{^}} ~SimpleCases() override; void a(); // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: annotate this // CHECK-FIXES: {{^}} void a() override; void b() override; // CHECK-MESSAGES-NOT: warning: // CHECK-FIXES: {{^}} void b() override; virtual void c(); // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using // CHECK-FIXES: {{^}} void c() override; virtual void d() override; // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'virtual' is redundant since the function is already declared 'override' // CHECK-FIXES: {{^}} void d() override; virtual void d2() final; // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'virtual' is redundant since the function is already declared 'final' // CHECK-FIXES: {{^}} void d2() final; virtual void e() = 0; // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using // CHECK-FIXES: {{^}} void e() override = 0; virtual void f()=0; // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using // CHECK-FIXES: {{^}} void f() override =0; virtual void f2() const=0; // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using // CHECK-FIXES: {{^}} void f2() const override =0; virtual void g() ABSTRACT; // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using // CHECK-FIXES: {{^}} void g() override ABSTRACT; virtual void j() const; // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using // CHECK-FIXES: {{^}} void j() const override; virtual MustUseResultObject k(); // Has an implicit attribute. // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: prefer using // CHECK-FIXES: {{^}} MustUseResultObject k() override; virtual bool l() MUST_USE_RESULT UNUSED; // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using // CHECK-FIXES: {{^}} bool l() override MUST_USE_RESULT UNUSED; virtual bool n() UNUSED MUST_USE_RESULT; // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using // CHECK-FIXES: {{^}} bool n() override UNUSED MUST_USE_RESULT; void m() override final; // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: 'override' is redundant since the function is already declared 'final' // CHECK-FIXES: {{^}} void m() final; virtual void m2() override final; // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'virtual' and 'override' are redundant since the function is already declared 'final' // CHECK-FIXES: {{^}} void m2() final; virtual void o() __attribute__((unused)); // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using // CHECK-FIXES: {{^}} void o() override __attribute__((unused)); virtual void ne() noexcept(false); // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using // CHECK-FIXES: {{^}} void ne() noexcept(false) override; virtual void t() throw(); // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using // CHECK-FIXES: {{^}} void t() throw() override; }; // CHECK-MESSAGES-NOT: warning: void SimpleCases::c() {} // CHECK-FIXES: {{^}}void SimpleCases::c() {} SimpleCases::~SimpleCases() {} // CHECK-FIXES: {{^}}SimpleCases::~SimpleCases() {} struct DefaultedDestructor : public Base { DefaultedDestructor() {} virtual ~DefaultedDestructor() = default; // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: prefer using // CHECK-FIXES: {{^}} ~DefaultedDestructor() override = default; }; struct FinalSpecified : public Base { public: virtual ~FinalSpecified() final; // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: 'virtual' is redundant since the function is already declared 'final' // CHECK-FIXES: {{^}} ~FinalSpecified() final; void b() final; // CHECK-MESSAGES-NOT: warning: // CHECK-FIXES: {{^}} void b() final; virtual void d() final; // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'virtual' is redundant // CHECK-FIXES: {{^}} void d() final; virtual void e() final = 0; // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'virtual' is redundant // CHECK-FIXES: {{^}} void e() final = 0; virtual void j() const final; // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'virtual' is redundant // CHECK-FIXES: {{^}} void j() const final; virtual bool l() final MUST_USE_RESULT UNUSED; // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'virtual' is redundant // CHECK-FIXES: {{^}} bool l() final MUST_USE_RESULT UNUSED; }; struct InlineDefinitions : public Base { public: virtual ~InlineDefinitions() {} // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: prefer using // CHECK-FIXES: {{^}} ~InlineDefinitions() override {} void a() {} // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: annotate this // CHECK-FIXES: {{^}} void a() override {} void b() override {} // CHECK-MESSAGES-NOT: warning: // CHECK-FIXES: {{^}} void b() override {} virtual void c() {} // CHECK-MESSAGES: :[[@LINE-2]]:16: warning: prefer using // CHECK-FIXES: {{^}} void c() override virtual void d() override {} // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'virtual' is redundant // CHECK-FIXES: {{^}} void d() override {} virtual void j() const {} // CHECK-MESSAGES: :[[@LINE-2]]:16: warning: prefer using // CHECK-FIXES: {{^}} void j() const override virtual MustUseResultObject k() {} // Has an implicit attribute. // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: prefer using // CHECK-FIXES: {{^}} MustUseResultObject k() override {} virtual bool l() MUST_USE_RESULT UNUSED {} // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using // CHECK-FIXES: {{^}} bool l() override MUST_USE_RESULT UNUSED {} virtual void r() & {} // CHECK-MESSAGES: :[[@LINE-2]]:16: warning: prefer using // CHECK-FIXES: {{^}} void r() & override virtual void rr() && {} // CHECK-MESSAGES: :[[@LINE-2]]:16: warning: prefer using // CHECK-FIXES: {{^}} void rr() && override virtual void cv() const volatile {} // CHECK-MESSAGES: :[[@LINE-2]]:16: warning: prefer using // CHECK-FIXES: {{^}} void cv() const volatile override virtual void cv2() const volatile // some comment {} // CHECK-MESSAGES: :[[@LINE-2]]:16: warning: prefer using // CHECK-FIXES: {{^}} void cv2() const volatile override // some comment }; struct DefaultArguments : public Base { // Tests for default arguments (with initializer lists). // Make sure the override fix is placed after the argument list. void il(IntPair p = {1, (2 + (3))}) {} // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: annotate this // CHECK-FIXES: {{^}} void il(IntPair p = {1, (2 + (3))}) override {} }; struct Macros : public Base { // Tests for 'virtual' and 'override' being defined through macros. Basically // give up for now. NOT_VIRTUAL void a() NOT_OVERRIDE; // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: annotate this // CHECK-FIXES: {{^}} NOT_VIRTUAL void a() override NOT_OVERRIDE; VIRTUAL void b() NOT_OVERRIDE; // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using // CHECK-FIXES: {{^}} VIRTUAL void b() override NOT_OVERRIDE; NOT_VIRTUAL void c() OVERRIDE; // CHECK-MESSAGES-NOT: warning: // CHECK-FIXES: {{^}} NOT_VIRTUAL void c() OVERRIDE; VIRTUAL void d() OVERRIDE; // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'virtual' is redundant // CHECK-FIXES: {{^}} VIRTUAL void d() OVERRIDE; #define FUNC(return_type, name) return_type name() FUNC(void, e); // CHECK-FIXES: {{^}} FUNC(void, e); #define F virtual void f(); F // CHECK-FIXES: {{^}} F VIRTUAL void g() OVERRIDE final; // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'virtual' and 'override' are redundant // CHECK-FIXES: {{^}} VIRTUAL void g() final; }; // Tests for templates. template struct TemplateBase { virtual void f(T t); }; template struct DerivedFromTemplate : public TemplateBase { virtual void f(T t); // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using // CHECK-FIXES: {{^}} void f(T t) override; }; void f() { DerivedFromTemplate().f(2); } template struct UnusedMemberInstantiation : public C { virtual ~UnusedMemberInstantiation() {} // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: prefer using // CHECK-FIXES: {{^}} ~UnusedMemberInstantiation() override {} }; struct IntantiateWithoutUse : public UnusedMemberInstantiation {}; struct Base2 { virtual ~Base2() {} virtual void a(); }; // The OverrideAttr isn't propagated to specializations in all cases. Make sure // we don't add "override" a second time. template struct MembersOfSpecializations : public Base2 { void a() override; // CHECK-MESSAGES-NOT: warning: // CHECK-FIXES: {{^}} void a() override; }; template <> void MembersOfSpecializations<3>::a() {} void ff() { MembersOfSpecializations<3>().a(); }; // In case try statement is used as a method body, // make sure that override fix is placed before try keyword. struct TryStmtAsBody : public Base { void a() try // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: annotate this // CHECK-FIXES: {{^}} void a() override try { b(); } catch(...) { c(); } virtual void d() try // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using // CHECK-FIXES: {{^}} void d() override try { e(); } catch(...) { f(); } };