aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@codesourcery.com>2005-07-08 11:05:51 +0000
committerNathan Sidwell <nathan@gcc.gnu.org>2005-07-08 11:05:51 +0000
commitc510f071aa275888a868948f96d1de6f9aa59c3b (patch)
tree6dc8dcb1d6f6561680fe1e1bb402168e2088e03c
parent6a7b00ad6d2640c0660ee8f4a1fa9edc5812eb9f (diff)
downloadgcc-c510f071aa275888a868948f96d1de6f9aa59c3b.zip
gcc-c510f071aa275888a868948f96d1de6f9aa59c3b.tar.gz
gcc-c510f071aa275888a868948f96d1de6f9aa59c3b.tar.bz2
re PR c++/21799 (Spurious ambiguity with pointers to members)
cp: 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. testsuite: PR c++/21799 * g++.dg/template/unify8.C: New. * g++.dg/template/unify9.C: New. From-SVN: r101760
-rw-r--r--gcc/cp/ChangeLog8
-rw-r--r--gcc/cp/pt.c34
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/g++.dg/template/unify8.C20
-rw-r--r--gcc/testsuite/g++.dg/template/unify9.C17
5 files changed, 80 insertions, 5 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 36a5e59..9019b67 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,11 @@
+2005-07-08 Nathan Sidwell <nathan@codesourcery.com>
+
+ 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 <nathan@codesourcery.com>
* pt.c (type_unification_real): Remove allow_incomplete argument.
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index d27e523..7424e9d 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 2a068542..8bfd32b 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2005-07-08 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/21799
+ * g++.dg/template/unify8.C: New.
+ * g++.dg/template/unify9.C: New.
+
2005-07-08 Jakub Jelinek <jakub@redhat.com>
* 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 0000000..9caf085
--- /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 <nathan@codesourcery.com>
+
+// Origin:Wolfgang Bangerth <bangerth@dealii.org>
+// PR 21799: deduction of cvqualifiers on member functions was wrong
+
+template <class T> void f (T &, void (T::*)() );
+template <class T> 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 0000000..2439efb
--- /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 <nathan@codesourcery.com>
+
+// Origin:Wolfgang Bangerth <bangerth@dealii.org>
+// PR 21799: deduction of cvqualifiers on member functions was wrong
+
+template <class T> void f (T &, void (T::*)() );
+
+struct X {
+ void g() const {}
+};
+
+const X *x;
+
+int main () {
+ f (*x, &X::g); // { dg-error "no matching function" }
+}