diff --git a/clang-tools-extra/clang-tidy/bugprone/VirtualNearMissCheck.h b/clang-tools-extra/clang-tidy/bugprone/VirtualNearMissCheck.h --- a/clang-tools-extra/clang-tidy/bugprone/VirtualNearMissCheck.h +++ b/clang-tools-extra/clang-tidy/bugprone/VirtualNearMissCheck.h @@ -32,6 +32,9 @@ } void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; + llvm::Optional getCheckTraversalKind() const override { + return TK_IgnoreUnlessSpelledInSource; + } private: /// Check if the given method is possible to be overridden by some other diff --git a/clang-tools-extra/clang-tidy/bugprone/VirtualNearMissCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/VirtualNearMissCheck.cpp --- a/clang-tools-extra/clang-tidy/bugprone/VirtualNearMissCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/VirtualNearMissCheck.cpp @@ -216,10 +216,9 @@ void VirtualNearMissCheck::registerMatchers(MatchFinder *Finder) { Finder->addMatcher( - cxxMethodDecl( - unless(anyOf(isOverride(), isImplicit(), cxxConstructorDecl(), - cxxDestructorDecl(), cxxConversionDecl(), isStatic(), - isOverloadedOperator()))) + cxxMethodDecl(unless(anyOf(isOverride(), cxxConstructorDecl(), + cxxDestructorDecl(), cxxConversionDecl(), + isStatic(), isOverloadedOperator()))) .bind("method"), this); } @@ -234,7 +233,15 @@ assert(DerivedRD); for (const auto &BaseSpec : DerivedRD->bases()) { - if (const auto *BaseRD = BaseSpec.getType()->getAsCXXRecordDecl()) { + const auto *BaseRD = BaseSpec.getType()->getAsCXXRecordDecl(); + if (const auto *TST = + dyn_cast(BaseSpec.getType())) { + auto TN = TST->getTemplateName(); + BaseRD = + dyn_cast(TN.getAsTemplateDecl()->getTemplatedDecl()); + } + + if (BaseRD) { for (const auto *BaseMD : BaseRD->methods()) { if (!isPossibleToBeOverridden(BaseMD)) continue; @@ -250,16 +257,12 @@ auto Range = CharSourceRange::getTokenRange( SourceRange(DerivedMD->getLocation())); - bool ApplyFix = !BaseMD->isTemplateInstantiation() && - !DerivedMD->isTemplateInstantiation(); - auto Diag = - diag(DerivedMD->getBeginLoc(), - "method '%0' has a similar name and the same signature as " - "virtual method '%1'; did you mean to override it?") + diag(DerivedMD->getBeginLoc(), + "method '%0' has a similar name and the same signature as " + "virtual method '%1'; did you mean to override it?") << DerivedMD->getQualifiedNameAsString() - << BaseMD->getQualifiedNameAsString(); - if (ApplyFix) - Diag << FixItHint::CreateReplacement(Range, BaseMD->getName()); + << BaseMD->getQualifiedNameAsString() + << FixItHint::CreateReplacement(Range, BaseMD->getName()); } } } diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone-virtual-near-miss.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone-virtual-near-miss.cpp --- a/clang-tools-extra/test/clang-tidy/checkers/bugprone-virtual-near-miss.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone-virtual-near-miss.cpp @@ -44,9 +44,8 @@ struct TDerived : TBase { virtual void tfunk(T t); // Should not apply fix for template. - // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: method 'TDerived::tfunk' has {{.*}} 'TBase::tfunc' - // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: method 'TDerived::tfunk' has {{.*}} 'TBase::tfunc' - // CHECK-FIXES: virtual void tfunk(T t); + // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: method 'TDerived::tfunk' has {{.*}} 'TBase::tfunc' + // CHECK-FIXES: virtual void tfunc(T t); }; TDerived T1;