http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48453

           Summary: [C++0x] Invalid reference initialization via explicit
                    conversion
           Product: gcc
           Version: 4.7.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
        AssignedTo: unassig...@gcc.gnu.org
        ReportedBy: daniel.krueg...@googlemail.com
                CC: ja...@redhat.com


GCC 4.7.0 accepts the following code in C++0x mode:

template<class T>
T&& create();

template<class T, class Arg>
void test() {
 T t(create<Arg>());
 (void) t;
}

template<class T>
struct To {
 explicit operator T();
};

int main()
{
 test<int&, To<int&>>(); // a Well-formed
 test<int&&, To<int&&>>(); // b Well-formed
}

This code should be ill-formed because of the *explicit* conversion to a
reference type. 

The semantics of this program is described in 8.5.3 [dcl.init.ref] p. 5
(referring to WD N3242). In case of (a) we first inter into bullet 1 ("If the
reference is an lvalue reference"). Sub-bullet 1 does not apply, then we have
to inspect sub-bullet 2:

"has a class type (i.e., T2 is a class type), where T1 is not reference-related
to T2, and can be implicitly converted to an lvalue of type “cv3 T3,” where
“cv1 T1” is reference-compatible with “cv3 T3”106 (this conversion is selected
by enumerating the applicable conversion functions (13.3.1.6) and choosing the
best one through overload resolution (13.3)),"

This *seems* to fit, except that there is no *implicit* conversion possible
here, so we cannot enter this rule. For (a) bullet 2 does not apply and we must
fail immediately.

For (b) we ignore bullet 1, but step into bullet 2 because of the
rvalue-reference. Again, sub-bullet 1 does not apply, only sub-bullet 2 comes
near:

"has a class type (i.e., T2 is a class type), where T1 is not reference-related
to T2, and can be implicitly converted to an xvalue, class prvalue, or function
lvalue of type “cv3 T3”, where “cv1 T1” is reference-compatible with “cv3 T3”,"

Again, we have *no* implicit conversion, but now we need to try the last
sub-bullet 3:

"Otherwise, a temporary of type “cv1 T1” is created and initialized from the
initializer expression using the rules for a non-reference copy-initialization
(8.5). [..]"

The semantics of a non-reference copy-initialization forbids the consideration
of the explicit conversion function, thus, we should fail again.

Reply via email to