Author: Aaron Puchert Date: 2020-03-06T14:57:01+01:00 New Revision: 33bb32bbc674a16973c59c9a6dc119387843a0f0
URL: https://github.com/llvm/llvm-project/commit/33bb32bbc674a16973c59c9a6dc119387843a0f0 DIFF: https://github.com/llvm/llvm-project/commit/33bb32bbc674a16973c59c9a6dc119387843a0f0.diff LOG: [Sema] Reword -Wrange-loop-analysis warning messages Summary: The messages for two of the warnings are misleading: * warn_for_range_const_reference_copy suggests that the initialization of the loop variable results in a copy. But that's not always true, we just know that some conversion happens, potentially invoking a constructor or conversion operator. The constructor might copy, as in the example that lead to this message [1], but it might also not. However, the constructed object is bound to a reference, which is potentially misleading, so we rewrite the message to emphasize that. We also make sure that we print the reference type into the warning message to clarify that this warning only appears when operator* returns a reference. * warn_for_range_variable_always_copy suggests that a reference type loop variable initialized from a temporary "is always a copy". But we don't know this, the range might just return temporary objects which aren't copies of anything. (Assuming RVO a copy constructor might never have been called.) The message for warn_for_range_copy is a bit repetitive: the type of a VarDecl and its initialization Expr are the same up to cv-qualifiers, because Sema will insert implicit casts or constructor calls to make them match. [1] https://bugs.llvm.org/show_bug.cgi?id=32823 Reviewers: aaron.ballman, Mordante, rtrieu Reviewed By: aaron.ballman Differential Revision: https://reviews.llvm.org/D75613 Added: Modified: clang/include/clang/Basic/DiagnosticSemaKinds.td clang/lib/Sema/SemaStmt.cpp clang/test/SemaCXX/warn-range-loop-analysis-trivially-copyable.cpp clang/test/SemaCXX/warn-range-loop-analysis.cpp Removed: ################################################################################ diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index e6155d5d0e10..cb3dd24a44cf 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -2424,20 +2424,19 @@ def note_for_range_invalid_iterator : Note < "in implicit call to 'operator%select{!=|*|++}0' for iterator of type %1">; def note_for_range_begin_end : Note< "selected '%select{begin|end}0' %select{function|template }1%2 with iterator type %3">; -def warn_for_range_const_reference_copy : Warning< +def warn_for_range_const_ref_binds_temp_built_from_ref : Warning< "loop variable %0 " - "% diff {has type $ but is initialized with type $" - "|is initialized with a value of a diff erent type}1,2 resulting in a copy">, + "% diff {of type $ binds to a temporary constructed from type $" + "|binds to a temporary constructed from a diff erent type}1,2">, InGroup<RangeLoopConstruct>, DefaultIgnore; def note_use_type_or_non_reference : Note< - "use non-reference type %0 to keep the copy or type %1 to prevent copying">; -def warn_for_range_variable_always_copy : Warning< - "loop variable %0 is always a copy because the range of type %1 does not " - "return a reference">, + "use non-reference type %0 to make construction explicit or type %1 to prevent copying">; +def warn_for_range_ref_binds_ret_temp : Warning< + "loop variable %0 binds to a temporary value produced by a range of type %1">, InGroup<RangeLoopBindReference>, DefaultIgnore; def note_use_non_reference_type : Note<"use non-reference type %0">; def warn_for_range_copy : Warning< - "loop variable %0 of type %1 creates a copy from type %2">, + "loop variable %0 creates a copy from type %1">, InGroup<RangeLoopConstruct>, DefaultIgnore; def note_use_reference_type : Note<"use reference type %0 to prevent copying">; def err_objc_for_range_init_stmt : Error< diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index ff6481006280..2104add400e0 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -2741,22 +2741,24 @@ static void DiagnoseForRangeReferenceVariableCopies(Sema &SemaRef, E = E->IgnoreImpCasts(); } - bool ReturnsReference = false; + QualType ReferenceReturnType; if (isa<UnaryOperator>(E)) { - ReturnsReference = true; + ReferenceReturnType = SemaRef.Context.getLValueReferenceType(E->getType()); } else { const CXXOperatorCallExpr *Call = cast<CXXOperatorCallExpr>(E); const FunctionDecl *FD = Call->getDirectCallee(); QualType ReturnType = FD->getReturnType(); - ReturnsReference = ReturnType->isReferenceType(); + if (ReturnType->isReferenceType()) + ReferenceReturnType = ReturnType; } - if (ReturnsReference) { + if (!ReferenceReturnType.isNull()) { // Loop variable creates a temporary. Suggest either to go with // non-reference loop variable to indicate a copy is made, or - // the correct time to bind a const reference. - SemaRef.Diag(VD->getLocation(), diag::warn_for_range_const_reference_copy) - << VD << VariableType << E->getType(); + // the correct type to bind a const reference. + SemaRef.Diag(VD->getLocation(), + diag::warn_for_range_const_ref_binds_temp_built_from_ref) + << VD << VariableType << ReferenceReturnType; QualType NonReferenceType = VariableType.getNonReferenceType(); NonReferenceType.removeLocalConst(); QualType NewReferenceType = @@ -2769,7 +2771,7 @@ static void DiagnoseForRangeReferenceVariableCopies(Sema &SemaRef, // Suggest removing the reference from the loop variable. // If the type is a rvalue reference do not warn since that changes the // semantic of the code. - SemaRef.Diag(VD->getLocation(), diag::warn_for_range_variable_always_copy) + SemaRef.Diag(VD->getLocation(), diag::warn_for_range_ref_binds_ret_temp) << VD << RangeInitType; QualType NonReferenceType = VariableType.getNonReferenceType(); NonReferenceType.removeLocalConst(); @@ -2821,7 +2823,7 @@ static void DiagnoseForRangeConstVariableCopies(Sema &SemaRef, // Suggest changing from a const variable to a const reference variable // if doing so will prevent a copy. SemaRef.Diag(VD->getLocation(), diag::warn_for_range_copy) - << VD << VariableType << InitExpr->getType(); + << VD << VariableType; SemaRef.Diag(VD->getBeginLoc(), diag::note_use_reference_type) << SemaRef.Context.getLValueReferenceType(VariableType) << VD->getSourceRange() @@ -2841,9 +2843,10 @@ static void DiagnoseForRangeVariableCopies(Sema &SemaRef, if (SemaRef.inTemplateInstantiation()) return; - if (SemaRef.Diags.isIgnored(diag::warn_for_range_const_reference_copy, - ForStmt->getBeginLoc()) && - SemaRef.Diags.isIgnored(diag::warn_for_range_variable_always_copy, + if (SemaRef.Diags.isIgnored( + diag::warn_for_range_const_ref_binds_temp_built_from_ref, + ForStmt->getBeginLoc()) && + SemaRef.Diags.isIgnored(diag::warn_for_range_ref_binds_ret_temp, ForStmt->getBeginLoc()) && SemaRef.Diags.isIgnored(diag::warn_for_range_copy, ForStmt->getBeginLoc())) { diff --git a/clang/test/SemaCXX/warn-range-loop-analysis-trivially-copyable.cpp b/clang/test/SemaCXX/warn-range-loop-analysis-trivially-copyable.cpp index f4c76f26f5c9..e345ef40aed9 100644 --- a/clang/test/SemaCXX/warn-range-loop-analysis-trivially-copyable.cpp +++ b/clang/test/SemaCXX/warn-range-loop-analysis-trivially-copyable.cpp @@ -16,7 +16,7 @@ void test_POD_65_bytes() { char a[65]; }; - // expected-warning@+3 {{loop variable 'r' of type 'const Record' creates a copy from type 'const Record'}} + // expected-warning@+3 {{loop variable 'r' creates a copy from type 'const Record'}} // expected-note@+2 {{use reference type 'const Record &' to prevent copying}} Record records[8]; for (const auto r : records) @@ -40,7 +40,7 @@ void test_TriviallyCopyable_65_bytes() { char a[65]; }; - // expected-warning@+3 {{loop variable 'r' of type 'const Record' creates a copy from type 'const Record'}} + // expected-warning@+3 {{loop variable 'r' creates a copy from type 'const Record'}} // expected-note@+2 {{use reference type 'const Record &' to prevent copying}} Record records[8]; for (const auto r : records) @@ -55,7 +55,7 @@ void test_NonTriviallyCopyable() { int b; }; - // expected-warning@+3 {{loop variable 'r' of type 'const Record' creates a copy from type 'const Record'}} + // expected-warning@+3 {{loop variable 'r' creates a copy from type 'const Record'}} // expected-note@+2 {{use reference type 'const Record &' to prevent copying}} Record records[8]; for (const auto r : records) @@ -81,7 +81,7 @@ void test_TrivialABI_65_bytes() { char a[65]; }; - // expected-warning@+3 {{loop variable 'r' of type 'const Record' creates a copy from type 'const Record'}} + // expected-warning@+3 {{loop variable 'r' creates a copy from type 'const Record'}} // expected-note@+2 {{use reference type 'const Record &' to prevent copying}} Record records[8]; for (const auto r : records) diff --git a/clang/test/SemaCXX/warn-range-loop-analysis.cpp b/clang/test/SemaCXX/warn-range-loop-analysis.cpp index 8331e6088b66..7fd7fcd69a54 100644 --- a/clang/test/SemaCXX/warn-range-loop-analysis.cpp +++ b/clang/test/SemaCXX/warn-range-loop-analysis.cpp @@ -71,17 +71,17 @@ void test0() { Container<Bar&> bar_container; for (const int &x : int_non_ref_container) {} - // expected-warning@-1 {{loop variable 'x' is always a copy because the range of type 'Container<int>' does not return a reference}} + // expected-warning@-1 {{loop variable 'x' binds to a temporary value produced by a range of type 'Container<int>'}} // expected-note@-2 {{use non-reference type 'int'}} // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:19}:"" for (const double &x : int_container) {} - // expected-warning@-1 {{loop variable 'x' has type 'const double &' but is initialized with type 'int' resulting in a copy}} - // expected-note@-2 {{use non-reference type 'double' to keep the copy or type 'const int &' to prevent copying}} + // expected-warning@-1 {{loop variable 'x' of type 'const double &' binds to a temporary constructed from type 'int &'}} + // expected-note@-2 {{use non-reference type 'double' to make construction explicit or type 'const int &' to prevent copying}} // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:21-[[@LINE-3]]:22}:"" for (const Bar x : bar_container) {} - // expected-warning@-1 {{loop variable 'x' of type 'const Bar' creates a copy from type 'const Bar'}} + // expected-warning@-1 {{loop variable 'x' creates a copy from type 'const Bar'}} // expected-note@-2 {{use reference type 'const Bar &' to prevent copying}} // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:18}:"&" } @@ -92,7 +92,7 @@ void test1() { for (const int &&x : A) {} // No warning, rvalue-reference to the temporary for (const int &x : A) {} - // expected-warning@-1 {{always a copy}} + // expected-warning@-1 {{binds to a temporary value produced by a range}} // expected-note@-2 {{'int'}} // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:19}:"" for (const int x : A) {} @@ -107,7 +107,7 @@ void test1() { for (const double &&x : A) {} // No warning, rvalue-reference to the temporary for (const double &x : A) {} - // expected-warning@-1 {{always a copy}} + // expected-warning@-1 {{binds to a temporary value produced by a range}} // expected-note@-2 {{'double'}} // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:21-[[@LINE-3]]:22}:"" for (const double x : A) {} @@ -122,7 +122,7 @@ void test1() { for (const Bar &&x : A) {} // No warning, rvalue-reference to the temporary for (const Bar &x : A) {} - // expected-warning@-1 {{always a copy}} + // expected-warning@-1 {{binds to a temporary value produced by a range}} // expected-note@-2 {{'Bar'}} // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:19}:"" for (const Bar x : A) {} @@ -152,16 +152,16 @@ void test2() { // No warning for (const double &&x : B) {} - // expected-warning@-1 {{resulting in a copy}} + // expected-warning@-1 {{binds to a temporary constructed from}} // expected-note-re@-2 {{'double'{{.*}}'const int &'}} // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:21-[[@LINE-3]]:23}:"" for (const double &x : B) {} - // expected-warning@-1 {{resulting in a copy}} + // expected-warning@-1 {{binds to a temporary constructed from}} // expected-note-re@-2 {{'double'{{.*}}'const int &'}} // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:21-[[@LINE-3]]:22}:"" for (const double x : B) {} for (double &&x : B) {} - // expected-warning@-1 {{resulting in a copy}} + // expected-warning@-1 {{binds to a temporary constructed from}} // expected-note-re@-2 {{'double'{{.*}}'const int &'}} // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:15-[[@LINE-3]]:17}:"" //for (double &x : B) {} @@ -170,16 +170,16 @@ void test2() { // No warning for (const Bar &&x : B) {} - // expected-warning@-1 {{resulting in a copy}} + // expected-warning@-1 {{binds to a temporary constructed from}} // expected-note@-2 {{'Bar'}} // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:20}:"" for (const Bar &x : B) {} - // expected-warning@-1 {{resulting in a copy}} + // expected-warning@-1 {{binds to a temporary constructed from}} // expected-note@-2 {{'Bar'}} // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:19}:"" for (const Bar x : B) {} for (Bar &&x : B) {} - // expected-warning@-1 {{resulting in a copy}} + // expected-warning@-1 {{binds to a temporary constructed from}} // expected-note@-2 {{'Bar'}} // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:12-[[@LINE-3]]:14}:"" //for (Bar &x : B) {} @@ -194,7 +194,7 @@ void test3() { for (const Bar &&x : C) {} // No warning, rvalue-reference to the temporary for (const Bar &x : C) {} - // expected-warning@-1 {{always a copy}} + // expected-warning@-1 {{binds to a temporary value produced by a range}} // expected-note@-2 {{'Bar'}} // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:19}:"" for (const Bar x : C) {} @@ -209,7 +209,7 @@ void test3() { for (const int &&x : C) {} // No warning, rvalue-reference to the temporary for (const int &x : C) {} - // expected-warning@-1 {{always a copy}} + // expected-warning@-1 {{binds to a temporary value produced by a range}} // expected-note@-2 {{'int'}} // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:19}:"" for (const int x : C) {} @@ -241,17 +241,17 @@ void test4() { // No warning for (const int &&x : D) {} - // expected-warning@-1 {{resulting in a copy}} + // expected-warning@-1 {{binds to a temporary constructed from}} // expected-note-re@-2 {{'int'{{.*}}'const Bar &'}} // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:20}:"" for (const int &x : D) {} - // expected-warning@-1 {{resulting in a copy}} + // expected-warning@-1 {{binds to a temporary constructed from}} // expected-note-re@-2 {{'int'{{.*}}'const Bar &'}} // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:19}:"" for (const int x : D) {} // No warning for (int &&x : D) {} - // expected-warning@-1 {{resulting in a copy}} + // expected-warning@-1 {{binds to a temporary constructed from}} // expected-note-re@-2 {{'int'{{.*}}'const Bar &'}} // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:12-[[@LINE-3]]:14}:"" //for (int &x : D) {} @@ -266,7 +266,7 @@ void test5() { for (const Bar &&x : E) {} // No warning, rvalue-reference to the temporary for (const Bar &x : E) {} - // expected-warning@-1 {{always a copy}} + // expected-warning@-1 {{binds to a temporary value produced by a range}} // expected-note@-2 {{'Bar'}} // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:19}:"" for (const Bar x : E) {} @@ -283,17 +283,17 @@ void test6() { Container<Foo&> F; for (const Bar &&x : F) {} - // expected-warning@-1 {{resulting in a copy}} + // expected-warning@-1 {{binds to a temporary constructed from}} // expected-note-re@-2 {{'Bar'{{.*}}'const Foo &'}} // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:20}:"" for (const Bar &x : F) {} - // expected-warning@-1 {{resulting in a copy}} + // expected-warning@-1 {{binds to a temporary constructed from}} // expected-note-re@-2 {{'Bar'{{.*}}'const Foo &'}} // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:19}:"" for (const Bar x : F) {} // No warning. for (Bar &&x : F) {} - // expected-warning@-1 {{resulting in a copy}} + // expected-warning@-1 {{binds to a temporary constructed from}} // expected-note-re@-2 {{'Bar'{{.*}}'const Foo &'}} // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:12-[[@LINE-3]]:14}:"" //for (Bar &x : F) {} @@ -319,17 +319,17 @@ void test7() { // No warning for (const int &&x : G) {} - // expected-warning@-1 {{resulting in a copy}} + // expected-warning@-1 {{binds to a temporary constructed from}} // expected-note-re@-2 {{'int'{{.*}}'const double &'}} // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:20}:"" for (const int &x : G) {} - // expected-warning@-1 {{resulting in a copy}} + // expected-warning@-1 {{binds to a temporary constructed from}} // expected-note-re@-2 {{'int'{{.*}}'const double &'}} // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:19}:"" for (const int x : G) {} // No warning for (int &&x : G) {} - // expected-warning@-1 {{resulting in a copy}} + // expected-warning@-1 {{binds to a temporary constructed from}} // expected-note-re@-2 {{'int'{{.*}}'const double &'}} // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:12-[[@LINE-3]]:14}:"" //for (int &x : G) {} @@ -338,17 +338,17 @@ void test7() { // No warning for (const Bar &&x : G) {} - // expected-warning@-1 {{resulting in a copy}} + // expected-warning@-1 {{binds to a temporary constructed from}} // expected-note-re@-2 {{'Bar'{{.*}}'const double &'}} // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:20}:"" for (const Bar &x : G) {} - // expected-warning@-1 {{resulting in a copy}} + // expected-warning@-1 {{binds to a temporary constructed from}} // expected-note-re@-2 {{'Bar'{{.*}}'const double &'}} // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:19}:"" for (const Bar x : G) {} // No warning for (Bar &&x : G) {} - // expected-warning@-1 {{resulting in a copy}} + // expected-warning@-1 {{binds to a temporary constructed from}} // expected-note-re@-2 {{'Bar'{{.*}}'const double &'}} // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:12-[[@LINE-3]]:14}:"" //for (Bar &x : G) {} @@ -374,17 +374,17 @@ void test8() { // No warning for (const Bar &&x : H) {} - // expected-warning@-1 {{resulting in a copy}} + // expected-warning@-1 {{binds to a temporary constructed from}} // expected-note-re@-2 {{'Bar'{{.*}}'const Foo &'}} // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:20}:"" for (const Bar &x : H) {} - // expected-warning@-1 {{resulting in a copy}} + // expected-warning@-1 {{binds to a temporary constructed from}} // expected-note-re@-2 {{'Bar'{{.*}}'const Foo &'}} // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:19}:"" for (const Bar x : H) {} // No warning for (Bar &&x: H) {} - // expected-warning@-1 {{resulting in a copy}} + // expected-warning@-1 {{binds to a temporary constructed from}} // expected-note-re@-2 {{'Bar'{{.*}}'const Foo &'}} // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:12-[[@LINE-3]]:14}:"" //for (Bar &x: H) {} @@ -412,17 +412,17 @@ void test9() { // No warning for (const int &&x : I) {} - // expected-warning@-1 {{resulting in a copy}} + // expected-warning@-1 {{binds to a temporary constructed from}} // expected-note-re@-2 {{'int'{{.*}}'const Bar &'}} // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:20}:"" for (const int &x : I) {} - // expected-warning@-1 {{resulting in a copy}} + // expected-warning@-1 {{binds to a temporary constructed from}} // expected-note-re@-2 {{'int'{{.*}}'const Bar &'}} // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:19}:"" for (const int x : I) {} // No warning for (int &&x : I) {} - // expected-warning@-1 {{resulting in a copy}} + // expected-warning@-1 {{binds to a temporary constructed from}} // expected-note-re@-2 {{'int'{{.*}}'const Bar &'}} // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:12-[[@LINE-3]]:14}:"" //for (int &x : I) {} @@ -435,22 +435,22 @@ void test10() { Container<Bar> C; for (const Bar &x : C) {} - // expected-warning@-1 {{always a copy}} + // expected-warning@-1 {{binds to a temporary value produced by a range}} // expected-note@-2 {{'Bar'}} // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:19}:"" for (const Bar& x : C) {} - // expected-warning@-1 {{always a copy}} + // expected-warning@-1 {{binds to a temporary value produced by a range}} // expected-note@-2 {{'Bar'}} // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:17-[[@LINE-3]]:18}:"" for (const Bar & x : C) {} - // expected-warning@-1 {{always a copy}} + // expected-warning@-1 {{binds to a temporary value produced by a range}} // expected-note@-2 {{'Bar'}} // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:20}:"" for (const Bar&x : C) {} - // expected-warning@-1 {{always a copy}} + // expected-warning@-1 {{binds to a temporary value produced by a range}} // expected-note@-2 {{'Bar'}} // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:17-[[@LINE-3]]:18}:" " } @@ -461,7 +461,7 @@ void test_template_function() { // loops with dependent types. Container<Bar> C; for (const Bar &x : C) {} - // expected-warning@-1 {{always a copy}} + // expected-warning@-1 {{binds to a temporary value produced by a range}} // expected-note@-2 {{'Bar'}} // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:19}:"" @@ -475,7 +475,7 @@ struct test_template_struct { static void static_member() { Container<Bar> C; for (const Bar &x : C) {} - // expected-warning@-1 {{always a copy}} + // expected-warning@-1 {{binds to a temporary value produced by a range}} // expected-note@-2 {{'Bar'}} // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:20-[[@LINE-3]]:21}:"" @@ -486,7 +486,7 @@ struct test_template_struct { void member() { Container<Bar> C; for (const Bar &x : C) {} - // expected-warning@-1 {{always a copy}} + // expected-warning@-1 {{binds to a temporary value produced by a range}} // expected-note@-2 {{'Bar'}} // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:20-[[@LINE-3]]:21}:"" @@ -500,7 +500,7 @@ struct test_struct_with_templated_member { void member() { Container<Bar> C; for (const Bar &x : C) {} - // expected-warning@-1 {{always a copy}} + // expected-warning@-1 {{binds to a temporary value produced by a range}} // expected-note@-2 {{'Bar'}} // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:20-[[@LINE-3]]:21}:"" } @@ -509,7 +509,7 @@ struct test_struct_with_templated_member { void template_member() { Container<Bar> C; for (const Bar &x : C) {} - // expected-warning@-1 {{always a copy}} + // expected-warning@-1 {{binds to a temporary value produced by a range}} // expected-note@-2 {{'Bar'}} // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:20-[[@LINE-3]]:21}:"" _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits