aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@codesourcery.com>2005-10-05 09:15:47 +0000
committerNathan Sidwell <nathan@gcc.gnu.org>2005-10-05 09:15:47 +0000
commit48884537a3a1b1d8023046dceb6c5358138c1a89 (patch)
treee8b6e32abd9c1307b81f84ce281459c250722933 /gcc
parent410e268ccec9d2c227cc12f3d081557ce2096c65 (diff)
downloadgcc-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/ChangeLog7
-rw-r--r--gcc/cp/call.c14
-rw-r--r--gcc/cp/pt.c33
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/g++.dg/template/spec22.C21
-rw-r--r--gcc/testsuite/g++.dg/template/spec26.C35
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;
+}