diff options
author | Nathan Sidwell <nathan@codesourcery.com> | 2005-10-05 09:15:47 +0000 |
---|---|---|
committer | Nathan Sidwell <nathan@gcc.gnu.org> | 2005-10-05 09:15:47 +0000 |
commit | 48884537a3a1b1d8023046dceb6c5358138c1a89 (patch) | |
tree | e8b6e32abd9c1307b81f84ce281459c250722933 /gcc | |
parent | 410e268ccec9d2c227cc12f3d081557ce2096c65 (diff) | |
download | gcc-48884537a3a1b1d8023046dceb6c5358138c1a89.zip gcc-48884537a3a1b1d8023046dceb6c5358138c1a89.tar.gz gcc-48884537a3a1b1d8023046dceb6c5358138c1a89.tar.bz2 |
re PR c++/23513 (overload resolution fails to select a more specialized template)
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.
From-SVN: r104981
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/cp/call.c | 14 | ||||
-rw-r--r-- | gcc/cp/pt.c | 33 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/spec22.C | 21 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/spec26.C | 35 |
6 files changed, 85 insertions, 31 deletions
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 <nathan@codesourcery.com> + + 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 <pinskia@physics.uc.edu> 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 <nathan@codesourcery.com> + + PR c++/23513 + * g++.dg/template/spec22.C: Robustify test. + * g++.dg/template/spec26.C: New. + 2005-10-05 Uros Bizjak <uros@kss-loka.si> * 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 <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> class srp; +template <typename T> struct ptr { - template <typename T> - int operator+ (T) const; // { dg-error "T = int" "" } + template <typename U> ptr(const srp<U> &other); // { dg-error "ptr<T>::ptr" } }; - -int main () +template <typename T> struct srp { - Foo f; - - return f + 0; // { dg-error "ambiguous overload" "" } + template <typename U> operator ptr<U>(void) const; // { dg-error "srp<T>::operator" } +}; +ptr<int> parent_get() +{ + srp<int> 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 <nathan@codesourcery.com> + +// PR 23519 template specialization ordering (DR214) +// Origin: Maxim Yegorushkin <maxim.yegorushkin@gmail.com> + +struct A +{ + template<class T> int operator+(T&) { return 1;} +}; + +template<class T> struct B +{ + int operator-(A&) {return 2;} + template<typename R> int operator*(R&) {return 3;} +}; + +template <typename T, typename R> int operator-(B<T>, R&) {return 4;} +template<class T> int operator+(A&, B<T>&) { return 5;} +template <typename T> int operator*(T &, A&){return 6;} + +int main() +{ + A a; + B<A> b; + if ((a + b) != 5) + return 1; + + if ((b - a) != 2) + return 2; + + if ((b * a) != 6) + return 3; +} |