OSDN Git Service

In partial ordering for a call, ignore parms for which we don't have
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 22 Dec 2000 14:47:23 +0000 (14:47 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 22 Dec 2000 14:47:23 +0000 (14:47 +0000)
        a real argument.
        * call.c (joust): Pass len to more_specialized.
        (add_template_candidate_real): Strip 'this', pass len.
        * pt.c (more_specialized): Pass len down.  Lose explicit_args parm.
        (get_bindings_order): New fn.  Pass len down.
        (get_bindings_real): Strip 'this', pass len.
        (fn_type_unification): Likewise.
        (type_unification_real): Succeed after checking 'len' args.
        (most_specialized_instantiation): Lose explicit_args parm.
        * class.c (resolve_address_of_overloaded_function): Strip 'this',
        pass len.

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

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/class.c
gcc/cp/pt.c
gcc/testsuite/g++.old-deja/g++.pt/partial5.C [new file with mode: 0644]

index 0dd5b81..8da2de1 100644 (file)
@@ -1,4 +1,19 @@
-2000-12-20  Jason Merrill  <jason@redhat.com>
+2000-12-22  Jason Merrill  <jason@redhat.com>
+
+       In partial ordering for a call, ignore parms for which we don't have
+       a real argument.
+       * call.c (joust): Pass len to more_specialized.
+       (add_template_candidate_real): Strip 'this', pass len.
+       * pt.c (more_specialized): Pass len down.  Lose explicit_args parm.
+       (get_bindings_order): New fn.  Pass len down.
+       (get_bindings_real): Strip 'this', pass len.
+       (fn_type_unification): Likewise.
+       (type_unification_real): Succeed after checking 'len' args.
+       (most_specialized_instantiation): Lose explicit_args parm.
+       * class.c (resolve_address_of_overloaded_function): Strip 'this', 
+       pass len.
+
+2000-12-21  Jason Merrill  <jason@redhat.com>
 
        * pt.c (tsubst_decl): A FUNCTION_DECL has DECL_RESULT, not
        DECL_TEMPLATE_RESULT.
index e7de1ba..07d7268 100644 (file)
@@ -2147,26 +2147,24 @@ add_template_candidate_real (candidates, tmpl, ctype, explicit_targs,
 {
   int ntparms = DECL_NTPARMS (tmpl);
   tree targs = make_tree_vec (ntparms);
-  tree args_without_in_chrg;
+  tree args_without_in_chrg = arglist;
   struct z_candidate *cand;
   int i;
   tree fn;
 
-  /* TEMPLATE_DECLs do not have the in-charge parameter, nor the VTT
-     parameter.  So, skip it here before attempting to perform
-     argument deduction.  */
+  /* We don't do deduction on the in-charge parameter, the VTT
+     parameter or 'this'.  */
+  if (DECL_NONSTATIC_MEMBER_FUNCTION_P (tmpl))
+    args_without_in_chrg = TREE_CHAIN (args_without_in_chrg);
+
   if ((DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (tmpl)
        || DECL_BASE_CONSTRUCTOR_P (tmpl))
       && TYPE_USES_VIRTUAL_BASECLASSES (DECL_CONTEXT (tmpl)))
-    args_without_in_chrg = tree_cons (NULL_TREE, 
-                                     TREE_VALUE (arglist),
-                                     TREE_CHAIN (TREE_CHAIN (arglist)));
-  else
-    args_without_in_chrg = arglist;
+    args_without_in_chrg = TREE_CHAIN (args_without_in_chrg);
 
   i = fn_type_unification (tmpl, explicit_targs, targs,
                           args_without_in_chrg,
-                          return_type, strict);
+                          return_type, strict, -1);
 
   if (i != 0)
     return candidates;
@@ -5156,7 +5154,8 @@ joust (cand1, cand2, warn)
   else if (cand1->template && cand2->template)
     winner = more_specialized
       (TI_TEMPLATE (cand1->template), TI_TEMPLATE (cand2->template),
-       NULL_TREE);
+       /* Never do unification on the 'this' parameter.  */
+       TREE_VEC_LENGTH (cand1->convs) - !DECL_STATIC_FUNCTION_P (cand1->fn));
 
   /* or, if not that,
      the  context  is  an  initialization by user-defined conversion (see
index 60041c5..4e6babd 100644 (file)
@@ -5953,6 +5953,10 @@ resolve_address_of_overloaded_function (target_type,
        target_fn_type = TREE_TYPE (target_type);
       target_arg_types = TYPE_ARG_TYPES (target_fn_type);
       target_ret_type = TREE_TYPE (target_fn_type);
+
+      /* Never do unification on the 'this' parameter.  */
+      if (TREE_CODE (target_fn_type) == METHOD_TYPE)
+       target_arg_types = TREE_CHAIN (target_arg_types);
          
       for (fns = overload; fns; fns = OVL_CHAIN (fns))
        {
@@ -5975,7 +5979,7 @@ resolve_address_of_overloaded_function (target_type,
          targs = make_tree_vec (DECL_NTPARMS (fn));
          if (fn_type_unification (fn, explicit_targs, targs,
                                   target_arg_types, target_ret_type,
-                                  DEDUCE_EXACT) != 0)
+                                  DEDUCE_EXACT, -1) != 0)
            /* Argument deduction failed.  */
            continue;
 
@@ -5999,8 +6003,7 @@ resolve_address_of_overloaded_function (target_type,
       /* Now, remove all but the most specialized of the matches.  */
       if (matches)
        {
-         tree match = most_specialized_instantiation (matches, 
-                                                      explicit_targs);
+         tree match = most_specialized_instantiation (matches);
 
          if (match != error_mark_node)
            matches = tree_cons (match, NULL_TREE, NULL_TREE);
index 50e7ddf..0a260df 100644 (file)
@@ -113,13 +113,14 @@ static tree add_outermost_template_args PARAMS ((tree, tree));
 static void maybe_adjust_types_for_deduction PARAMS ((unification_kind_t, tree*,
                                                    tree*)); 
 static int  type_unification_real PARAMS ((tree, tree, tree, tree,
-                                        int, unification_kind_t, int));
+                                        int, unification_kind_t, int, int));
 static void note_template_header PARAMS ((int));
 static tree maybe_fold_nontype_arg PARAMS ((tree));
 static tree convert_nontype_argument PARAMS ((tree, tree));
 static tree convert_template_argument PARAMS ((tree, tree, tree, int,
                                              int , tree));
 static tree get_bindings_overload PARAMS ((tree, tree, tree));
+static tree get_bindings_order PARAMS ((tree, tree, int));
 static int for_each_template_parm PARAMS ((tree, tree_fn_t, void*));
 static tree build_template_parm_index PARAMS ((int, int, int, tree, tree));
 static int inline_needs_template_parms PARAMS ((tree));
@@ -134,7 +135,7 @@ static tree build_template_decl PARAMS ((tree, tree));
 static int mark_template_parm PARAMS ((tree, void *));
 static tree tsubst_friend_function PARAMS ((tree, tree));
 static tree tsubst_friend_class PARAMS ((tree, tree));
-static tree get_bindings_real PARAMS ((tree, tree, tree, int));
+static tree get_bindings_real PARAMS ((tree, tree, tree, int, int));
 static int template_decl_level PARAMS ((tree));
 static tree maybe_get_template_decl_from_type_decl PARAMS ((tree));
 static int check_cv_quals_for_unify PARAMS ((int, tree, tree));
@@ -7572,10 +7573,8 @@ overload_template_name (type)
    all the types, and 1 for complete failure.  An error message will be
    printed only for an incomplete match.
 
-   If FN is a conversion operator, RETURN_TYPE is the type desired as
-   the result of the conversion operator.
-
-   TPARMS is a vector of template parameters.
+   If FN is a conversion operator, or we are trying to produce a specific
+   specialization, RETURN_TYPE is the return type desired.
 
    The EXPLICIT_TARGS are explicit template arguments provided via a
    template-id.
@@ -7599,13 +7598,18 @@ overload_template_name (type)
      [temp.expl.spec], or when taking the address of a function
      template, as in [temp.deduct.funcaddr]. 
 
-   The other arguments are as for type_unification.  */
+   LEN is the number of parms to consider before returning success, or -1
+   for all.  This is used in partial ordering to avoid comparing parms for
+   which no actual argument was passed, since they are not considered in
+   overload resolution (and are explicitly excluded from consideration in
+   partial ordering in [temp.func.order]/6).  */
 
 int
 fn_type_unification (fn, explicit_targs, targs, args, return_type,
-                    strict)
+                    strict, len)
      tree fn, explicit_targs, targs, args, return_type;
      unification_kind_t strict;
+     int len;
 {
   tree parms;
   tree fntype;
@@ -7653,15 +7657,9 @@ fn_type_unification (fn, explicit_targs, targs, args, return_type,
     }
      
   parms = TYPE_ARG_TYPES (fntype);
-
-  if (DECL_CONV_FN_P (fn))
-    {
-      /* This is a template conversion operator.  Remove `this', since
-         we could be comparing conversions from different classes.  */
-      parms = TREE_CHAIN (parms);
-      args = TREE_CHAIN (args);
-      my_friendly_assert (return_type != NULL_TREE, 20000227);
-    }
+  /* Never do unification on the 'this' parameter.  */
+  if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn))
+    parms = TREE_CHAIN (parms);
   
   if (return_type)
     {
@@ -7676,7 +7674,7 @@ fn_type_unification (fn, explicit_targs, targs, args, return_type,
      event.  */
   result = type_unification_real (DECL_INNERMOST_TEMPLATE_PARMS (fn), 
                                  targs, parms, args, /*subr=*/0,
-                                 strict, /*allow_incomplete*/1);
+                                 strict, /*allow_incomplete*/1, len);
 
   if (result == 0) 
     /* All is well so far.  Now, check:
@@ -7769,7 +7767,7 @@ maybe_adjust_types_for_deduction (strict, parm, arg)
     *parm = TREE_TYPE (*parm);
 }
 
-/* Like type_unification.
+/* Most parms like fn_type_unification.
 
    If SUBR is 1, we're being called recursively (to unify the
    arguments of a function or method parameter of a function
@@ -7777,11 +7775,11 @@ maybe_adjust_types_for_deduction (strict, parm, arg)
 
 static int
 type_unification_real (tparms, targs, parms, args, subr,
-                      strict, allow_incomplete)
+                      strict, allow_incomplete, len)
      tree tparms, targs, parms, args;
      int subr;
      unification_kind_t strict;
-     int allow_incomplete;
+     int allow_incomplete, len;
 {
   tree parm, arg;
   int i;
@@ -7815,6 +7813,9 @@ type_unification_real (tparms, targs, parms, args, subr,
       my_friendly_abort (0);
     }
 
+  if (len == 0)
+    return 0;
+
   while (parms
         && parms != void_list_node
         && args
@@ -7887,6 +7888,10 @@ type_unification_real (tparms, targs, parms, args, subr,
 
       if (unify (tparms, targs, parm, arg, sub_strict))
         return 1;
+
+      /* Are we done with the interesting parms?  */
+      if (--len == 0)
+       return 0;
     }
   /* Fail if we've reached the end of the parm list, and more args
      are present, and the parm list isn't variadic.  */
@@ -8738,7 +8743,7 @@ unify (tparms, targs, parm, arg, strict)
        return 1;
       return type_unification_real (tparms, targs, TYPE_ARG_TYPES (parm),
                                    TYPE_ARG_TYPES (arg), 1, 
-                                   DEDUCE_EXACT, 0);
+                                   DEDUCE_EXACT, 0, -1);
 
     case OFFSET_TYPE:
       if (TREE_CODE (arg) != OFFSET_TYPE)
@@ -8854,27 +8859,30 @@ mark_decl_instantiated (result, extern_p)
     defer_fn (result);
 }
 
-/* Given two function templates PAT1 and PAT2, and explicit template
-   arguments EXPLICIT_ARGS return:
+/* Given two function templates PAT1 and PAT2, return:
 
    1 if PAT1 is more specialized than PAT2 as described in [temp.func.order].
    -1 if PAT2 is more specialized than PAT1.
-   0 if neither is more specialized.  */
+   0 if neither is more specialized.
+
+   LEN is passed through to fn_type_unification.  */
    
 int
-more_specialized (pat1, pat2, explicit_args)
-     tree pat1, pat2, explicit_args;
+more_specialized (pat1, pat2, len)
+     tree pat1, pat2;
+     int len;
 {
   tree targs;
   int winner = 0;
 
-  targs
-    = get_bindings_overload (pat1, DECL_TEMPLATE_RESULT (pat2), explicit_args);
+  if (len == 0)
+    return 0;
+
+  targs = get_bindings_order (pat1, DECL_TEMPLATE_RESULT (pat2), len);
   if (targs)
     --winner;
 
-  targs
-    = get_bindings_overload (pat2, DECL_TEMPLATE_RESULT (pat1), explicit_args);
+  targs = get_bindings_order (pat2, DECL_TEMPLATE_RESULT (pat1), len);
   if (targs)
     ++winner;
 
@@ -8911,12 +8919,12 @@ more_specialized_class (pat1, pat2)
    DECL from the function template FN, with the explicit template
    arguments EXPLICIT_ARGS.  If CHECK_RETTYPE is 1, the return type must
    also match.  Return NULL_TREE if no satisfactory arguments could be
-   found.  */
-
+   found.  LEN is passed through to fn_type_unification.  */
+   
 static tree
-get_bindings_real (fn, decl, explicit_args, check_rettype)
+get_bindings_real (fn, decl, explicit_args, check_rettype, len)
      tree fn, decl, explicit_args;
-     int check_rettype;
+     int check_rettype, len;
 {
   int ntparms = DECL_NTPARMS (fn);
   tree targs = make_tree_vec (ntparms);
@@ -8953,18 +8961,16 @@ get_bindings_real (fn, decl, explicit_args, check_rettype)
        return NULL_TREE;
     }
 
-  /* If FN is a static member function, adjust the type of DECL
-     appropriately.  */
   decl_arg_types = TYPE_ARG_TYPES (decl_type);
-  if (DECL_STATIC_FUNCTION_P (fn) 
-      && DECL_NONSTATIC_MEMBER_FUNCTION_P (decl))
+  /* Never do unification on the 'this' parameter.  */
+  if (DECL_NONSTATIC_MEMBER_FUNCTION_P (decl))
     decl_arg_types = TREE_CHAIN (decl_arg_types);
 
   i = fn_type_unification (fn, explicit_args, targs, 
                           decl_arg_types,
                           (check_rettype || DECL_CONV_FN_P (fn)
                            ? TREE_TYPE (decl_type) : NULL_TREE),
-                          DEDUCE_EXACT);
+                          DEDUCE_EXACT, len);
 
   if (i != 0)
     return NULL_TREE;
@@ -8978,16 +8984,27 @@ tree
 get_bindings (fn, decl, explicit_args)
      tree fn, decl, explicit_args;
 {
-  return get_bindings_real (fn, decl, explicit_args, 1);
+  return get_bindings_real (fn, decl, explicit_args, 1, -1);
 }
 
-/* But for more_specialized, we only care about the parameter types.  */
+/* But for resolve_overloaded_unification, we only care about the parameter
+   types.  */
 
 static tree
 get_bindings_overload (fn, decl, explicit_args)
      tree fn, decl, explicit_args;
 {
-  return get_bindings_real (fn, decl, explicit_args, 0);
+  return get_bindings_real (fn, decl, explicit_args, 0, -1);
+}
+
+/* And for more_specialized, we want to be able to stop partway.  */
+
+static tree
+get_bindings_order (fn, decl, len)
+     tree fn, decl;
+     int len;
+{
+  return get_bindings_real (fn, decl, NULL_TREE, 0, len);
 }
 
 /* Return the innermost template arguments that, when applied to a
@@ -9029,15 +9046,13 @@ get_class_bindings (tparms, parms, args)
 /* In INSTANTIATIONS is a list of <INSTANTIATION, TEMPLATE> pairs.
    Pick the most specialized template, and return the corresponding
    instantiation, or if there is no corresponding instantiation, the
-   template itself.  EXPLICIT_ARGS is any template arguments explicitly
-   mentioned in a template-id.  If there is no most specialized
-   template, error_mark_node is returned.  If there are no templates
-   at all, NULL_TREE is returned.  */
+   template itself.  If there is no most specialized template,
+   error_mark_node is returned.  If there are no templates at all,
+   NULL_TREE is returned.  */
 
 tree
-most_specialized_instantiation (instantiations, explicit_args)
+most_specialized_instantiation (instantiations)
      tree instantiations;
-     tree explicit_args;
 {
   tree fn, champ;
   int fate;
@@ -9048,8 +9063,7 @@ most_specialized_instantiation (instantiations, explicit_args)
   champ = instantiations;
   for (fn = TREE_CHAIN (instantiations); fn; fn = TREE_CHAIN (fn))
     {
-      fate = more_specialized (TREE_VALUE (champ), 
-                              TREE_VALUE (fn), explicit_args);
+      fate = more_specialized (TREE_VALUE (champ), TREE_VALUE (fn), -1);
       if (fate == 1)
        ;
       else
@@ -9066,8 +9080,7 @@ most_specialized_instantiation (instantiations, explicit_args)
 
   for (fn = instantiations; fn && fn != champ; fn = TREE_CHAIN (fn))
     {
-      fate = more_specialized (TREE_VALUE (champ), 
-                              TREE_VALUE (fn), explicit_args);
+      fate = more_specialized (TREE_VALUE (champ), TREE_VALUE (fn), -1);
       if (fate != 1)
        return error_mark_node;
     }
@@ -9095,7 +9108,7 @@ most_specialized (fns, decl, explicit_args)
        candidates = tree_cons (NULL_TREE, candidate, candidates);
     }
 
-  return most_specialized_instantiation (candidates, explicit_args);
+  return most_specialized_instantiation (candidates);
 }
 
 /* If DECL is a specialization of some template, return the most
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/partial5.C b/gcc/testsuite/g++.old-deja/g++.pt/partial5.C
new file mode 100644 (file)
index 0000000..fa5ebda
--- /dev/null
@@ -0,0 +1,18 @@
+// Test that partial ordering ignores defaulted parms and 'this'.
+
+struct A {
+  template<class T> int f(T) { return 1; }
+  template<class T> int f(T*, int=0) { return 0; }
+  template<class T> int g(T*) { return 0; }
+  template<class T> static int g(T, int=0) { return 1; }
+  template<class T> int h(T*) { return 0; }
+  template<class T> static int h(T, int=0) { return 1; }
+  template<class T> static int j(T*, short y=0) { return 0; }
+  template<class T> static int j(T, int=0) { return 1; }
+};
+
+int main(void) {
+  A a;
+  int *p;
+  return (a.f(p) || a.g(p) || a.h(p) || a.j(p));
+}