[clang] 33bb32b - [Sema] Reword -Wrange-loop-analysis warning messages

Aaron Puchert via cfe-commits cfe-commits at lists.llvm.org
Fri Mar 6 06:18:37 PST 2020


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 at +3 {{loop variable 'r' of type 'const Record' creates a copy from type 'const Record'}}
+  // expected-warning at +3 {{loop variable 'r' creates a copy from type 'const Record'}}
   // expected-note at +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 at +3 {{loop variable 'r' of type 'const Record' creates a copy from type 'const Record'}}
+  // expected-warning at +3 {{loop variable 'r' creates a copy from type 'const Record'}}
   // expected-note at +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 at +3 {{loop variable 'r' of type 'const Record' creates a copy from type 'const Record'}}
+  // expected-warning at +3 {{loop variable 'r' creates a copy from type 'const Record'}}
   // expected-note at +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 at +3 {{loop variable 'r' of type 'const Record' creates a copy from type 'const Record'}}
+  // expected-warning at +3 {{loop variable 'r' creates a copy from type 'const Record'}}
   // expected-note at +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 at -1 {{loop variable 'x' is always a copy because the range of type 'Container<int>' does not return a reference}}
+  // expected-warning at -1 {{loop variable 'x' binds to a temporary value produced by a range of type 'Container<int>'}}
   // expected-note at -2 {{use non-reference type 'int'}}
   // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:19}:""
 
   for (const double &x : int_container) {}
-  // expected-warning at -1 {{loop variable 'x' has type 'const double &' but is initialized with type 'int' resulting in a copy}}
-  // expected-note at -2 {{use non-reference type 'double' to keep the copy or type 'const int &' to prevent copying}}
+  // expected-warning at -1 {{loop variable 'x' of type 'const double &' binds to a temporary constructed from type 'int &'}}
+  // expected-note at -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 at -1 {{loop variable 'x' of type 'const Bar' creates a copy from type 'const Bar'}}
+  // expected-warning at -1 {{loop variable 'x' creates a copy from type 'const Bar'}}
   // expected-note at -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 at -1 {{always a copy}}
+  // expected-warning at -1 {{binds to a temporary value produced by a range}}
   // expected-note at -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 at -1 {{always a copy}}
+  // expected-warning at -1 {{binds to a temporary value produced by a range}}
   // expected-note at -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 at -1 {{always a copy}}
+  // expected-warning at -1 {{binds to a temporary value produced by a range}}
   // expected-note at -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 at -1 {{resulting in a copy}}
+  // expected-warning at -1 {{binds to a temporary constructed from}}
   // expected-note-re at -2 {{'double'{{.*}}'const int &'}}
   // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:21-[[@LINE-3]]:23}:""
   for (const double &x : B) {}
-  // expected-warning at -1 {{resulting in a copy}}
+  // expected-warning at -1 {{binds to a temporary constructed from}}
   // expected-note-re at -2 {{'double'{{.*}}'const int &'}}
   // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:21-[[@LINE-3]]:22}:""
   for (const double x : B) {}
   for (double &&x : B) {}
-  // expected-warning at -1 {{resulting in a copy}}
+  // expected-warning at -1 {{binds to a temporary constructed from}}
   // expected-note-re at -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 at -1 {{resulting in a copy}}
+  // expected-warning at -1 {{binds to a temporary constructed from}}
   // expected-note at -2 {{'Bar'}}
   // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:20}:""
   for (const Bar &x : B) {}
-  // expected-warning at -1 {{resulting in a copy}}
+  // expected-warning at -1 {{binds to a temporary constructed from}}
   // expected-note at -2 {{'Bar'}}
   // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:19}:""
   for (const Bar x : B) {}
   for (Bar &&x : B) {}
-  // expected-warning at -1 {{resulting in a copy}}
+  // expected-warning at -1 {{binds to a temporary constructed from}}
   // expected-note at -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 at -1 {{always a copy}}
+  // expected-warning at -1 {{binds to a temporary value produced by a range}}
   // expected-note at -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 at -1 {{always a copy}}
+  // expected-warning at -1 {{binds to a temporary value produced by a range}}
   // expected-note at -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 at -1 {{resulting in a copy}}
+  // expected-warning at -1 {{binds to a temporary constructed from}}
   // expected-note-re at -2 {{'int'{{.*}}'const Bar &'}}
   // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:20}:""
   for (const int &x : D) {}
-  // expected-warning at -1 {{resulting in a copy}}
+  // expected-warning at -1 {{binds to a temporary constructed from}}
   // expected-note-re at -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 at -1 {{resulting in a copy}}
+  // expected-warning at -1 {{binds to a temporary constructed from}}
   // expected-note-re at -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 at -1 {{always a copy}}
+  // expected-warning at -1 {{binds to a temporary value produced by a range}}
   // expected-note at -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 at -1 {{resulting in a copy}}
+  // expected-warning at -1 {{binds to a temporary constructed from}}
   // expected-note-re at -2 {{'Bar'{{.*}}'const Foo &'}}
   // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:20}:""
   for (const Bar &x : F) {}
-  // expected-warning at -1 {{resulting in a copy}}
+  // expected-warning at -1 {{binds to a temporary constructed from}}
   // expected-note-re at -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 at -1 {{resulting in a copy}}
+  // expected-warning at -1 {{binds to a temporary constructed from}}
   // expected-note-re at -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 at -1 {{resulting in a copy}}
+  // expected-warning at -1 {{binds to a temporary constructed from}}
   // expected-note-re at -2 {{'int'{{.*}}'const double &'}}
   // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:20}:""
   for (const int &x : G) {}
-  // expected-warning at -1 {{resulting in a copy}}
+  // expected-warning at -1 {{binds to a temporary constructed from}}
   // expected-note-re at -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 at -1 {{resulting in a copy}}
+  // expected-warning at -1 {{binds to a temporary constructed from}}
   // expected-note-re at -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 at -1 {{resulting in a copy}}
+  // expected-warning at -1 {{binds to a temporary constructed from}}
   // expected-note-re at -2 {{'Bar'{{.*}}'const double &'}}
   // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:20}:""
   for (const Bar &x : G) {}
-  // expected-warning at -1 {{resulting in a copy}}
+  // expected-warning at -1 {{binds to a temporary constructed from}}
   // expected-note-re at -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 at -1 {{resulting in a copy}}
+  // expected-warning at -1 {{binds to a temporary constructed from}}
   // expected-note-re at -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 at -1 {{resulting in a copy}}
+  // expected-warning at -1 {{binds to a temporary constructed from}}
   // expected-note-re at -2 {{'Bar'{{.*}}'const Foo &'}}
   // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:20}:""
   for (const Bar &x : H) {}
-  // expected-warning at -1 {{resulting in a copy}}
+  // expected-warning at -1 {{binds to a temporary constructed from}}
   // expected-note-re at -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 at -1 {{resulting in a copy}}
+  // expected-warning at -1 {{binds to a temporary constructed from}}
   // expected-note-re at -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 at -1 {{resulting in a copy}}
+  // expected-warning at -1 {{binds to a temporary constructed from}}
   // expected-note-re at -2 {{'int'{{.*}}'const Bar &'}}
   // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:20}:""
   for (const int &x : I) {}
-  // expected-warning at -1 {{resulting in a copy}}
+  // expected-warning at -1 {{binds to a temporary constructed from}}
   // expected-note-re at -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 at -1 {{resulting in a copy}}
+  // expected-warning at -1 {{binds to a temporary constructed from}}
   // expected-note-re at -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 at -1 {{always a copy}}
+  // expected-warning at -1 {{binds to a temporary value produced by a range}}
   // expected-note at -2 {{'Bar'}}
   // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:19}:""
 
   for (const Bar& x : C) {}
-  // expected-warning at -1 {{always a copy}}
+  // expected-warning at -1 {{binds to a temporary value produced by a range}}
   // expected-note at -2 {{'Bar'}}
   // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:17-[[@LINE-3]]:18}:""
 
   for (const Bar & x : C) {}
-  // expected-warning at -1 {{always a copy}}
+  // expected-warning at -1 {{binds to a temporary value produced by a range}}
   // expected-note at -2 {{'Bar'}}
   // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:18-[[@LINE-3]]:20}:""
 
   for (const Bar&x : C) {}
-  // expected-warning at -1 {{always a copy}}
+  // expected-warning at -1 {{binds to a temporary value produced by a range}}
   // expected-note at -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 at -1 {{always a copy}}
+  // expected-warning at -1 {{binds to a temporary value produced by a range}}
   // expected-note at -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 at -1 {{always a copy}}
+    // expected-warning at -1 {{binds to a temporary value produced by a range}}
     // expected-note at -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 at -1 {{always a copy}}
+    // expected-warning at -1 {{binds to a temporary value produced by a range}}
     // expected-note at -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 at -1 {{always a copy}}
+    // expected-warning at -1 {{binds to a temporary value produced by a range}}
     // expected-note at -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 at -1 {{always a copy}}
+    // expected-warning at -1 {{binds to a temporary value produced by a range}}
     // expected-note at -2 {{'Bar'}}
     // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:20-[[@LINE-3]]:21}:""
 


        


More information about the cfe-commits mailing list