[pushed] c++: improve reference binding diagnostic [PR91849]
Jason Merrill
jason@redhat.com
Thu Apr 8 16:01:09 GMT 2021
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.
Tested x86_64-pc-linux-gnu, applying to trunk.
gcc/cp/ChangeLog:
PR c++/91849
* call.c (convert_like_internal): Improve reference diagnostic.
gcc/testsuite/ChangeLog:
PR c++/91849
* g++.dg/conversion/ref7.C: New test.
---
gcc/cp/call.c | 15 +++++++++++++--
gcc/testsuite/g++.dg/conversion/pr66211.C | 2 +-
gcc/testsuite/g++.dg/conversion/ref7.C | 17 +++++++++++++++++
3 files changed, 31 insertions(+), 3 deletions(-)
create mode 100644 gcc/testsuite/g++.dg/conversion/ref7.C
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 4b81d0ff333..c9a8c0d305f 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 770e8a0e20f..5c1ae13c76d 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 00000000000..99347cb1c27
--- /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" }
+}
base-commit: ac24fa46e449fbff0ff571951cfcc78b8488f6e7
--
2.27.0
More information about the Gcc-patches
mailing list