This is an archive of the discontinued LLVM Phabricator instance.

[clang-tidy] Fix for performance-unnecessary-value-param, performance-unnecessary-copy-initialization and performance-for-range-copy
AbandonedPublic

Authored by baloghadamsoftware on Sep 21 2018, 7:16 AM.

Details

Summary

The three checks mentioned in the Title are two noisy if the code uses custom (e.g. smart) pointers or references. LLVM/Clang is such a code, it has lots of such types, e.g. StringRef, SymbolRef or ProgramStateRef, all of them based llvm::IntrusiveRefCntPtr. Every time such a type is passed as parameter, used for initialization or in a range-based for loop a false positive warning is issued together with an (unnecessary) fix.

This patch excludes pointer types (e.g. smart pointers) by their name: if the name of the type ends on Pointer, pointer, Ptr, ptr, Reference, reference, Ref or ref the type is considered a pointer/reference type.

Diff Detail

Event Timeline

This is an alternative approach to D52315.

lebedev.ri added a subscriber: lebedev.ri.

Better, but these blacklists need to be config options, not random hardcoded globs.
See e.g. google-runtime-references.WhiteListTypes.

Config option is a good idea but it must not be empty by default. The checker must ignore all pointer and references by default based on their names.

Would that also skip checks for something like shared_ptr?

Config option is a good idea but it must not be empty by default. The checker must ignore all pointer and references by default based on their names.

I disagree, it must not have false-negatives by default.
It may have false-positives, that are controllable via the options.

Would that also skip checks for something like shared_ptr?

Yes, everything ending on pointer, ptr, reference or ref, first letter case insensitive.

I disagree, it must not have false-negatives by default.

What kind of false-negatives could be caused by smart pointers or references? Sane people do not name a type pointer or reference if they are not. Such types must never be passed by reference. Few people will use the check if they have to set tons of options for the basic expected behavior. For example in CodeChecker this check is disabled by default and is only enabled in the Sensitive profile.

I disagree, it must not have false-negatives by default.

What kind of false-negatives could be caused by smart pointers or references? Sane people do not name a type pointer or reference if they are not. Such types must never be passed by reference. Few people will use the check if they have to set tons of options for the basic expected behavior. For example in CodeChecker this check is disabled by default and is only enabled in the Sensitive profile.

Ok, so let's entertain the current patch.
Now, some time passes, and someone either discovers that the check does not warn on some code that one would have thought it should warn.
Shitty code happens. Not everyone is sane in their naming choices. More importantly, there isn't a common coding style naming guidelines everyone has to follow.
Someone somewhere will surely hit this. When he does, how does one get the check to warn on that?
Or other side of the coin, how does one get the check not to warn on some custom type that does not match those hardcoded regexes?

I don't disagree that this has false-positives. But this is really sensitive to the type names. It is not a good idea to hardcode this.
Please follow pre-existing practice of configurable type white/blacklists.

$ clang-tidy -checks=\* -dump-config | grep -i "types$" -A1
  - key:             cert-msc32-c.DisallowedSeedTypes
    value:           'time_t,std::time_t'
  - key:             cert-msc51-cpp.DisallowedSeedTypes
    value:           'time_t,std::time_t'
--
  - key:             google-runtime-references.WhiteListTypes
    value:           ''
--
  - key:             hicpp-use-emplace.TupleTypes
    value:           '::std::pair;::std::tuple'
--
  - key:             modernize-use-emplace.TupleTypes
    value:           '::std::pair;::std::tuple'
--
  - key:             readability-simplify-subscript-expr.Types
    value:           '::std::basic_string;::std::basic_string_view;::std::vector;::std::array'
flx added a comment.Sep 26 2018, 7:09 AM

Would that also skip checks for something like shared_ptr?

Yes, everything ending on pointer, ptr, reference or ref, first letter case insensitive.

std::shared_ptr should not be blacklisted. It is not free to copy it: It incurs two atomic operations and two branches.

Users should blacklist it if they know they don't care about this or not use the check.

While it looks weird for the check to suggest to pass std::shared_ptr by reference it is correct. A better change would be to just pass the raw pointer in this case:

std::shared_ptr<Ptr> p;
PassByRawPointer(p.get());

But this would require function signature change that breaks callers outside of the translation unit.

baloghadamsoftware abandoned this revision.Oct 1 2018, 8:59 AM