forked from OSchip/llvm-project
clang-tidy use override: Don't generate incorrect warnings without fixes
Add basic testing for the emitted diagnostics. llvm-svn: 210171
This commit is contained in:
parent
91f5b26268
commit
0ab7902755
|
@ -61,7 +61,8 @@ void UseOverride::check(const MatchFinder::MatchResult &Result) {
|
|||
Method->isOutOfLine())
|
||||
return;
|
||||
|
||||
if (Method->getAttr<clang::OverrideAttr>() != nullptr &&
|
||||
if ((Method->getAttr<clang::OverrideAttr>() != nullptr ||
|
||||
Method->getAttr<clang::FinalAttr>() != nullptr) &&
|
||||
!Method->isVirtualAsWritten())
|
||||
return; // Nothing to do.
|
||||
|
||||
|
|
|
@ -0,0 +1,156 @@
|
|||
// RUN: $(dirname %s)/check_clang_tidy_fix.sh %s misc-use-override %t
|
||||
// REQUIRES: shell
|
||||
|
||||
#define ABSTRACT = 0
|
||||
|
||||
#define OVERRIDE override
|
||||
#define VIRTUAL virtual
|
||||
#define NOT_VIRTUAL
|
||||
#define NOT_OVERRIDE
|
||||
|
||||
#define MUST_USE_RESULT __attribute__((warn_unused_result))
|
||||
|
||||
struct MUST_USE_RESULT MustUseResultObject {};
|
||||
|
||||
struct Base {
|
||||
virtual ~Base() {}
|
||||
virtual void a();
|
||||
virtual void b();
|
||||
virtual void c();
|
||||
virtual void d();
|
||||
virtual void e() = 0;
|
||||
virtual void f() = 0;
|
||||
virtual void g() = 0;
|
||||
|
||||
virtual void j() const;
|
||||
virtual MustUseResultObject k();
|
||||
virtual bool l() MUST_USE_RESULT;
|
||||
};
|
||||
|
||||
struct SimpleCases : public Base {
|
||||
public:
|
||||
virtual ~SimpleCases();
|
||||
// CHECK: {{^ ~SimpleCases\(\) override;}}
|
||||
|
||||
void a();
|
||||
// CHECK: {{^ void a\(\) override;}}
|
||||
void b() override;
|
||||
// CHECK: {{^ void b\(\) override;}}
|
||||
virtual void c();
|
||||
// CHECK: {{^ void c\(\) override;}}
|
||||
virtual void d() override;
|
||||
// CHECK: {{^ void d\(\) override;}}
|
||||
|
||||
virtual void e() = 0;
|
||||
// CHECK: {{^ void e\(\) override = 0;}}
|
||||
virtual void f()=0;
|
||||
// CHECK: {{^ void f\(\)override =0;}}
|
||||
virtual void g() ABSTRACT;
|
||||
// CHECK: {{^ void g\(\) override ABSTRACT;}}
|
||||
|
||||
virtual void j() const;
|
||||
// CHECK: {{^ void j\(\) const override;}}
|
||||
virtual MustUseResultObject k(); // Has an implicit attribute.
|
||||
// CHECK: {{^ MustUseResultObject k\(\) override;}}
|
||||
virtual bool l() MUST_USE_RESULT; // Has an explicit attribute
|
||||
// CHECK: {{^ bool l\(\) override MUST_USE_RESULT;}}
|
||||
};
|
||||
|
||||
void SimpleCases::i() {}
|
||||
// CHECK: {{^void SimpleCases::i\(\) {}}}
|
||||
|
||||
SimpleCases::~SimpleCases() {}
|
||||
// CHECK: {{^SimpleCases::~SimpleCases\(\) {}}}
|
||||
|
||||
struct FinalSpecified : public Base {
|
||||
public:
|
||||
virtual ~FinalSpecified() final;
|
||||
// CHECK: {{^ ~FinalSpecified\(\) final;}}
|
||||
|
||||
void b() final;
|
||||
// CHECK: {{^ void b\(\) final;}}
|
||||
virtual void d() final;
|
||||
// CHECK: {{^ void d\(\) final;}}
|
||||
|
||||
virtual void e() final = 0;
|
||||
// CHECK: {{^ void e\(\) final = 0;}}
|
||||
|
||||
virtual void j() const final;
|
||||
// CHECK: {{^ void j\(\) const final;}}
|
||||
virtual bool l() final MUST_USE_RESULT;
|
||||
// CHECK: {{^ bool l\(\) final MUST_USE_RESULT;}}
|
||||
};
|
||||
|
||||
struct InlineDefinitions : public Base {
|
||||
public:
|
||||
virtual ~InlineDefinitions() {}
|
||||
// CHECK: {{^ ~InlineDefinitions\(\) override {}}}
|
||||
|
||||
void a() {}
|
||||
// CHECK: {{^ void a\(\) override {}}}
|
||||
void b() override {}
|
||||
// CHECK: {{^ void b\(\) override {}}}
|
||||
virtual void c() {}
|
||||
// CHECK: {{^ void c\(\) override {}}}
|
||||
virtual void d() override {}
|
||||
// CHECK: {{^ void d\(\) override {}}}
|
||||
|
||||
virtual void j() const {}
|
||||
// CHECK: {{^ void j\(\) const override {}}}
|
||||
virtual MustUseResultObject k() {} // Has an implicit attribute.
|
||||
// CHECK: {{^ MustUseResultObject k\(\) override {}}}
|
||||
virtual bool l() MUST_USE_RESULT {} // Has an explicit attribute
|
||||
// CHECK: {{^ bool l\(\) override MUST_USE_RESULT {}}}
|
||||
};
|
||||
|
||||
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: {{^ NOT_VIRTUAL void a\(\) override NOT_OVERRIDE;}}
|
||||
|
||||
VIRTUAL void b() NOT_OVERRIDE;
|
||||
// CHECK: {{^ VIRTUAL void b\(\) override NOT_OVERRIDE;}}
|
||||
|
||||
NOT_VIRTUAL void c() OVERRIDE;
|
||||
// CHECK: {{^ NOT_VIRTUAL void c\(\) OVERRIDE;}}
|
||||
|
||||
VIRTUAL void d() OVERRIDE;
|
||||
// CHECK: {{^ VIRTUAL void d\(\) OVERRIDE;}}
|
||||
|
||||
#define FUNC(name, return_type) return_type name()
|
||||
FUNC(void, e);
|
||||
// CHECK: {{^ FUNC\(void, e\);}}
|
||||
|
||||
#define F virtual void f();
|
||||
F
|
||||
// CHECK: {{^ F}}
|
||||
};
|
||||
|
||||
// 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: {{^ void f\(T t\) override;}}
|
||||
};
|
||||
void f() { DerivedFromTemplate<int>().f(2); }
|
||||
|
||||
template <class C>
|
||||
struct UnusedMemberInstantiation : public C {
|
||||
virtual ~UnusedMemberInstantiation() {}
|
||||
// CHECK: {{^ ~UnusedMemberInstantiation\(\) override {}}}
|
||||
};
|
||||
struct IntantiateWithoutUse : public UnusedMemberInstantiation<Base> {};
|
||||
|
||||
// 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 Base {
|
||||
void a() override;
|
||||
// CHECK: {{^ void a\(\) override;}}
|
||||
};
|
||||
template <> void MembersOfSpecializations<3>::a() {}
|
||||
void f() { D<3>().a(); };
|
|
@ -1,156 +1,25 @@
|
|||
// RUN: $(dirname %s)/check_clang_tidy_fix.sh %s misc-use-override %t
|
||||
// RUN: $(dirname %s)/check_clang_tidy_output.sh %s misc-use-override %t
|
||||
// REQUIRES: shell
|
||||
|
||||
#define ABSTRACT = 0
|
||||
|
||||
#define OVERRIDE override
|
||||
#define VIRTUAL virtual
|
||||
#define NOT_VIRTUAL
|
||||
#define NOT_OVERRIDE
|
||||
|
||||
#define MUST_USE_RESULT __attribute__((warn_unused_result))
|
||||
|
||||
struct MUST_USE_RESULT MustUseResultObject {};
|
||||
|
||||
struct Base {
|
||||
virtual ~Base() {}
|
||||
virtual void a();
|
||||
virtual void b();
|
||||
virtual void c();
|
||||
virtual void d();
|
||||
virtual void e() = 0;
|
||||
virtual void f() = 0;
|
||||
virtual void g() = 0;
|
||||
|
||||
virtual void j() const;
|
||||
virtual MustUseResultObject k();
|
||||
virtual bool l() MUST_USE_RESULT;
|
||||
};
|
||||
|
||||
struct SimpleCases : public Base {
|
||||
public:
|
||||
virtual ~SimpleCases();
|
||||
// CHECK: {{^ ~SimpleCases\(\) override;}}
|
||||
virtual ~SimpleCases() {}
|
||||
// CHECK: warning: Prefer using 'override' or 'final' instead of 'virtual'
|
||||
|
||||
void a();
|
||||
// CHECK: {{^ void a\(\) override;}}
|
||||
void b() override;
|
||||
// CHECK: {{^ void b\(\) override;}}
|
||||
virtual void c();
|
||||
// CHECK: {{^ void c\(\) override;}}
|
||||
virtual void d() override;
|
||||
// CHECK: {{^ void d\(\) override;}}
|
||||
|
||||
virtual void e() = 0;
|
||||
// CHECK: {{^ void e\(\) override = 0;}}
|
||||
virtual void f()=0;
|
||||
// CHECK: {{^ void f\(\)override =0;}}
|
||||
virtual void g() ABSTRACT;
|
||||
// CHECK: {{^ void g\(\) override ABSTRACT;}}
|
||||
|
||||
virtual void j() const;
|
||||
// CHECK: {{^ void j\(\) const override;}}
|
||||
virtual MustUseResultObject k(); // Has an implicit attribute.
|
||||
// CHECK: {{^ MustUseResultObject k\(\) override;}}
|
||||
virtual bool l() MUST_USE_RESULT; // Has an explicit attribute
|
||||
// CHECK: {{^ bool l\(\) override MUST_USE_RESULT;}}
|
||||
// CHECK: warning: Prefer using
|
||||
virtual void b();
|
||||
// CHECK: warning: Prefer using
|
||||
void c() override;
|
||||
// CHECK-NOT: warning:
|
||||
void d() final;
|
||||
// CHECK-NOT: warning:
|
||||
};
|
||||
|
||||
void SimpleCases::i() {}
|
||||
// CHECK: {{^void SimpleCases::i\(\) {}}}
|
||||
|
||||
SimpleCases::~SimpleCases() {}
|
||||
// CHECK: {{^SimpleCases::~SimpleCases\(\) {}}}
|
||||
|
||||
struct FinalSpecified : public Base {
|
||||
public:
|
||||
virtual ~FinalSpecified() final;
|
||||
// CHECK: {{^ ~FinalSpecified\(\) final;}}
|
||||
|
||||
void b() final;
|
||||
// CHECK: {{^ void b\(\) final;}}
|
||||
virtual void d() final;
|
||||
// CHECK: {{^ void d\(\) final;}}
|
||||
|
||||
virtual void e() final = 0;
|
||||
// CHECK: {{^ void e\(\) final = 0;}}
|
||||
|
||||
virtual void j() const final;
|
||||
// CHECK: {{^ void j\(\) const final;}}
|
||||
virtual bool l() final MUST_USE_RESULT;
|
||||
// CHECK: {{^ bool l\(\) final MUST_USE_RESULT;}}
|
||||
};
|
||||
|
||||
struct InlineDefinitions : public Base {
|
||||
public:
|
||||
virtual ~InlineDefinitions() {}
|
||||
// CHECK: {{^ ~InlineDefinitions\(\) override {}}}
|
||||
|
||||
void a() {}
|
||||
// CHECK: {{^ void a\(\) override {}}}
|
||||
void b() override {}
|
||||
// CHECK: {{^ void b\(\) override {}}}
|
||||
virtual void c() {}
|
||||
// CHECK: {{^ void c\(\) override {}}}
|
||||
virtual void d() override {}
|
||||
// CHECK: {{^ void d\(\) override {}}}
|
||||
|
||||
virtual void j() const {}
|
||||
// CHECK: {{^ void j\(\) const override {}}}
|
||||
virtual MustUseResultObject k() {} // Has an implicit attribute.
|
||||
// CHECK: {{^ MustUseResultObject k\(\) override {}}}
|
||||
virtual bool l() MUST_USE_RESULT {} // Has an explicit attribute
|
||||
// CHECK: {{^ bool l\(\) override MUST_USE_RESULT {}}}
|
||||
};
|
||||
|
||||
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: {{^ NOT_VIRTUAL void a\(\) override NOT_OVERRIDE;}}
|
||||
|
||||
VIRTUAL void b() NOT_OVERRIDE;
|
||||
// CHECK: {{^ VIRTUAL void b\(\) override NOT_OVERRIDE;}}
|
||||
|
||||
NOT_VIRTUAL void c() OVERRIDE;
|
||||
// CHECK: {{^ NOT_VIRTUAL void c\(\) OVERRIDE;}}
|
||||
|
||||
VIRTUAL void d() OVERRIDE;
|
||||
// CHECK: {{^ VIRTUAL void d\(\) OVERRIDE;}}
|
||||
|
||||
#define FUNC(name, return_type) return_type name()
|
||||
FUNC(void, e);
|
||||
// CHECK: {{^ FUNC\(void, e\);}}
|
||||
|
||||
#define F virtual void f();
|
||||
F
|
||||
// CHECK: {{^ F}}
|
||||
};
|
||||
|
||||
// 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: {{^ void f\(T t\) override;}}
|
||||
};
|
||||
void f() { DerivedFromTemplate<int>().f(2); }
|
||||
|
||||
template <class C>
|
||||
struct UnusedMemberInstantiation : public C {
|
||||
virtual ~UnusedMemberInstantiation() {}
|
||||
// CHECK: {{^ ~UnusedMemberInstantiation\(\) override {}}}
|
||||
};
|
||||
struct IntantiateWithoutUse : public UnusedMemberInstantiation<Base> {};
|
||||
|
||||
// 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 Base {
|
||||
void a() override;
|
||||
// CHECK: {{^ void a\(\) override;}}
|
||||
};
|
||||
template <> void MembersOfSpecializations<3>::a() {}
|
||||
void f() { D<3>().a(); };
|
||||
|
|
Loading…
Reference in New Issue