From ee307009db460dd07589e6bc2d31aad4c5a40426 Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Sun, 3 Apr 2005 12:33:02 +0000 Subject: [PATCH] re PR c++/20723 (ICE in more_specialized_fn, more than one user-defined conversion "srp" to "ptr") 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 | 7 +++++++ gcc/cp/pt.c | 10 ++++++++-- gcc/testsuite/ChangeLog | 6 ++++++ gcc/testsuite/g++.dg/template/spec22.C | 22 ++++++++++++++++++++++ gcc/testsuite/g++.dg/template/spec23.C | 25 +++++++++++++++++++++++++ 5 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/g++.dg/template/spec22.C create mode 100644 gcc/testsuite/g++.dg/template/spec23.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 4065f1746937..90a68926ecfb 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2005-04-03 Nathan Sidwell + + 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 * call.c (add_template_candidates_real): Remove length parameter diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index f92ce90a7f0f..e8b219080a5b 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -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++; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 612dcab58956..7191f88e7df7 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2005-04-03 Nathan Sidwell + + PR c++/20723 + * g++.dg/template/spec22.C: New. + * g++.dg/template/spec23.C: New. + 2005-04-03 Dale Ranta Francois-Xavier Coudert diff --git a/gcc/testsuite/g++.dg/template/spec22.C b/gcc/testsuite/g++.dg/template/spec22.C new file mode 100644 index 000000000000..e2d439c9252a --- /dev/null +++ b/gcc/testsuite/g++.dg/template/spec22.C @@ -0,0 +1,22 @@ +// Copyright (C) 2005 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 2 Apr 2005 + +// PR 20723 +// Origin: Andrew Pinski +// Nathan Sidwell + +template +int operator+ (T const &, int); // { dg-error "T = Foo" "" } + +struct Foo +{ + template + 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 index 000000000000..15618b10b515 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/spec23.C @@ -0,0 +1,25 @@ +// Copyright (C) 2005 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 2 Apr 2005 + +// PR 20723 +// Origin: Andrew Pinski +// Nathan Sidwell + +struct Foo +{ + template + Foo (const T &); // { dg-error "T = Bar" "" } +}; + +struct Bar +{ + template + operator T () const; // { dg-error "T = Foo" "" } +}; + +Foo Quux (Bar const &b) +{ + return b; // { dg-error "ambiguous overload" "" } +} + +