diff mbox

C++ PATCH for c++/65051 (wrong template instantiation in overload resolution)

Message ID 54DE2002.1070301@redhat.com
State New
Headers show

Commit Message

Jason Merrill Feb. 13, 2015, 4:02 p.m. UTC
My patch to make the compiler give more friendly diagnostics about 
cv-qual dropping in reference binding meant that we looked for 
conversions to incomplete class type, leading to instantiating that 
type, which can lead to errors that would not otherwise occur.  So don't 
try if the target is incomplete.

Tested x86_64-pc-linux-gnu, applying to trunk.
diff mbox

Patch

commit c16cd1efe8d627fab1e03a0278ea974edc3d947f
Author: Jason Merrill <jason@redhat.com>
Date:   Fri Feb 13 10:17:02 2015 -0500

    	PR c++/65051
    	* call.c (reference_binding): Don't look for bad conversion
    	if TO is incomplete.

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); }