OSDN Git Service

cp:
authornathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 8 Jul 2005 11:05:51 +0000 (11:05 +0000)
committernathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 8 Jul 2005 11:05:51 +0000 (11:05 +0000)
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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@101760 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/pt.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/template/unify8.C [new file with mode: 0644]
gcc/testsuite/g++.dg/template/unify9.C [new file with mode: 0644]

index 36a5e59..9019b67 100644 (file)
@@ -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.
index d27e523..7424e9d 100644 (file)
@@ -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
index 2a06854..8bfd32b 100644 (file)
@@ -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 (file)
index 0000000..9caf085
--- /dev/null
@@ -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 (file)
index 0000000..2439efb
--- /dev/null
@@ -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" }
+}