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

Jonathan Wakely jwakely@redhat.com
Fri Aug 5 09:09:00 GMT 2016


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?


-------------- next part --------------
A non-text attachment was scrubbed...
Name: patch.txt
Type: text/x-patch
Size: 5106 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20160805/b0e42edc/attachment.bin>


More information about the Gcc-patches mailing list