steveire created this revision. steveire added reviewers: aaron.ballman, njames93. Herald added a subscriber: nullptr.cpp. steveire requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
Diagnose the problem in templates in the context of the template declaration instead of in the context of all of the (possibly very many) template instantiations. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D96224 Files: clang-tools-extra/clang-tidy/bugprone/VirtualNearMissCheck.cpp clang-tools-extra/clang-tidy/bugprone/VirtualNearMissCheck.h clang-tools-extra/test/clang-tidy/checkers/bugprone-virtual-near-miss.cpp Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-virtual-near-miss.cpp =================================================================== --- clang-tools-extra/test/clang-tidy/checkers/bugprone-virtual-near-miss.cpp +++ clang-tools-extra/test/clang-tidy/checkers/bugprone-virtual-near-miss.cpp @@ -44,9 +44,7 @@ struct TDerived : TBase<T> { virtual void tfunk(T t); // Should not apply fix for template. - // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: method 'TDerived<double>::tfunk' has {{.*}} 'TBase<double>::tfunc' - // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: method 'TDerived<int>::tfunk' has {{.*}} 'TBase<int>::tfunc' - // CHECK-FIXES: virtual void tfunk(T t); + // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: method 'TDerived::tfunk' has {{.*}} 'TBase::tfunc' }; TDerived<int> T1; Index: clang-tools-extra/clang-tidy/bugprone/VirtualNearMissCheck.h =================================================================== --- clang-tools-extra/clang-tidy/bugprone/VirtualNearMissCheck.h +++ 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<TraversalKind> getCheckTraversalKind() const override { + return TK_IgnoreUnlessSpelledInSource; + } private: /// Check if the given method is possible to be overridden by some other Index: clang-tools-extra/clang-tidy/bugprone/VirtualNearMissCheck.cpp =================================================================== --- clang-tools-extra/clang-tidy/bugprone/VirtualNearMissCheck.cpp +++ 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<TemplateSpecializationType>(BaseSpec.getType())) { + auto TN = TST->getTemplateName(); + BaseRD = + dyn_cast<CXXRecordDecl>(TN.getAsTemplateDecl()->getTemplatedDecl()); + } + + if (BaseRD) { for (const auto *BaseMD : BaseRD->methods()) { if (!isPossibleToBeOverridden(BaseMD)) continue;
Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-virtual-near-miss.cpp =================================================================== --- clang-tools-extra/test/clang-tidy/checkers/bugprone-virtual-near-miss.cpp +++ clang-tools-extra/test/clang-tidy/checkers/bugprone-virtual-near-miss.cpp @@ -44,9 +44,7 @@ struct TDerived : TBase<T> { virtual void tfunk(T t); // Should not apply fix for template. - // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: method 'TDerived<double>::tfunk' has {{.*}} 'TBase<double>::tfunc' - // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: method 'TDerived<int>::tfunk' has {{.*}} 'TBase<int>::tfunc' - // CHECK-FIXES: virtual void tfunk(T t); + // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: method 'TDerived::tfunk' has {{.*}} 'TBase::tfunc' }; TDerived<int> T1; Index: clang-tools-extra/clang-tidy/bugprone/VirtualNearMissCheck.h =================================================================== --- clang-tools-extra/clang-tidy/bugprone/VirtualNearMissCheck.h +++ 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<TraversalKind> getCheckTraversalKind() const override { + return TK_IgnoreUnlessSpelledInSource; + } private: /// Check if the given method is possible to be overridden by some other Index: clang-tools-extra/clang-tidy/bugprone/VirtualNearMissCheck.cpp =================================================================== --- clang-tools-extra/clang-tidy/bugprone/VirtualNearMissCheck.cpp +++ 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<TemplateSpecializationType>(BaseSpec.getType())) { + auto TN = TST->getTemplateName(); + BaseRD = + dyn_cast<CXXRecordDecl>(TN.getAsTemplateDecl()->getTemplatedDecl()); + } + + if (BaseRD) { for (const auto *BaseMD : BaseRD->methods()) { if (!isPossibleToBeOverridden(BaseMD)) continue;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits