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.
This commit is contained in:
Jason Merrill 2021-04-08 08:23:17 -04:00
parent 94279aacd0
commit 9f74f9cf47
3 changed files with 31 additions and 3 deletions

View 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)))
{
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

View 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" }
}

View File

@ -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" }
}