[PATCH] D73007: [Sema] Avoid Wrange-loop-analysis false positives
Aaron Puchert via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Sun Feb 2 07:10:46 PST 2020
aaronpuchert added a comment.
I've been thinking about the warning messages, which seem to a bit inaccurate. Sorry for piggy-backing this onto the change, I hope you don't mind.
================
Comment at: clang/lib/Sema/SemaStmt.cpp:2758-2759
// the correct time to bind a const reference.
SemaRef.Diag(VD->getLocation(), diag::warn_for_range_const_reference_copy)
<< VD << VariableType << E->getType();
QualType NonReferenceType = VariableType.getNonReferenceType();
----------------
The message here says: "loop variable A has type B but is initialized with type C resulting in a copy".
That's not necessarily true, we just know (I think) that a constructor is called. The constructor might copy, but it might also not. However, the constructed object is bound to a reference, which is potentially misleading. One writes `const X& x : range` and `x` doesn't bind to the return value of `*begin(range)`, but to a temporary constructed from that.
Perhaps a more accurate message would be: "loop variable A of type B binds to a temporary constructed from type C" with the appropriate types.
================
Comment at: clang/lib/Sema/SemaStmt.cpp:2772-2773
// semantic of the code.
SemaRef.Diag(VD->getLocation(), diag::warn_for_range_variable_always_copy)
<< VD << RangeInitType;
QualType NonReferenceType = VariableType.getNonReferenceType();
----------------
The message here is: "loop variable A is always a **copy** because the range of type B does not return a reference". This is somewhat misleading, some ranges create objects on-the-fly, in which case these aren't copies. (Assuming RVO the copy constructor might have never been called.)
I would suggest to rephrase this as something like "loop variable A binds to a temporary value produced by a range of type B".
================
Comment at: clang/lib/Sema/SemaStmt.cpp:2823-2824
// if doing so will prevent a copy.
SemaRef.Diag(VD->getLocation(), diag::warn_for_range_copy)
<< VD << VariableType << InitExpr->getType();
SemaRef.Diag(VD->getBeginLoc(), diag::note_use_reference_type)
----------------
Given that `VariableType == VD->getType()` and `InitExpr->getType() == VD->getInit()->getType()`, can these two types ever be different other than cv-qualifiers? We only call this function if `VariableType` is not a reference type.
Which begs the question: which value provides C in "loop variable A of type B creates a copy from type C"? I would suggest to omit the second type and write: "loop variable A creates a copy of type B", perhaps with stripping const from B.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D73007/new/
https://reviews.llvm.org/D73007
More information about the cfe-commits
mailing list