diff --git a/clang-tools-extra/clang-tidy/modernize/UseOverrideCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseOverrideCheck.cpp --- a/clang-tools-extra/clang-tidy/modernize/UseOverrideCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseOverrideCheck.cpp @@ -30,12 +30,16 @@ } void UseOverrideCheck::registerMatchers(MatchFinder *Finder) { - if (IgnoreDestructors) - Finder->addMatcher( - cxxMethodDecl(isOverride(), unless(cxxDestructorDecl())).bind("method"), - this); - else - Finder->addMatcher(cxxMethodDecl(isOverride()).bind("method"), this); + + auto IgnoreDestructorMatcher = + IgnoreDestructors ? cxxMethodDecl(unless(cxxDestructorDecl())) + : cxxMethodDecl(); + Finder->addMatcher( + cxxMethodDecl(isOverride(), + unless(ast_matchers::isTemplateInstantiation()), + IgnoreDestructorMatcher) + .bind("method"), + this); } // Re-lex the tokens to get precise locations to insert 'override' and remove diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -235,6 +235,11 @@ functions containing macros or preprocessor directives, and out-of-line special member functions in unions. +- Fixed false positive in :doc:`modernize-use-override + ` check that occurred when warnings + were generated for template classes that were valid for some instantiations + but potentially invalid for others. + - Fixed reading `HungarianNotation.CString.*` options in :doc:`readability-identifier-naming ` check. diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-override.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-override.cpp --- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-override.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-override.cpp @@ -274,16 +274,16 @@ 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; + // CHECK-MESSAGES-NOT: :[[@LINE-1]]:16: warning: prefer using + // CHECK-FIXES-NOT: {{^}} 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 {} + // CHECK-MESSAGES-NOT: :[[@LINE-1]]:11: warning: prefer using + // CHECK-FIXES-NOT: {{^}} ~UnusedMemberInstantiation() override {} }; struct IntantiateWithoutUse : public UnusedMemberInstantiation {}; @@ -316,3 +316,56 @@ // CHECK-FIXES: {{^}} void d() override try { e(); } catch(...) { f(); } }; + +namespace PR38276 { + struct Base { + virtual void foo(); + }; + + struct Base2 { + virtual void foo2(); + }; + + template + struct Derived : T { + virtual void foo(); + // CHECK-MESSAGES-NOT: :[[@LINE-1]]:18: warning: prefer using 'override' or (rarely) 'final' instead of 'virtual' [cppcoreguidelines-explicit-virtual-functions,modernize-use-override] + // CHECK-FIXES-NOT: {{^}} void foo() override;{{$}} + virtual void foo2(); + // CHECK-MESSAGES-NOT: :[[@LINE-1]]:18: warning: prefer using 'override' or (rarely) 'final' instead of 'virtual' [cppcoreguidelines-explicit-virtual-functions,modernize-use-override] + // CHECK-FIXES-NOT: {{^}} void foo2() override;{{$}} + }; + + void test() { + Derived b; + Derived b2; + } + + template + struct BaseS { + virtual void boo(); + }; + + template<> + struct BaseS { + virtual void boo2(); + }; + + struct BaseU { + virtual void boo3(); + }; + + template + struct Derived2 : BaseS, BaseU { + virtual void boo(); + // CHECK-MESSAGES-NOT: :[[@LINE-1]]:18: warning: prefer using 'override' or (rarely) 'final' instead of 'virtual' [cppcoreguidelines-explicit-virtual-functions,modernize-use-override] + // CHECK-FIXES-NOT: {{^}} void boo() override;{{$}} + virtual void boo2(); + // CHECK-MESSAGES-NOT: :[[@LINE-1]]:18: warning: prefer using 'override' or (rarely) 'final' instead of 'virtual' [cppcoreguidelines-explicit-virtual-functions,modernize-use-override] + // CHECK-FIXES-NOT: {{^}} void boo2() override;{{$}} + virtual void boo3(); + // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: prefer using 'override' or (rarely) 'final' instead of 'virtual' [cppcoreguidelines-explicit-virtual-functions,modernize-use-override] + // CHECK-FIXES: {{^}} void boo3() override;{{$}} + }; + +}