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 20 2018, 10:08 AM.

Details

Summary

The three checks mentioned in the Title are two noisy if the code uses intrusive smart (reference counting) pointers. 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 changes the term "expensive to copy" to also regard the size of the type so it disables warnings and fixes if the type is not greater than a pointer. This removes false positives for intrusive smart pointers. False positives for non-intrusive smart pointers are not addressed in this patch.

Diff Detail

Event Timeline

JonasToth added inline comments.
clang-tidy/utils/TypeTraits.cpp
47

Please make that comment a sentence, and maybe don't use not twice.

What do you think about making this parameter configurable and/or set it in relation to the size of a cache-line.
This is of course target dependent, but given the CPU effects more accurate.

JonasToth set the repository for this revision to rCTE Clang Tools Extra.
JonasToth added a project: Restricted Project.

This looks questionable to me.
I don't disagree with the reasons stated about llvm types.
But is that *always* true?
I would personally be very surprized, and consider this a false-positive.

This should at least be optional.
Not sure about the default, but setting the StrictMode should certainly disable this relaxation.

flx added inline comments.Sep 20 2018, 10:40 AM
clang-tidy/utils/TypeTraits.cpp
49

This early return now ignores the fact that the type has non-trivial copy constructors, virtual destructors etc which makes the type expensive to copy. Could we achieve the same desired outcome by adding a blacklist that allows users exclude types they deem to be not expensive?

This way they would get a warning the first time they run the check and then could disable such types.

I still wonder what true positives could we get without checking the size? No real-life types come to my mind with size of a pointer but really expensive copy operations. What could be so really expensive when copying a single machine world?

I still wonder what true positives could we get without checking the size? No real-life types come to my mind with size of a pointer but really expensive copy operations. What could be so really expensive when copying a single machine world?

The type is not trivially-copyable, so how do you know the user-provided copy constructors
don't treat that pointer as a pointer to a string, which they allocate and copy on each copy?

I really don't think the default should change.
I think the best solution would be simply to add type blacklists for each of these checks.

"The three checks mentioned in the Title are two noisy if the code uses intrusive smart (reference counting) pointers. 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."

I'm not quite following this comment - StringRef doesn't appear to have any connection to IntrusiveRefCntPtr so far as I can see? (I don't see anything in SymbolRef either. ProgramStateRef is an IntrusiveRefCntPtr, for sure - and has a non-trivial copy ctor - yeah, if you pass that by value unnecessarily, I think that's a real/reasonable warning?

The reason these things are passed by value a lot is when passing ownership - if the callee is moving the IntrusiveRefCntPtr into something that exceeds the duration of the function call (eg: moving it into a member function from a setter) - so the warning should take that into account. But it shouldn't rely on the sizeof of the type - that's not really a good signal here, I think.

...

I think this has been attempted to be superseded by D52360, although that has the same basic issue.

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