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 4b81d0f..c9a8c0d 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 770e8a0..5c1ae13 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" }
+}