diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 36a5e59283e..9019b67f8c0 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +2005-07-08 Nathan Sidwell + + PR c++/21799 + * pt.c (type_unification_real): Add is_method argument. Use it + for this pointer unification. + (fn_type_unification): Adjust type_unification_real call. + (unify): Likewise. + 2005-07-07 Nathan Sidwell * pt.c (type_unification_real): Remove allow_incomplete argument. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index d27e5234009..7424e9dfc83 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -109,7 +109,7 @@ static tree add_outermost_template_args (tree, tree); static bool check_instantiated_args (tree, tree, tsubst_flags_t); static int maybe_adjust_types_for_deduction (unification_kind_t, tree*, tree*); static int type_unification_real (tree, tree, tree, tree, - int, unification_kind_t); + int, unification_kind_t, int); static void note_template_header (int); static tree convert_nontype_argument_function (tree, tree); static tree convert_nontype_argument (tree, tree); @@ -9177,7 +9177,7 @@ fn_type_unification (tree fn, event. */ result = type_unification_real (DECL_INNERMOST_TEMPLATE_PARMS (fn), targs, parms, args, /*subr=*/0, - strict); + strict, 0); if (result == 0) /* All is well so far. Now, check: @@ -9285,7 +9285,9 @@ maybe_adjust_types_for_deduction (unification_kind_t strict, If SUBR is 1, we're being called recursively (to unify the arguments of a function or method parameter of a function - template). */ + template). If IS_METHOD is true, XPARMS are the parms of a + member function, and special rules apply to cv qualification + deduction on the this parameter. */ static int type_unification_real (tree tparms, @@ -9293,7 +9295,8 @@ type_unification_real (tree tparms, tree xparms, tree xargs, int subr, - unification_kind_t strict) + unification_kind_t strict, + int is_method) { tree parm, arg; int i; @@ -9345,6 +9348,26 @@ type_unification_real (tree tparms, template args from other function args. */ continue; + if (is_method) + { + /* The cv qualifiers on the this pointer argument must match + exactly. We cannot deduce a T as const X against a const + member function for instance. */ + gcc_assert (TREE_CODE (parm) == POINTER_TYPE); + gcc_assert (TREE_CODE (arg) == POINTER_TYPE); + /* The restrict qualifier will be on the pointer. */ + if (cp_type_quals (parm) != cp_type_quals (arg)) + return 1; + parm = TREE_TYPE (parm); + arg = TREE_TYPE (arg); + if (cp_type_quals (parm) != cp_type_quals (arg)) + return 1; + + parm = TYPE_MAIN_VARIANT (parm); + arg = TYPE_MAIN_VARIANT (arg); + is_method = 0; + } + /* Conversions will be performed on a function argument that corresponds with a function parameter that contains only non-deducible template parameters and explicitly specified @@ -10249,7 +10272,8 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict) TREE_TYPE (arg), UNIFY_ALLOW_NONE)) return 1; return type_unification_real (tparms, targs, TYPE_ARG_TYPES (parm), - TYPE_ARG_TYPES (arg), 1, DEDUCE_EXACT); + TYPE_ARG_TYPES (arg), 1, DEDUCE_EXACT, + TREE_CODE (parm) == METHOD_TYPE); case OFFSET_TYPE: /* Unify a pointer to member with a pointer to member function, which diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 2a06854202c..8bfd32bbf0a 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2005-07-08 Nathan Sidwell + + PR c++/21799 + * g++.dg/template/unify8.C: New. + * g++.dg/template/unify9.C: New. + 2005-07-08 Jakub Jelinek * gfortran.fortran-torture/execute/entry_10.f90: New test. diff --git a/gcc/testsuite/g++.dg/template/unify8.C b/gcc/testsuite/g++.dg/template/unify8.C new file mode 100644 index 00000000000..9caf085f6b5 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/unify8.C @@ -0,0 +1,20 @@ +// { dg-do link } + +// Copyright (C) 2005 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 7 Jul 2005 + +// Origin:Wolfgang Bangerth +// PR 21799: deduction of cvqualifiers on member functions was wrong + +template void f (T &, void (T::*)() ); +template void f (const T &, void (T::*)() const) {} + +struct X { + void g() const {} +}; + +const X *x; + +int main () { + f (*x, &X::g); +} diff --git a/gcc/testsuite/g++.dg/template/unify9.C b/gcc/testsuite/g++.dg/template/unify9.C new file mode 100644 index 00000000000..2439efb761c --- /dev/null +++ b/gcc/testsuite/g++.dg/template/unify9.C @@ -0,0 +1,17 @@ +// Copyright (C) 2005 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 7 Jul 2005 + +// Origin:Wolfgang Bangerth +// PR 21799: deduction of cvqualifiers on member functions was wrong + +template void f (T &, void (T::*)() ); + +struct X { + void g() const {} +}; + +const X *x; + +int main () { + f (*x, &X::g); // { dg-error "no matching function" } +}