re PR c++/20723 (ICE in more_specialized_fn, more than one user-defined conversion...
authorNathan Sidwell <nathan@codesourcery.com>
Sun, 3 Apr 2005 12:33:02 +0000 (12:33 +0000)
committerNathan Sidwell <nathan@gcc.gnu.org>
Sun, 3 Apr 2005 12:33:02 +0000 (12:33 +0000)
cp:
PR c++/20723
* pt.c (more_specialized_fn): Member functions are unordered wrt
non-members.  Conversion operators are unordered wrt other
functions.
testsuite:
PR c++/20723
* g++.dg/template/spec22.C: New.
* g++.dg/template/spec23.C: New.

From-SVN: r97489

gcc/cp/ChangeLog
gcc/cp/pt.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/template/spec22.C [new file with mode: 0644]
gcc/testsuite/g++.dg/template/spec23.C [new file with mode: 0644]

index 4065f17469377b142c470ee1b16587e956743724..90a68926ecfbc8c8cdd79ebffca820db53c289a3 100644 (file)
@@ -1,3 +1,10 @@
+2005-04-03  Nathan Sidwell  <nathan@codesourcery.com>
+
+       PR c++/20723
+       * pt.c (more_specialized_fn): Member functions are unordered wrt
+       non-members.  Conversion operators are unordered wrt other
+       functions.
+
 2005-04-01  Nathan Sidwell  <nathan@codesourcery.com>
 
        * call.c (add_template_candidates_real): Remove length parameter
index f92ce90a7f0fad2c65f47274c3d8f2ed45b06936..e8b219080a5b289be34412a207b433588c1100c5 100644 (file)
@@ -10407,17 +10407,23 @@ more_specialized_fn (tree pat1, tree pat2, int len)
   int better1 = 0;
   int better2 = 0;
 
+  /* If only one is a member function, they are unordered.  */
+  if (DECL_FUNCTION_MEMBER_P (decl1) != DECL_FUNCTION_MEMBER_P (decl2))
+    return 0;
+  
   /* Don't consider 'this' parameter.  */
   if (DECL_NONSTATIC_MEMBER_FUNCTION_P (decl1))
     args1 = TREE_CHAIN (args1);
-  
   if (DECL_NONSTATIC_MEMBER_FUNCTION_P (decl2))
     args2 = TREE_CHAIN (args2);
 
+  /* If only one is a conversion operator, they are unordered.  */
+  if (DECL_CONV_FN_P (decl1) != DECL_CONV_FN_P (decl2))
+    return 0;
+  
   /* Consider the return type for a conversion function */
   if (DECL_CONV_FN_P (decl1))
     {
-      gcc_assert (DECL_CONV_FN_P (decl2));
       args1 = tree_cons (NULL_TREE, TREE_TYPE (TREE_TYPE (decl1)), args1);
       args2 = tree_cons (NULL_TREE, TREE_TYPE (TREE_TYPE (decl2)), args2);
       len++;
index 612dcab58956c5fa94904eb6e303a96a47e692a3..7191f88e7df79807a0aeb4183919c98c84493a99 100644 (file)
@@ -1,3 +1,9 @@
+2005-04-03  Nathan Sidwell  <nathan@codesourcery.com>
+
+       PR c++/20723
+       * g++.dg/template/spec22.C: New.
+       * g++.dg/template/spec23.C: New.
+
 2005-04-03  Dale Ranta  <dir@lanl.gov>
             Francois-Xavier Coudert  <coudert@clipper.ens.fr>
 
diff --git a/gcc/testsuite/g++.dg/template/spec22.C b/gcc/testsuite/g++.dg/template/spec22.C
new file mode 100644 (file)
index 0000000..e2d439c
--- /dev/null
@@ -0,0 +1,22 @@
+// Copyright (C) 2005 Free Software Foundation, Inc.
+// Contributed by Nathan Sidwell 2 Apr 2005 <nathan@codesourcery.com>
+
+// PR 20723
+// Origin: Andrew Pinski <pinskia@gcc.gnu.org>
+//         Nathan Sidwell <nathan@gcc.gnu.org>
+
+template <typename T>
+int operator+ (T const &, int); // { dg-error "T = Foo" "" }
+
+struct Foo 
+{
+  template <typename T>
+  int operator+ (T) const; // { dg-error "T = int" "" }
+};
+
+int main ()
+{
+  Foo f;
+
+  return f + 0; // { dg-error "ambiguous overload" "" }
+}
diff --git a/gcc/testsuite/g++.dg/template/spec23.C b/gcc/testsuite/g++.dg/template/spec23.C
new file mode 100644 (file)
index 0000000..15618b1
--- /dev/null
@@ -0,0 +1,25 @@
+// Copyright (C) 2005 Free Software Foundation, Inc.
+// Contributed by Nathan Sidwell 2 Apr 2005 <nathan@codesourcery.com>
+
+// PR 20723
+// Origin: Andrew Pinski <pinskia@gcc.gnu.org>
+//         Nathan Sidwell <nathan@gcc.gnu.org>
+
+struct Foo
+{
+  template <typename T>
+  Foo (const T &); // { dg-error "T = Bar" "" }
+};
+
+struct Bar
+{
+  template <typename T>
+  operator T () const;   // { dg-error "T = Foo" "" }
+};
+
+Foo Quux (Bar const &b)
+{
+  return b; // { dg-error "ambiguous overload" "" }
+}
+
+