https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77875

Jonathan Wakely <redi at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |rejects-valid
             Status|UNCONFIRMED                 |NEW
   Last reconfirmed|                            |2019-03-27
     Ever confirmed|0                           |1

--- Comment #2 from Jonathan Wakely <redi at gcc dot gnu.org> ---
From PR 89857:

gcc doesn't compile the following well-formed program:

void foo () {
    using T = int&;
    int i{};
    T{i};
}

$ g++ -std=c++17 -c gcc_bug2.cpp 
gcc_bug2.cpp: In function ‘void foo()’:
gcc_bug2.cpp:4:8: error: invalid cast of an rvalue expression of type ‘int’ to
type ‘T’ {aka ‘int&’}
     T{i};

Quoting from the standard draft:

http://eel.is/c++draft/dcl.init.list#3.9

Otherwise, if the initializer list has a single element of type E and either T
is not a reference type or its referenced type is reference-related to E, the
object or reference is initialized from that element (by copy-initialization
for copy-list-initialization, or by direct-initialization for
direct-list-initialization); if a narrowing conversion (see below) is required
to convert the element to T, the program is ill-formed.

According to the error, it looks like gcc skips this and tries to apply the
next rule:

Otherwise, if T is a reference type, a prvalue of the type referenced by T is
generated.
The prvalue initializes its result object by copy-list-initialization.
The prvalue is then used to direct-initialize the reference.
[ Note: As usual, the binding will fail and the program is ill-formed if the
reference type is an lvalue reference to a non-const type.
— end note ]

Note: The current behavior was originally a defect in the C++11 standard that
was corrected in CWG1288.
http://open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html#1288

Reply via email to