Skip to content

Commit 9a4b574

Browse files
committed
[clang-itdy] Simplify virtual near-miss check
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. Differential Revision: https://reviews.llvm.org/D96224
1 parent a852234 commit 9a4b574

File tree

3 files changed

+22
-17
lines changed

3 files changed

+22
-17
lines changed

clang-tools-extra/clang-tidy/bugprone/VirtualNearMissCheck.cpp

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -216,10 +216,9 @@ bool VirtualNearMissCheck::isOverriddenByDerivedClass(
216216

217217
void VirtualNearMissCheck::registerMatchers(MatchFinder *Finder) {
218218
Finder->addMatcher(
219-
cxxMethodDecl(
220-
unless(anyOf(isOverride(), isImplicit(), cxxConstructorDecl(),
221-
cxxDestructorDecl(), cxxConversionDecl(), isStatic(),
222-
isOverloadedOperator())))
219+
cxxMethodDecl(unless(anyOf(isOverride(), cxxConstructorDecl(),
220+
cxxDestructorDecl(), cxxConversionDecl(),
221+
isStatic(), isOverloadedOperator())))
223222
.bind("method"),
224223
this);
225224
}
@@ -234,7 +233,15 @@ void VirtualNearMissCheck::check(const MatchFinder::MatchResult &Result) {
234233
assert(DerivedRD);
235234

236235
for (const auto &BaseSpec : DerivedRD->bases()) {
237-
if (const auto *BaseRD = BaseSpec.getType()->getAsCXXRecordDecl()) {
236+
const auto *BaseRD = BaseSpec.getType()->getAsCXXRecordDecl();
237+
if (const auto *TST =
238+
dyn_cast<TemplateSpecializationType>(BaseSpec.getType())) {
239+
auto TN = TST->getTemplateName();
240+
BaseRD =
241+
dyn_cast<CXXRecordDecl>(TN.getAsTemplateDecl()->getTemplatedDecl());
242+
}
243+
244+
if (BaseRD) {
238245
for (const auto *BaseMD : BaseRD->methods()) {
239246
if (!isPossibleToBeOverridden(BaseMD))
240247
continue;
@@ -250,16 +257,12 @@ void VirtualNearMissCheck::check(const MatchFinder::MatchResult &Result) {
250257
auto Range = CharSourceRange::getTokenRange(
251258
SourceRange(DerivedMD->getLocation()));
252259

253-
bool ApplyFix = !BaseMD->isTemplateInstantiation() &&
254-
!DerivedMD->isTemplateInstantiation();
255-
auto Diag =
256-
diag(DerivedMD->getBeginLoc(),
257-
"method '%0' has a similar name and the same signature as "
258-
"virtual method '%1'; did you mean to override it?")
260+
diag(DerivedMD->getBeginLoc(),
261+
"method '%0' has a similar name and the same signature as "
262+
"virtual method '%1'; did you mean to override it?")
259263
<< DerivedMD->getQualifiedNameAsString()
260-
<< BaseMD->getQualifiedNameAsString();
261-
if (ApplyFix)
262-
Diag << FixItHint::CreateReplacement(Range, BaseMD->getName());
264+
<< BaseMD->getQualifiedNameAsString()
265+
<< FixItHint::CreateReplacement(Range, BaseMD->getName());
263266
}
264267
}
265268
}

clang-tools-extra/clang-tidy/bugprone/VirtualNearMissCheck.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ class VirtualNearMissCheck : public ClangTidyCheck {
3232
}
3333
void registerMatchers(ast_matchers::MatchFinder *Finder) override;
3434
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
35+
llvm::Optional<TraversalKind> getCheckTraversalKind() const override {
36+
return TK_IgnoreUnlessSpelledInSource;
37+
}
3538

3639
private:
3740
/// Check if the given method is possible to be overridden by some other

clang-tools-extra/test/clang-tidy/checkers/bugprone-virtual-near-miss.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,8 @@ template <typename T>
4444
struct TDerived : TBase<T> {
4545
virtual void tfunk(T t);
4646
// Should not apply fix for template.
47-
// CHECK-MESSAGES: :[[@LINE-2]]:3: warning: method 'TDerived<double>::tfunk' has {{.*}} 'TBase<double>::tfunc'
48-
// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: method 'TDerived<int>::tfunk' has {{.*}} 'TBase<int>::tfunc'
49-
// CHECK-FIXES: virtual void tfunk(T t);
47+
// CHECK-MESSAGES: :[[@LINE-2]]:3: warning: method 'TDerived::tfunk' has {{.*}} 'TBase::tfunc'
48+
// CHECK-FIXES: virtual void tfunc(T t);
5049
};
5150

5251
TDerived<int> T1;

0 commit comments

Comments
 (0)