This is an archive of the discontinued LLVM Phabricator instance.

[clang-tidy] Added check-fixes for misc-virtual-near-miss.
ClosedPublic

Authored by congliu on Feb 5 2016, 5:56 AM.

Details

Reviewers
alexfh
Summary

Addes FixItHint and updated test.

Diff Detail

Event Timeline

congliu updated this revision to Diff 47012.Feb 5 2016, 5:56 AM
congliu retitled this revision from to [clang-tidy] Added check-fixes for misc-virtual-near-miss..
congliu updated this object.
congliu added a reviewer: alexfh.
congliu added a subscriber: cfe-commits.
alexfh added inline comments.Feb 5 2016, 6:42 AM
clang-tidy/misc/VirtualNearMissCheck.cpp
252

There are two ways to make it shorter:

  • use the getTokenRange overload for SourceLocations: CharSourceRange::getTokenRange(DerivedMD->getLocation(), DerivedMD->getLocation());;
  • use the SourceRange constructor accepting a single location: CharSourceRange::getTokenRange(SourceRange(DerivedMD->getLocation()));.

Choose whatever you like more ;)

test/clang-tidy/misc-virtual-near-miss.cpp
1

Please add a test ensuring replacements are applied correctly in templates with multiple instantiations and in macros.

congliu updated this revision to Diff 47024.Feb 5 2016, 9:54 AM
  • Added test cases of macro and template.
congliu added inline comments.Feb 5 2016, 9:58 AM
test/clang-tidy/misc-virtual-near-miss.cpp
1

Now the fixes work fine for macros. But for template, the behavior is, as the test shows, two warnings were generated, no fix was applied. Is this what we want or should we change the strategy?

alexfh added inline comments.Feb 8 2016, 8:10 AM
test/clang-tidy/misc-virtual-near-miss.cpp
1

The check shouldn't make any changes to template classes based on any single instantiation. An easy way to ensure this is to disallow matches in template instantiations, e.g. using the unless(isInTemplateInstantiation()) limiting matcher.

38

Please move the #defines close to their usages and also verify they don't change as a result of applying fixes.

congliu updated this revision to Diff 47307.Feb 9 2016, 5:30 AM
  • Disallowed matches for method in template instantiations. Updated test.
alexfh added inline comments.Feb 9 2016, 8:35 AM
clang-tidy/misc/VirtualNearMissCheck.cpp
183

I'm not fond of code duplication. If this function is useful in more than one place, it should be made public (in a separate patch, since this is a different repository) and reused, not just copied.

225

We usually use isInTemplateInstantiation(), which also ignores all non-template declarations which have template parents. Also, there's no need to fully qualify the name.

test/clang-tidy/misc-virtual-near-miss.cpp
49

This CHECK-FIXES pattern could also match the line inside the TBase class. We need to make this pattern more specific, e.g. like this:

// CHECK-FIXES: struct TDerived :
// CHECK-FIXES-NEXT: virtual void tfunc(T t);
55

This comment is not enough, please add a CHECK-FIXES ensuring the macro definitions are left intact.

congliu updated this revision to Diff 47448.Feb 10 2016, 6:05 AM
congliu marked 2 inline comments as done.
  • Generate a single warning for multiple template instantiations.

The strategy has changed. Now this check does not ignore template in instantiation, instead, it generate a single warning for some instantiation and ignore others, so that fix is able to apply.
We do this to walk around the function copied from ASTMatchFinder, since it's incorrect for some tricky situation. And make sense to analyse overriding only when there is fully instantiation of the primary template.

alexfh edited edge metadata.Feb 10 2016, 7:14 AM

The strategy has changed. Now this check does not ignore template in instantiation, instead, it generate a
single warning for some instantiation and ignore others, so that fix is able to apply.

I'm not sure this is the right thing to do, since there might be a case when the presence of the pattern we consider a bug depends on the instantiation:

struct A {
  virtual void func() = 0;
};
struct B {
  virtual void funk();
};
template<typename T>
struct D : public T {
  virtual void func() {...}
};
void f() {
  A *da = new D<A>;
  da->func();
  B *db = new D<B>; // If the check applies a fix issued when inspecting this instantiation, it will break the code on the previous line.
}

We still might want to warn in this case though.

clang-tidy/misc/VirtualNearMissCheck.cpp
252

This should be done using a single lookup:

if (!WarningSet.insert(Loc).second)
  continue;
clang-tidy/misc/VirtualNearMissCheck.h
47–48

The "unique ID of a method" would better be described as a "pointer to the method definition" or "pointer to the canonical declaration of the method" depending on what is actually used as a key.

Also, please use proper capitalization and punctuation ("Key", and the trailing period).

58

Please use proper capitalization and punctuation. Also, I'd just say that we keep source locations of issued warnings to avoid duplicate warnings caused by multiple instantiations.

59

You don't need to getRawEncoding. This can be a std::set<SourceLocation> or even better a llvm::SmallPtrSet<SourceLocation, 8>, for example.

congliu updated this revision to Diff 47461.Feb 10 2016, 8:37 AM
congliu marked 3 inline comments as done.
congliu edited edge metadata.
  • Allowed warnings but disallowed fix for template instantiations.
  • Updated tests.
alexfh accepted this revision.Feb 11 2016, 6:51 AM
alexfh edited edge metadata.

Looks good now. Thank you!

This revision is now accepted and ready to land.Feb 11 2016, 6:51 AM