From 3d32803dcfd52c9bb32d21fa47442a4f8da00106 Mon Sep 17 00:00:00 2001 From: nathan Date: Wed, 5 Oct 2005 09:15:47 +0000 Subject: [PATCH] cp: PR c++/23513 * call.c (joust): Adjust length count to more_specialized_fn. * pt.c (more_specialized_fn): Cope with non-static member vs non-member. testsuite: PR c++/23513 * g++.dg/template/spec22.C: Robustify test. * g++.dg/template/spec26.C: New. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@104981 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/cp/ChangeLog | 7 +++++++ gcc/cp/call.c | 14 ++++---------- gcc/cp/pt.c | 33 ++++++++++++++++++++++---------- gcc/testsuite/ChangeLog | 6 ++++++ gcc/testsuite/g++.dg/template/spec22.C | 21 ++++++++++---------- gcc/testsuite/g++.dg/template/spec26.C | 35 ++++++++++++++++++++++++++++++++++ 6 files changed, 85 insertions(+), 31 deletions(-) create mode 100644 gcc/testsuite/g++.dg/template/spec26.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index c42ec9e..c79a926 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2005-10-05 Nathan Sidwell + + PR c++/23513 + * call.c (joust): Adjust length count to more_specialized_fn. + * pt.c (more_specialized_fn): Cope with non-static member vs + non-member. + 2005-10-04 Andrew Pinski PR middle-end/23125 diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 3507e582..2843b16 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -6133,17 +6133,11 @@ joust (struct z_candidate *cand1, struct z_candidate *cand2, bool warn) winner = more_specialized_fn (TI_TEMPLATE (cand1->template_decl), TI_TEMPLATE (cand2->template_decl), - /* Tell the deduction code how many real function arguments - we saw, not counting the implicit 'this' argument. But, - add_function_candidate() suppresses the "this" argument - for constructors. - - [temp.func.order]: The presence of unused ellipsis and default + /* [temp.func.order]: The presence of unused ellipsis and default arguments has no effect on the partial ordering of function - templates. */ - cand1->num_convs - - (DECL_NONSTATIC_MEMBER_FUNCTION_P (cand1->fn) - - DECL_CONSTRUCTOR_P (cand1->fn))); + templates. add_function_candidate() will not have + counted the "this" argument for constructors. */ + cand1->num_convs + DECL_CONSTRUCTOR_P (cand1->fn)); if (winner) return winner; } diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 82d569b..317d17f 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -10491,17 +10491,30 @@ more_specialized_fn (tree pat1, tree pat2, int len) tree args2 = TYPE_ARG_TYPES (TREE_TYPE (decl2)); 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. */ + + /* Remove the this parameter from non-static member functions. If + one is a non-static member function and the other is not a static + member function, remove the first parameter from that function + also. This situation occurs for operator functions where we + locate both a member function (with this pointer) and non-member + operator (with explicit first operand). */ if (DECL_NONSTATIC_MEMBER_FUNCTION_P (decl1)) - args1 = TREE_CHAIN (args1); - if (DECL_NONSTATIC_MEMBER_FUNCTION_P (decl2)) - args2 = TREE_CHAIN (args2); - + { + len--; /* LEN is the number of significant arguments for DECL1 */ + args1 = TREE_CHAIN (args1); + if (!DECL_STATIC_FUNCTION_P (decl2)) + args2 = TREE_CHAIN (args2); + } + else if (DECL_NONSTATIC_MEMBER_FUNCTION_P (decl2)) + { + args2 = TREE_CHAIN (args2); + if (!DECL_STATIC_FUNCTION_P (decl1)) + { + len--; + args1 = TREE_CHAIN (args1); + } + } + /* If only one is a conversion operator, they are unordered. */ if (DECL_CONV_FN_P (decl1) != DECL_CONV_FN_P (decl2)) return 0; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 62ca00c..6790aa8 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2005-10-05 Nathan Sidwell + + PR c++/23513 + * g++.dg/template/spec22.C: Robustify test. + * g++.dg/template/spec26.C: New. + 2005-10-05 Uros Bizjak * gcc.dg/vect/vect-shift-1.c: Include tree-vect.h header. Check diff --git a/gcc/testsuite/g++.dg/template/spec22.C b/gcc/testsuite/g++.dg/template/spec22.C index e2d439c..a091b0f 100644 --- a/gcc/testsuite/g++.dg/template/spec22.C +++ b/gcc/testsuite/g++.dg/template/spec22.C @@ -5,18 +5,17 @@ // Origin: Andrew Pinski // Nathan Sidwell -template -int operator+ (T const &, int); // { dg-error "T = Foo" "" } - -struct Foo +template class srp; +template struct ptr { - template - int operator+ (T) const; // { dg-error "T = int" "" } + template ptr(const srp &other); // { dg-error "ptr::ptr" } }; - -int main () +template struct srp { - Foo f; - - return f + 0; // { dg-error "ambiguous overload" "" } + template operator ptr(void) const; // { dg-error "srp::operator" } +}; +ptr parent_get() +{ + srp parent; + return parent; // { dg-error "is ambiguous" } } diff --git a/gcc/testsuite/g++.dg/template/spec26.C b/gcc/testsuite/g++.dg/template/spec26.C new file mode 100644 index 0000000..3d18707 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/spec26.C @@ -0,0 +1,35 @@ +// dg-do run +// Copyright (C) 2005 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 16 Sep 2005 + +// PR 23519 template specialization ordering (DR214) +// Origin: Maxim Yegorushkin + +struct A +{ + template int operator+(T&) { return 1;} +}; + +template struct B +{ + int operator-(A&) {return 2;} + template int operator*(R&) {return 3;} +}; + +template int operator-(B, R&) {return 4;} +template int operator+(A&, B&) { return 5;} +template int operator*(T &, A&){return 6;} + +int main() +{ + A a; + B b; + if ((a + b) != 5) + return 1; + + if ((b - a) != 2) + return 2; + + if ((b * a) != 6) + return 3; +} -- 2.7.4