This is an archive of the discontinued LLVM Phabricator instance.

[clang] Warn about by-value const auto from lvalue
AbandonedPublic

Authored by urnathan on Dec 2 2021, 12:44 PM.

Details

Summary

This adds a warning about:

auto const v = returns_a_ref();

when the deduced type is a record, and suggests perhaps a missing '&'.
There's usually no need to make a local copy -- unless the reference
is unstable or the object mutated in subsequent code. Adjust to use a
ref, or use constructor notation -- either brace or parens -- to
avoid:

auto const &ref_ok = returns_a_ref();
auto const want_value_1 (returns_a_ref());
auto const want_value_2 {returns_a_ref()};

Found 4 cases in llvm itself (there's a followup patch).

I bottled out of adding this to Wextra or something, but perhaps that'd be a good idea?

Diff Detail

Unit TestsFailed

Event Timeline

urnathan requested review of this revision.Dec 2 2021, 12:44 PM
urnathan created this revision.
urnathan added reviewers: bruno, aaron.ballman.
aaron.ballman added inline comments.Dec 15 2021, 12:38 PM
clang/include/clang/Basic/DiagnosticSemaKinds.td
2370

Not super happy about "call's lvalue return". How about something along the lines of: initialization of %0 creates a value copy of the returned reference; did you mean '&'?

2371

We typically don't add new off-by-default diagnostics to Clang because we have evidence to suggest almost nobody enables them. Is something holding us back from enabling this by default? If so, does it suggest this should be a clang-tidy check instead (perhaps under the performance module)?

clang/lib/Sema/SemaDecl.cpp
12267–12268

You can pass VDecl directly instead of getting its name. Also, you should fix the formatting issues.

clang/test/SemaCXX/warn-auto-value-copy.cpp
9–10

Can you also add a test whether the return type is const Big & and another one where the return type is const Big? For the latter case, do you still think we should suggest adding & or is the const Ty <-> const auto signaling user intent of some kind?

urnathan updated this revision to Diff 394883.Dec 16 2021, 8:07 AM

thanks for the feedback

urnathan marked 4 inline comments as done.Dec 16 2021, 8:07 AM

I see you switched this to on-by-default, thanks! Have you run this over some other large code bases to see what the false positive rate is? I know you ran it over LLVM and it found some true positives, but were there false positives as well? If we do notice some false positives in practice (but not a significant amount), I think adding this to -Wextra would not be a terrible compromise either.

clang/include/clang/Basic/DiagnosticSemaKinds.td
2370–2371

Saves on my eyes a bit to remove the leading whitespace. :-D

The "use brace or paren init to suppress" seems pretty questionable - like "()" to suppress "-Wparentheses" which I think is generally considered poor form, but has enough history to be acceptable.

This seems more like a stylistic thing, suitable for clang-tidy, rather than a warning? (some codebases might use "always auto" and/or "const by default" that could trip over this warning)

Though, perhaps given we already have -Wrange-loop-construct there's already precedent. But is this new warning powered by the same heuristics (as much as possible) as that warning? It'd be good if it was, for consistency. (I believe it has some heuristics for the size of the object or non-trivial copy, etc): https://godbolt.org/z/ch3nseG6b

This seems more like a stylistic thing, suitable for clang-tidy, rather than a warning? (some codebases might use "always auto" and/or "const by default" that could trip over this warning)

+1, this is what I was trying to get at with the false positive question. I suspect we'll find this is quite chatty in practice, but it'd be good to know just how bad it is to decide whether this is clang-tidy material, -Wextra, something else, etc.

urnathan abandoned this revision.Mar 9 2022, 11:06 AM
Herald added a project: Restricted Project. · View Herald TranscriptMar 9 2022, 11:06 AM