This is an archive of the discontinued LLVM Phabricator instance.

A clang-tidy check for std:accumulate.
ClosedPublic

Authored by courbet on Mar 24 2016, 5:33 AM.

Details

Summary

For folds (e.g. std::accumulate), check matches between the provided init value and the range's value_type. A typical error is "std::accumulate(begin, end, 0);", where begin and end have float value_type. See the documentation for more examples.

For now we check std::accumulate, std::reduce and std::inner_product.

Diff Detail

Repository
rL LLVM

Event Timeline

courbet updated this revision to Diff 51543.Mar 24 2016, 5:33 AM
courbet retitled this revision from to A clang-tidy check for std:accumulate..
courbet updated this object.
courbet added reviewers: alexfh, hokein.
courbet added a subscriber: courbet.
alexfh edited edge metadata.Apr 1 2016, 7:28 AM

Sorry for the delay (mostly due to the holidays here).

The check looks very useful, at least, the pattern is hard to spot by manual inspection. A few comments though, mostly style-related.

clang-tidy/misc/FoldInitTypeCheck.cpp
21 ↗(On Diff #51543)

I suspect, a significant part of this could be done in the matcher. I might be wrong, but it seems worth trying. The resulting code is usually much shorter and cleaner.

57 ↗(On Diff #51543)

nit: no space needed before the question mark.

101 ↗(On Diff #51543)

nit: No braces needed for one line if bodies. Here and elsewhere.

test/clang-tidy/misc-fold-init-type.cpp
17 ↗(On Diff #51543)

The CHECK lines shouldn't be broken. Looks like your clang-format doesn't use -style=file by default.

24 ↗(On Diff #51543)

We usually specify each unique message completely once and truncate static parts of all other patterns to a make the test more readable. E.g. here I would remove everything after 'int'.

alexfh requested changes to this revision.Apr 1 2016, 7:30 AM
alexfh edited edge metadata.
This revision now requires changes to proceed.Apr 1 2016, 7:30 AM
aaron.ballman added inline comments.
clang-tidy/misc/FoldInitTypeCheck.cpp
21 ↗(On Diff #51543)

I kind of wonder if it would be generally useful as a matcher helper utility -- expose everything from std::iterator_traits with a nice AST matcher interface. Something that can be used like: iteratorTrait(hasValueType(<blah>), hasPointerType(<yada>)) Or is that overkill?

23 ↗(On Diff #51543)

Should elide the braces (here and elsewhere).

43 ↗(On Diff #51543)

s/allwed/allowed.

Also, may want to clarify what "fold" means in this context (can be confusing because there are fold expressions as well as constant folding).

79 ↗(On Diff #51543)

Are there plans to apply this to other STL algorithms, like inner_product, reduce, etc? If so, it may be good to add a chunk of those up front.

Also, the name we should check should be ::std::accumulate. May want to include a test like:

namespace blah {
namespace std {
template <typename Iter, typename T>
T accumulate(Iter, Iter, T); // We should not care about this one.
}
}
118 ↗(On Diff #51543)

You should be able to just pass the type directly into the diagnostic engine instead of mucking about with the printing policy directly.

courbet updated this revision to Diff 54045.Apr 18 2016, 5:17 AM
courbet updated this object.
courbet edited edge metadata.
courbet marked 7 inline comments as done.
  • Use matchers for most of the check logic,
  • Implement checking for reduce and inner_product,
  • more tests.

Thanks, PTAL.

clang-tidy/misc/FoldInitTypeCheck.cpp
21 ↗(On Diff #51543)

That would be cool, but I'm afraid it would give the false sense of covering all cases. Unfortunately the user can specialize iterator_traits for their iterator type, which would not be easy to cover.

21 ↗(On Diff #51543)

Done, and that's indeed much nicer to read.

79 ↗(On Diff #51543)

Added a test, thanks for the catch !

alexfh requested changes to this revision.Apr 21 2016, 10:07 AM
alexfh edited edge metadata.
alexfh added inline comments.
clang-tidy/misc/FoldInitTypeCheck.cpp
23 ↗(On Diff #54045)
39 ↗(On Diff #54045)

Use the more effective hasAnyName matcher.

52 ↗(On Diff #54045)

You can pull a few common parts to local variables to make the code slightly shorter and easier to read:

auto IteratorParam = parmVarDecl(hasType(hasCanonicalType(IteratorWithValueType("IterValueType"))));
auto Iterator2Param = parmVarDecl(hasType(hasCanonicalType(IteratorWithValueType("Iter2ValueType"))));
auto InitParam = parmVarDecl(hasType(BuiltinTypeWithId("InitType")));
89 ↗(On Diff #54045)

Is "fold" a commonly used term in this context? At least, it's not a language standard jargon and not something I heard of frequently. Maybe we should try to find a more clear word?

This revision now requires changes to proceed.Apr 21 2016, 10:07 AM
courbet updated this revision to Diff 54833.Apr 25 2016, 4:42 AM
courbet edited edge metadata.
courbet marked 3 inline comments as done.

Refactoring matchers & cosmetics.

clang-tidy/misc/FoldInitTypeCheck.cpp
89 ↗(On Diff #54045)

The terminology is from functional programming (https://en.wikipedia.org/wiki/Fold_(higher-order_function)), I don't really have a better name for these. Do you have anything to suggest ?

Prazek added a subscriber: Prazek.Apr 25 2016, 5:34 AM
Prazek added inline comments.
docs/clang-tidy/checks/misc-fold-init-type.rst
16–17 ↗(On Diff #54833)

Doesn't .. code node need new line?

A few nits.

clang-tidy/misc/FoldInitTypeCheck.cpp
90 ↗(On Diff #54833)

No, I don't have a better name. The fp reference fixes my confusion ;) Maybe add this link to the user-facing documentation to tune the readers on the right frequency?

docs/clang-tidy/checks/misc-fold-init-type.rst
8 ↗(On Diff #54833)

s/a initial value/an initial value/

16–17 ↗(On Diff #54833)

Yes, it needs a new-line. Also, please verify the documentation actually builds with sphinx. On Ubuntu it should boil down to these commands:

$ sudo apt-get install python-sphinx
$ mkdir -p /some/build/directory && cd /some/build/directory
$ cmake /path/to/llvm/ -DLLVM_ENABLE_SPHINX=ON
$ make docs-clang-tools-html
courbet updated this revision to Diff 54969.Apr 26 2016, 12:59 AM
courbet edited edge metadata.
courbet marked 2 inline comments as done.

Fix doc formatting and add more doc.

docs/clang-tidy/checks/misc-fold-init-type.rst
16–17 ↗(On Diff #54833)

Thanks for the catch.

16–17 ↗(On Diff #54833)

Thanks.

alexfh accepted this revision.Apr 26 2016, 2:45 AM
alexfh edited edge metadata.

Looks good now. Thank you for the new check!

Do you need me to submit the patch for you?

This revision is now accepted and ready to land.Apr 26 2016, 2:45 AM

Looks good now. Thank you for the new check!

Thanks for the review.

Do you need me to submit the patch for you?

Yes, please.

This revision was automatically updated to reflect the committed changes.