]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: improve reference binding diagnostic [PR91849]
authorJason Merrill <jason@redhat.com>
Thu, 8 Apr 2021 12:23:17 +0000 (08:23 -0400)
committerJason Merrill <jason@redhat.com>
Thu, 8 Apr 2021 16:02:27 +0000 (12:02 -0400)
Here we were complaining about binding the lvalue reference to the rvalue
result of converting from float to int, but didn't mention that conversion.
Talk about the type of the initializer instead.

gcc/cp/ChangeLog:

PR c++/91849
* call.c (convert_like_internal): Improve reference diagnostic.

gcc/testsuite/ChangeLog:

PR c++/91849
* g++.dg/conversion/pr66211.C: Adjust diagnostic.
* g++.dg/conversion/ref7.C: New test.

gcc/cp/call.c
gcc/testsuite/g++.dg/conversion/pr66211.C
gcc/testsuite/g++.dg/conversion/ref7.C [new file with mode: 0644]

index 4b81d0ff33311676d5f7e6b1397c0176a479a886..c9a8c0d305f81eb4b963be5dc4b56d52f7953d4d 100644 (file)
@@ -7898,8 +7898,19 @@ convert_like_internal (conversion *convs, tree expr, tree fn, int argnum,
                         "lvalue of type %qI", totype, extype);
            else if (!TYPE_REF_IS_RVALUE (ref_type) && !lvalue_p (expr)
                     && !CP_TYPE_CONST_NON_VOLATILE_P (TREE_TYPE (ref_type)))
-             error_at (loc, "cannot bind non-const lvalue reference of "
-                       "type %qH to an rvalue of type %qI", totype, extype);
+             {
+               conversion *next = next_conversion (convs);
+               if (next->kind == ck_std)
+                 {
+                   next = next_conversion (next);
+                   error_at (loc, "cannot bind non-const lvalue reference of "
+                             "type %qH to a value of type %qI",
+                             totype, next->type);
+                 }
+               else
+                 error_at (loc, "cannot bind non-const lvalue reference of "
+                           "type %qH to an rvalue of type %qI", totype, extype);
+             }
            else if (!reference_compatible_p (TREE_TYPE (totype), extype))
              {
                /* If we're converting from T[] to T[N], don't talk
index 770e8a0e20f26445ee4b34d69263aac7e022d4fa..5c1ae13c76d02e17beaffea617f1699c5b80560f 100644 (file)
@@ -7,5 +7,5 @@ int main()
 {
   int x = 0;
   double y = 1;
-  f(1 > 0 ? x : y); // { dg-error "cannot bind .* to an rvalue" }
+  f(1 > 0 ? x : y); // { dg-error "cannot bind non-const lvalue reference of type .int&. to a value of type .double" }
 }
diff --git a/gcc/testsuite/g++.dg/conversion/ref7.C b/gcc/testsuite/g++.dg/conversion/ref7.C
new file mode 100644 (file)
index 0000000..99347cb
--- /dev/null
@@ -0,0 +1,17 @@
+// PR c++/91849
+
+struct A { operator float(); };
+
+void
+g ()
+{
+  float f = 1.f;
+  int &r = f;                  // { dg-error "float" }
+  int &r2 = A();               // { dg-error "float" }
+}
+
+void
+g2 ()
+{
+  int &r = 1.f;                        // { dg-error "float" }
+}