Add a check for const& to builtin types. Add FixIt replacing, for example, 'const& int i' with 'int i'.
Diff Detail
Event Timeline
There is utility in the definition of a function in saying that an argument is const int i instead of int i. The const-ness declares the intent that this local variable is not going to be modified. However, there is that oddity in C++ that allows a declaration to say void f(int i); and the implementation to say void f(const int i) { ... }.
I think I would like the fixit to preserve the const-ness of the argument while still stripping it of it's reference.
test/clang-tidy/misc-const-ref-builtin.cpp | ||
---|---|---|
33–35 | I see tests here only for declarations, and not definitions of functions. I also don't see any tests for:
|
Add more test cases, covering templates, template specializations, function definitions, member function templates.
Check if parent function of the argument is a nullptr.
Fix spelling mistake.
The usual pattern for that is to have the definition use const, and the declaration not, since it's an implementation detail if the passed parameter is modified. And, unfortunately, I'm stuck with one compiler that mangles those two differently, causing link errors.
Having void foo(const int i) in a declaration makes me suspicious, since the const is meaningless.
I could make this an option? If the option is set, emit 'const type' if the Decl hasBody?
Adding Samuel, who's written a similar check internally and might want to upstream it or suggest improvements to this patch.
As Alex mentioned, we have a test like this.
It also adds a hardcoded list of user-defined types that are known to be better when passed by value (eg. StringRef)
One big difference is that we decided to not trigger on typedefs.
We can't know that the typedef is documented to be trivial and it could change in the future.
The check actually verifies that the spelling is the expected spelling.
That skips things like macros, templates, type traits, typedefs, aliases, etc.
I could upstream that check and make the user-defined type list configurable.
At least in my codebase, skipping templates is too strong. I run across ones where the const& parameter is not one controlled by a template. It's often a size_t.
I could easily see not fixing the typedef'd refs, also, although I think warning on them is still useful. Particularly if they can then be added to a list to be changed. E.g. size_t.
The only check we are doing (other than matching type) is matching spelling.
This means that it will only skip templates where that type is spelled, for example, using the template argument.
So it will skip this template <typename T> void Foo(const T&); but not this template <typename T> void Foo(const T&, const size_t&); (for the size_t argument).
It will also skip things like void Foo(const T&, const typename T::difference_type&);
The idea is that if the spelling is not exact, then there is some external factor that can change what the type means and make the by-value option less efficient.
I could easily see not fixing the typedef'd refs, also, although I think warning on them is still useful. Particularly if they can then be added to a list to be changed. E.g. size_t.
Warning on types that will never be added to the list and that should be taken by const& will lead to constant false positives.
We could make these warnings opt-in. This way some users might turn it on always or just turn it on to find the list of types.
docs/clang-tidy/checks/misc-const-ref-builtin.rst | ||
---|---|---|
29 | nit: enclose g with double backquotes, please. Same with other inline code snippets (int, double, etc.) |
Function is deferenced, but it's assumed possibly null at line 34 -> dyn_cast_or_null
If not, then you should use dyn_cast instead.