This is an archive of the discontinued LLVM Phabricator instance.

[clang-tidy] new performance-no-automatic-move check.
ClosedPublic

Authored by courbet on Nov 18 2019, 5:13 AM.

Details

Summary

The check flags constructs that prevent automatic move of local variables.

Diff Detail

Event Timeline

courbet created this revision.Nov 18 2019, 5:13 AM
Herald added a project: Restricted Project. · View Herald TranscriptNov 18 2019, 5:13 AM
JonasToth added inline comments.
clang-tools-extra/docs/clang-tidy/checks/performance-no-automatic-move.rst
48

While checking this example it seems clang already has a warning for that case?

https://godbolt.org/z/q5zzh-

What parts of this check will be more then the warnings already do?

56

Does this syntax work in rst files?

courbet marked 3 inline comments as done.Nov 18 2019, 6:45 AM

Thanks for the comments

clang-tools-extra/docs/clang-tidy/checks/performance-no-automatic-move.rst
48

I was not aware of that, thanks for pointing that out. I don't think the check does more than the warning in that case. TBH I have not seen instances of this while running the check on our codebase (I'm only looking at a sample of the mistakes though, there are too many hits to look at all of them). All mistakes I have seen are of the const kind.

The value we get from having this in the form of a check is more control over which types are allowed through the clang-tidy options.

56

Nope, this was migrated from our internal markdown syntax, thanks.

courbet updated this revision to Diff 229833.Nov 18 2019, 6:46 AM
courbet marked an inline comment as done.

Fix markdown in doc.

Eugene.Zelenko added inline comments.
clang-tools-extra/docs/ReleaseNotes.rst
149

Please omit The check and synchronize with first sentence of documentation.

clang-tools-extra/docs/clang-tidy/checks/performance-no-automatic-move.rst
11

Please omit This check,

Eugene.Zelenko added a project: Restricted Project.
courbet marked 2 inline comments as done.Nov 18 2019, 7:08 AM

Thanks.

courbet updated this revision to Diff 229840.Nov 18 2019, 7:08 AM

Address comments.

lebedev.ri added inline comments.
clang-tools-extra/docs/clang-tidy/checks/performance-no-automatic-move.rst
48

The const std::vector<int> f isn't diagnosed by the existing diag: https://godbolt.org/z/ZTQ3H6

JonasToth added inline comments.Nov 18 2019, 2:49 PM
clang-tools-extra/docs/clang-tidy/checks/performance-no-automatic-move.rst
48

so should we split this up in a diagnostic and a clang-tidy check? maybe it makes more sense to improve the warning further?

lebedev.ri added inline comments.Nov 18 2019, 11:12 PM
clang-tools-extra/docs/clang-tidy/checks/performance-no-automatic-move.rst
48

I'd +1 just enhancing the clang diagnostic.
The downside is that it does not allow blacklist, sure.

courbet abandoned this revision.Nov 18 2019, 11:47 PM
courbet marked an inline comment as done.
courbet added inline comments.
clang-tools-extra/docs/clang-tidy/checks/performance-no-automatic-move.rst
48

OK I'll work on improving the warning.

courbet reclaimed this revision.Nov 19 2019, 12:14 AM

Actually, thinking more about this, adding this to the existing warning might not be a very consensual change. In the case of the warning:

S<T> f() {
  T&& t = ...;
  ...
  return t;
}

there is no argument against doing the std::move(): the code is just as clear and has better performance:

S<T> f() {
  T&& t = ...;
  ...
  return std::move(t);
}

In the case of a const variable, some people might value the safety from the const above the performance:

S<T> f() {
  const T t = ...;
  ...  // here be dragons
  return t;
}

And they would be unhappy if the -Wreturn-std-move started warning about this.

So I think there are two options here:

  • Add a new warning, or
  • Add it as a clang-tidy as in this change.

What do you think ?

Adding @Quuxplusone (warning author) for opinions.

IMHO these two should just not overlap. It makes sense, to have controversial or configurable stuff in clang-tidy. It should just be consistent with the warnings, as those are "always right" and clang-tidy can be opinionated/specialized.

IMHO these two should just not overlap. It makes sense, to have controversial or configurable stuff in clang-tidy. It should just be consistent with the warnings, as those are "always right" and clang-tidy can be opinionated/specialized.

So to make sure I understand you're advocating for keeping the const version in the clang-tidy check but removing the && detection from this check and let the warning deal with that ?

IMHO these two should just not overlap. It makes sense, to have controversial or configurable stuff in clang-tidy. It should just be consistent with the warnings, as those are "always right" and clang-tidy can be opinionated/specialized.

So to make sure I understand you're advocating for keeping the const version in the clang-tidy check but removing the && detection from this check and let the warning deal with that ?

Yes.

Hi, I'm the main original author (although I would not claim "current maintainer") of the Clang warning.
Clang doesn't warn about const vector<int> v; return v; because in that case, adding std::move to the return would not help anything. I had not considered that we might suggest a "fixit" of "Change the declared type of this variable from vector to const vector"; that sounds like a big non-local change whose correctness would be very difficult to verify. I think (FWIW) that such a fixit would be a very hard sell, but at the same time I admit that I had not even thought of it when I was working on the diagnostic originally.

If you're working in this area, I would also caution you that C++2a is going to completely rewrite the rules in this area. In C++2a, everything that Clang currently warns about is going to be fixed in the standard, so that the Clang warning becomes merely part of -Wc++17-compat. Nobody is currently working on that Clang patch AFAIK. If you're interested in submitting Clang patches in this area, that might be a very high-value (if kind of fuzzy/user-experience/political) patch to work on!

Meanwhile, as of November 2019, the C++2a committee draft still contains unfixed corner cases that Clang doesn't warn about. For example:
https://godbolt.org/z/fBKM-4 (no warning from Clang; C++2a fixes this behavior)
https://godbolt.org/z/EfBCdQ (no warning from Clang; C++2a does NOT fix this behavior)

that sounds like a big non-local change whose correctness would be very difficult to verify.

Agreed. That's why I did not make this check suggest a fixit, because it's too easy to click "apply" without thinking.

I think (FWIW) that such a fixit would be a very hard sell

I've seen several places in our codebase where it did make quite a big difference performance wise, so they were quite easy to sell :)

Nobody is currently working on that Clang patch AFAIK. If you're interested in submitting Clang patches in this area, that might be a very high-value (if kind of fuzzy/user-experience/political) patch to work on!
Meanwhile, as of November 2019, the C++2a committee draft still contains unfixed corner cases that Clang doesn't warn about. For example:
https://godbolt.org/z/fBKM-4 (no warning from Clang; C++2a fixes this behavior)
https://godbolt.org/z/EfBCdQ (no warning from Clang; C++2a does NOT fix this behavior)

Super interesting, thanks ! I'll see if I have time to work on that.

courbet planned changes to this revision.Nov 20 2019, 12:03 AM

I'm going to remove the && warning from the check and keep only the const one, as I think these is a consensus on that.

courbet updated this revision to Diff 230202.Nov 20 2019, 12:24 AM

Remove && warnings.

JonasToth added inline comments.Nov 20 2019, 4:02 PM
clang-tools-extra/clang-tidy/performance/NoAutomaticMoveCheck.cpp
29

the matchers need only to be registered for c++ and and c++11 and later. See getLangOpts() in other checks.

60

i think isConstQualified could move into the matcher with Matcher<QualType> isConstQualified.

clang-tools-extra/docs/clang-tidy/checks/performance-no-automatic-move.rst
12

s/declared/declare

courbet updated this revision to Diff 230428.Nov 21 2019, 4:44 AM
courbet marked 2 inline comments as done.

Address comments.

JonasToth accepted this revision.Nov 21 2019, 7:56 AM

LGTM after the variable names are adjusted

clang-tools-extra/clang-tidy/performance/NoAutomaticMoveCheck.cpp
33

Last nits: all variables do not follow the LLVM convention of camel-casing. Just realized now, sorry

This revision is now accepted and ready to land.Nov 21 2019, 7:56 AM
courbet updated this revision to Diff 230595.Nov 21 2019, 11:44 PM

Use LLVM style

courbet marked an inline comment as done.Nov 21 2019, 11:45 PM

Thanks for the review.

clang-tools-extra/clang-tidy/performance/NoAutomaticMoveCheck.cpp
33

Oh yes right, thanks for the catch.

This revision was automatically updated to reflect the committed changes.