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.

Reply via email to