This is the mail archive of the mailing list for the GCC project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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

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.
commit c16cd1efe8d627fab1e03a0278ea974edc3d947f
Author: Jason Merrill <>
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.  */
+      && !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); }

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]