Patchwork C++ PATCH for c++/51079 (DR 495, checking second conv before template)

login
register
mail settings
Submitter Jason Merrill
Date Nov. 10, 2011, 8:27 p.m.
Message ID <4EBC33C1.1080800@redhat.com>
Download mbox | patch
Permalink /patch/125001/
State New
Headers show

Comments

Jason Merrill - Nov. 10, 2011, 8:27 p.m.
DR 495 changed the order of these rules.

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

Patch

commit dc49a72a22b10b39edc054414537bda44ce82546
Author: Jason Merrill <jason@redhat.com>
Date:   Thu Nov 10 14:59:15 2011 -0500

    	PR c++/51079, DR 495
    	* call.c (joust): Check the second conversion sequence
    	before checking templates.

diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 578905e..e81950c 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -8109,6 +8109,22 @@  joust (struct z_candidate *cand1, struct z_candidate *cand2, bool warn)
   if (winner)
     return winner;
 
+  /* DR 495 moved this tiebreaker above the template ones.  */
+  /* or, if not that,
+     the  context  is  an  initialization by user-defined conversion (see
+     _dcl.init_  and  _over.match.user_)  and  the  standard   conversion
+     sequence  from  the return type of F1 to the destination type (i.e.,
+     the type of the entity being initialized)  is  a  better  conversion
+     sequence  than the standard conversion sequence from the return type
+     of F2 to the destination type.  */
+
+  if (cand1->second_conv)
+    {
+      winner = compare_ics (cand1->second_conv, cand2->second_conv);
+      if (winner)
+	return winner;
+    }
+
   /* or, if not that,
      F1 is a non-template function and F2 is a template function
      specialization.  */
@@ -8137,21 +8153,6 @@  joust (struct z_candidate *cand1, struct z_candidate *cand2, bool warn)
 	return winner;
     }
 
-  /* or, if not that,
-     the  context  is  an  initialization by user-defined conversion (see
-     _dcl.init_  and  _over.match.user_)  and  the  standard   conversion
-     sequence  from  the return type of F1 to the destination type (i.e.,
-     the type of the entity being initialized)  is  a  better  conversion
-     sequence  than the standard conversion sequence from the return type
-     of F2 to the destination type.  */
-
-  if (cand1->second_conv)
-    {
-      winner = compare_ics (cand1->second_conv, cand2->second_conv);
-      if (winner)
-	return winner;
-    }
-
   /* Check whether we can discard a builtin candidate, either because we
      have two identical ones or matching builtin and non-builtin candidates.
 
diff --git a/gcc/testsuite/g++.dg/template/conv12.C b/gcc/testsuite/g++.dg/template/conv12.C
new file mode 100644
index 0000000..e6af054
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/conv12.C
@@ -0,0 +1,25 @@ 
+// PR c++/51079
+
+#if __cplusplus > 199711L
+struct C1
+{
+  template <class T>
+  operator T() = delete;	// { dg-message "declared here" "" { target c++11 } }
+  operator bool() { return false; }
+} c1;
+
+int ic1 = c1;			// { dg-error "deleted" "" { target c++11 } }
+int ac1 = c1 + c1;		// { dg-error "deleted" "" { target c++11 } }
+#endif
+
+struct C2
+{
+private:
+  template <class T>
+  operator T();			// { dg-error "private" }
+public:
+  operator bool() { return false; }
+} c2;
+
+int ic2 = c2;			// { dg-error "" }
+int ac2 = c2 + c2;		// { dg-error "" }