RFC: Make diagnostics for C++ reference binding more consistent

Jason Merrill jason@redhat.com
Fri Aug 5 16:14:00 GMT 2016


OK.

On Fri, Aug 5, 2016 at 5:08 AM, Jonathan Wakely <jwakely@redhat.com> wrote:
> On 27/07/16 18:06 -0400, Jason Merrill wrote:
>>
>> On Wed, Jul 27, 2016 at 8:05 AM, Jonathan Wakely <jwakely@redhat.com>
>> wrote:
>>>
>>> Consider:
>>>
>>> template<typename T> T declval();
>>>
>>> int& r1 = declval<int&&>();
>>> int&& r2 = declval<int&>();
>>> int& r3 = declval<const int&>();
>>>
>>>
>>> This produces three quite different errors:
>>>
>>>
>>> refs.cc:3:25: error: invalid initialization of non-const reference of
>>> type
>>> 'int&' from an rvalue of type 'int'
>>> int& r1 = declval<int&&>();
>>>           ~~~~~~~~~~~~~~^~
>>> refs.cc:4:25: error: cannot bind 'int' lvalue to 'int&&'
>>> int&& r2 = declval<int&>();
>>>            ~~~~~~~~~~~~~^~
>>> refs.cc:5:30: error: binding 'const int' to reference of type 'int&'
>>> discards qualifiers
>>> int& r3 = declval<const int&>();
>>>           ~~~~~~~~~~~~~~~~~~~^~
>>>
>>>
>>> The first one uses the order to/from, but the other two are from/to.
>>>
>>> The first and second are saying the same thing (wrong value category)
>>> but very differently.
>>>
>>> The first and third mention references but the second doesn't.
>>>
>>> The standard talks about binding a reference to something, but the
>>> second and third diagnostics talk about binding something to a
>>> reference (and the first doesn't mention binding at all).
>>>
>>> The first diagnostic is specific to lvalue references (it wouldn't be
>>> invalid if it was binding a non-const _rvalue_ reference to an
>>> rvalue), but doesn't use the word "lvalue".
>>>
>>> (FWIW Clang and EDG both have their own inconsistencies for the same
>>> example, but that shouldn't stop us trying to improve.)
>>>
>>>
>>> IMHO the first should use the words "bind" and "lvalue reference":
>>>
>>> refs.cc:3:25: error: cannot bind non-const lvalue reference of type
>>> 'int&'
>>> to an rvalue of type 'int'
>>> int& r1 = declval<int&&>();
>>>           ~~~~~~~~~~~~~~^~
>>>
>>> The second should use the phrasing "bind ref to value" instead of
>>> "bind value to ref", and mention "rvalue reference":
>>>
>>> refs.cc:4:25: error: cannot bind rvalue reference of type 'int&&' to an
>>> lvalue of type 'int'
>>> int&& r2 = declval<int&>();
>>>            ~~~~~~~~~~~~~^~
>>>
>>> The third should use the same phrasing (but doesn't need to mention
>>> lvalue/rvalue because the problem is related to cv-qualifiers not
>>> value categories):
>>>
>>> refs.cc:5:30: error: binding reference of type 'int&' to 'const int'
>>> discards qualifiers
>>> int& r3 = declval<const int&>();
>>>           ~~~~~~~~~~~~~~~~~~~^~
>>>
>>>
>>> I've only considered trivial examples here, is there some reason to
>>> prefer to current diagnostics for more complex cases?
>>>
>>> The attached patch makes that change, but there are probably lots of
>>> tests that would need updating which I haven't done until I know if
>>> the change is worthwhile.
>>
>>
>> Sounds good to me.
>
>
> Here's the full patch then. There weren't too many tests to adjust.
>
> Tested x86_64-linux. OK for trunk?
>
>



More information about the Gcc-patches mailing list