Patchwork C++ PATCH to overload resolution in synthesized member functions

login
register
mail settings
Submitter Jason Merrill
Date Aug. 19, 2010, 5:23 p.m.
Message ID <4C6D6875.7090301@redhat.com>
Download mbox | patch
Permalink /patch/62208/
State New
Headers show

Comments

Jason Merrill - Aug. 19, 2010, 5:23 p.m.
The overload resolution hack I made to fix c++/44909 is coming to seem 
like the right way to fix this issue in the standard; this patch refines 
it a bit so that overload resolution is the same in determining the 
signature and in actually defining the function.

Tested x86_64-pc-linux-gnu, applied to trunk.

Patch

commit 96b87db748e5800d276887ae90dc85634c5d9bbc
Author: Jason Merrill <jason@redhat.com>
Date:   Wed Aug 18 18:20:12 2010 -0400

    	* call.c (reference_related_p): Check for error_mark_node.
    	(add_function_candidate): Check it instead of
    	same_type_ignoring_top_level_qualifiers_p.

diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 71297ec..adcf984 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -999,6 +999,9 @@  standard_conversion (tree to, tree from, tree expr, bool c_cast_p,
 bool
 reference_related_p (tree t1, tree t2)
 {
+  if (t1 == error_mark_node || t2 == error_mark_node)
+    return false;
+
   t1 = TYPE_MAIN_VARIANT (t1);
   t2 = TYPE_MAIN_VARIANT (t2);
 
@@ -1598,8 +1601,10 @@  add_function_candidate (struct z_candidate **candidates,
 
   /* Kludge: When looking for a function from a subobject while generating
      an implicit copy/move constructor/operator=, don't consider anything
-     that takes (a reference to) a different type.  See c++/44909.  */
-  else if (flags & LOOKUP_SPECULATIVE)
+     that takes (a reference to) an unrelated type.  See c++/44909.  */
+  else if ((flags & LOOKUP_SPECULATIVE)
+	   || (current_function_decl
+	       && DECL_DEFAULTED_FN (current_function_decl)))
     {
       if (DECL_CONSTRUCTOR_P (fn))
 	i = 1;
@@ -1611,8 +1616,8 @@  add_function_candidate (struct z_candidate **candidates,
       if (i && len == i)
 	{
 	  parmnode = chain_index (i-1, parmlist);
-	  if (!(same_type_ignoring_top_level_qualifiers_p
-		(non_reference (TREE_VALUE (parmnode)), ctype)))
+	  if (!reference_related_p (non_reference (TREE_VALUE (parmnode)),
+				    ctype))
 	    viable = 0;
 	}
     }
diff --git a/gcc/testsuite/g++.dg/init/synth3.C b/gcc/testsuite/g++.dg/init/synth3.C
new file mode 100644
index 0000000..d656ddb
--- /dev/null
+++ b/gcc/testsuite/g++.dg/init/synth3.C
@@ -0,0 +1,21 @@ 
+// Test that synthesizing the C copy constructor doesn't require B<int> to
+// be complete.
+
+template <class T>
+struct B
+{
+  typename T::NT nt;
+};
+
+struct A
+{
+  A ();
+  A (const A&);
+  A (const B<int>&);
+};
+
+struct C: A { };
+
+C c;
+C c2(c);
+