aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2015-02-13 11:02:31 -0500
committerJason Merrill <jason@gcc.gnu.org>2015-02-13 11:02:31 -0500
commitf9b600badc7e9e5700ec26e930e0b98ba568edee (patch)
treedbb55398a6d97ba972543d45d0fd1f8e29af430a /gcc
parent81adbcea49c3dbc5bb1fe4211e113a9141d13263 (diff)
downloadgcc-f9b600badc7e9e5700ec26e930e0b98ba568edee.zip
gcc-f9b600badc7e9e5700ec26e930e0b98ba568edee.tar.gz
gcc-f9b600badc7e9e5700ec26e930e0b98ba568edee.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/call.c13
-rw-r--r--gcc/testsuite/g++.dg/template/overload14.C18
3 files changed, 37 insertions, 0 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index a39acaa..8468771 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,9 @@
+2015-02-13 Jason Merrill <jason@redhat.com>
+
+ PR c++/65051
+ * call.c (reference_binding): Don't look for bad conversion
+ if TO is incomplete.
+
2015-02-13 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/64970
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index f2076c6..2b15185 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 0000000..ec2c381
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/overload14.C
@@ -0,0 +1,18 @@
+// PR c++/65051
+
+template<typename T> struct wrap { typedef T type; };
+template <class T> class rv: public wrap <T>::type {};
+
+template <class value_type>
+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<U> b, const U& u) { b.push_back(u); }