https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100635
Bug ID: 100635 Summary: error: cannot bind non-const lvalue reference of type 'const volatile int&' to ... Product: gcc Version: 11.1.1 Status: UNCONFIRMED Keywords: diagnostic Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: redi at gcc dot gnu.org Target Milestone: --- void foo(const volatile int&) { } volatile int&& declvol(); using X = decltype(foo(declvol())); This code is invalid and is correctly rejected, but the diagnostic is bad: vol.C:3:31: error: cannot bind non-const lvalue reference of type 'const volatile int&' to an rvalue of type 'volatile int' 3 | using X = decltype(foo(declvol())); | ~~~~~~~^~ vol.C:1:10: note: initializing argument 1 of 'void foo(const volatile int&)' 1 | void foo(const volatile int&) { } | ^~~~~~~~~~~~~~~~~~~ vol.C:3:31: error: cannot bind non-const lvalue reference of type 'const volatile int&' to an rvalue of type 'volatile int' 3 | using X = decltype(foo(declvol())); | ~~~~~~~^~ vol.C:1:10: note: initializing argument 1 of 'void foo(const volatile int&)' 1 | void foo(const volatile int&) { } | ^~~~~~~~~~~~~~~~~~~ The error says "non-const lvalue reference" but then shows a const volatile lvalue reference, so "non-const" is wrong. The error also shouldn't be printed twice. I'm not sure about the duplicate error (something tries to perform the conversion twice and both times fail?) but the first problem could probably be fixed by simply omitting the "non-const" for the case of a reference-to-volatile: vol.C:3:31: error: cannot bind lvalue reference of type 'const volatile int&' to an rvalue of type 'volatile int' This is accurate, because the relevant rule is: Otherwise, if the reference is an lvalue reference to a type that is not const-qualified or is volatile-qualified, the program is ill-formed. i.e. binding an lvalue reference to an rvalue is ill-formed for non-const types (as the current diagnostic covers) and for volatile types (as in the testcase above). For the latter case, simple saying "cannot bind lvalue reference" would be fine.