aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2021-04-08 08:23:17 -0400
committerJason Merrill <jason@redhat.com>2021-04-08 12:02:27 -0400
commit9f74f9cf47ed9d65e65a06378041e9dd5698e49d (patch)
tree97dfd41e1cebae85a2d941549a1ccf5c8359a8d9
parent94279aacd061623a160b8dc1b9ea267ee435b0f8 (diff)
downloadgcc-9f74f9cf47ed9d65e65a06378041e9dd5698e49d.zip
gcc-9f74f9cf47ed9d65e65a06378041e9dd5698e49d.tar.gz
gcc-9f74f9cf47ed9d65e65a06378041e9dd5698e49d.tar.bz2
c++: improve reference binding diagnostic [PR91849]
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.
-rw-r--r--gcc/cp/call.c15
-rw-r--r--gcc/testsuite/g++.dg/conversion/pr66211.C2
-rw-r--r--gcc/testsuite/g++.dg/conversion/ref7.C17
3 files changed, 31 insertions, 3 deletions
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 4b81d0f..c9a8c0d 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -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
diff --git a/gcc/testsuite/g++.dg/conversion/pr66211.C b/gcc/testsuite/g++.dg/conversion/pr66211.C
index 770e8a0..5c1ae13 100644
--- a/gcc/testsuite/g++.dg/conversion/pr66211.C
+++ b/gcc/testsuite/g++.dg/conversion/pr66211.C
@@ -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
index 0000000..99347cb
--- /dev/null
+++ b/gcc/testsuite/g++.dg/conversion/ref7.C
@@ -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" }
+}