forked from OSchip/llvm-project
319 lines
10 KiB
C++
319 lines
10 KiB
C++
// RUN: %check_clang_tidy %s modernize-use-override,cppcoreguidelines-explicit-virtual-functions %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'
|
|
// 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 <typename T> struct TemplateBase {
|
|
virtual void f(T t);
|
|
};
|
|
|
|
template <typename T> struct DerivedFromTemplate : public TemplateBase<T> {
|
|
virtual void f(T t);
|
|
// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using
|
|
// CHECK-FIXES: {{^}} void f(T t) override;
|
|
};
|
|
void f() { DerivedFromTemplate<int>().f(2); }
|
|
|
|
template <class C>
|
|
struct UnusedMemberInstantiation : public C {
|
|
virtual ~UnusedMemberInstantiation() {}
|
|
// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: prefer using
|
|
// CHECK-FIXES: {{^}} ~UnusedMemberInstantiation() override {}
|
|
};
|
|
struct IntantiateWithoutUse : public UnusedMemberInstantiation<Base> {};
|
|
|
|
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 <int I>
|
|
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(); }
|
|
};
|