From: Jason Merrill Date: Fri, 13 Feb 2015 16:02:31 +0000 (-0500) Subject: re PR c++/65051 (r210436 regression?) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=f9b600badc7e9e5700ec26e930e0b98ba568edee;p=gcc.git re PR c++/65051 (r210436 regression?) PR c++/65051 * call.c (reference_binding): Don't look for bad conversion if TO is incomplete. From-SVN: r220685 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index a39acaab759..84687715921 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2015-02-13 Jason Merrill + + PR c++/65051 + * call.c (reference_binding): Don't look for bad conversion + if TO is incomplete. + 2015-02-13 Paolo Carlini PR c++/64970 diff --git a/gcc/cp/call.c b/gcc/cp/call.c index f2076c67aee..2b15185a895 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -1694,6 +1694,19 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags, difference in top-level cv-qualification is subsumed by the initialization itself and does not constitute a conversion. */ + /* [dcl.init.ref] + + Otherwise, the reference shall be an lvalue reference to a + non-volatile const type, or the reference shall be an rvalue + reference. + + We try below to treat this as a bad conversion to improve diagnostics, + but if TO is an incomplete class, we need to reject this conversion + now to avoid unnecessary instantiation. */ + if (!CP_TYPE_CONST_NON_VOLATILE_P (to) && !TYPE_REF_IS_RVALUE (rto) + && !COMPLETE_TYPE_P (to)) + return NULL; + /* We're generating a temporary now, but don't bind any more in the conversion (specifically, don't slice the temporary returned by a conversion operator). */ diff --git a/gcc/testsuite/g++.dg/template/overload14.C b/gcc/testsuite/g++.dg/template/overload14.C new file mode 100644 index 00000000000..ec2c3815100 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/overload14.C @@ -0,0 +1,18 @@ +// PR c++/65051 + +template struct wrap { typedef T type; }; +template class rv: public wrap ::type {}; + +template +struct circular_buffer +{ + typedef const value_type& param_value_type; + typedef rv< value_type >& rvalue_type; + + void push_back(param_value_type item) {} + void push_back(rvalue_type item) {} +}; + +union U { int i; char c; }; + +void f(circular_buffer b, const U& u) { b.push_back(u); }