OSDN Git Service

* cp-tree.h (most_specialized_instantiation): New function.
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 9 Dec 1998 16:20:05 +0000 (16:20 +0000)
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 9 Dec 1998 16:20:05 +0000 (16:20 +0000)
(print_candidates): Likewise.
* class.c (validate_lhs): Remove.
(resolve_address_of_overloaded_function): New function, split out
and then substantially reworked, from ...
(instantiate_type): Use it.  Simplify.
* cvt.c (convert_to_reference): Complain when caller has indicated
that's the right thing to do.  Don't crash if instantiate_type
fails.
* pt.c: Substitute `parameters' for `paramters' throughout.
(print_candidates): Don't make it static.
(most_specialized_instantiation): Split out from ...
(most_specialized): Here.

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

gcc/cp/ChangeLog
gcc/cp/class.c
gcc/cp/cp-tree.h
gcc/cp/cvt.c
gcc/cp/pt.c
gcc/testsuite/g++.old-deja/g++.other/overload8.C [new file with mode: 0644]
gcc/testsuite/g++.old-deja/g++.pt/overload10.C [new file with mode: 0644]
gcc/testsuite/g++.old-deja/g++.pt/overload9.C [new file with mode: 0644]

index bc6665d..cf09c64 100644 (file)
@@ -1,3 +1,19 @@
+1998-12-09  Mark Mitchell  <mark@markmitchell.com>
+
+       * cp-tree.h (most_specialized_instantiation): New function.
+       (print_candidates): Likewise.
+       * class.c (validate_lhs): Remove.
+       (resolve_address_of_overloaded_function): New function, split out
+       and then substantially reworked, from ...
+       (instantiate_type): Use it.  Simplify.
+       * cvt.c (convert_to_reference): Complain when caller has indicated
+       that's the right thing to do.  Don't crash if instantiate_type
+       fails.
+       * pt.c: Substitute `parameters' for `paramters' throughout.
+       (print_candidates): Don't make it static.
+       (most_specialized_instantiation): Split out from ...
+       (most_specialized): Here.
+
 Wed Dec  9 15:33:01 1998  Dave Brolley  <brolley@cygnus.com>
 
        * lex.c (lang_init_options): Initialize cpplib.
index 8cd1c82..806ba62 100644 (file)
@@ -4971,27 +4971,245 @@ pop_lang_context ()
 \f
 /* Type instantiation routines.  */
 
+/* Given an OVERLOAD and a TARGET_TYPE, return the function that
+   matches the TARGET_TYPE.  If there is no satisfactory match, return
+   error_mark_node, and issue an error message if COMPLAIN is
+   non-zero.  If TEMPLATE_ONLY, the name of the overloaded function
+   was a template-id, and EXPLICIT_TARGS are the explicitly provided
+   template arguments.  */
+
 static tree
-validate_lhs (lhstype, complain)
-     tree lhstype;
+resolve_address_of_overloaded_function (target_type, 
+                                       overload,
+                                       complain, 
+                                       template_only,
+                                       explicit_targs)
+     tree target_type;
+     tree overload;
      int complain;
+     int template_only;
+     tree explicit_targs;
 {
-  if (TYPE_PTRMEMFUNC_P (lhstype))
-    lhstype = TYPE_PTRMEMFUNC_FN_TYPE (lhstype);
+  /* Here's what the standard says:
+     
+       [over.over]
+
+       If the name is a function template, template argument deduction
+       is done, and if the argument deduction succeeds, the deduced
+       arguments are used to generate a single template function, which
+       is added to the set of overloaded functions considered.
+
+       Non-member functions and static member functions match targets of
+       type "pointer-to-function" or "reference-to-function."  Nonstatic
+       member functions match targets of type "pointer-to-member
+       function;" the function type of the pointer to member is used to
+       select the member function from the set of overloaded member
+       functions.  If a nonstatic member function is selected, the
+       reference to the overloaded function name is required to have the
+       form of a pointer to member as described in 5.3.1.
+
+       If more than one function is selected, any template functions in
+       the set are eliminated if the set also contains a non-template
+       function, and any given template function is eliminated if the
+       set contains a second template function that is more specialized
+       than the first according to the partial ordering rules 14.5.5.2.
+       After such eliminations, if any, there shall remain exactly one
+       selected function.  */
+
+  int is_ptrmem = 0;
+  int is_reference = 0;
+  /* We store the matches in a TREE_LIST rooted here.  The functions
+     are the TREE_PURPOSE, not the TREE_VALUE, in this list, for easy
+     interoperability with most_specialized_instantiation.  */
+  tree matches = NULL_TREE;
+
+  /* If the TARGET_TYPE is a pointer-to-a-method, we convert it to
+     proper pointer-to-member type here.  */
+  if (TREE_CODE (target_type) == POINTER_TYPE
+      && TREE_CODE (TREE_TYPE (target_type)) == METHOD_TYPE)
+    target_type = build_ptrmemfunc_type (target_type);
+
+  /* Check that the TARGET_TYPE is reasonable.  */
+  if (TYPE_PTRFN_P (target_type))
+    /* This is OK.  */
+    ;
+  else if (TYPE_PTRMEMFUNC_P (target_type))
+    /* This is OK, too.  */
+    is_ptrmem = 1;
+  else if (TREE_CODE (target_type) == FUNCTION_TYPE)
+    {
+      /* This is OK, too.  This comes from a conversion to reference
+        type.  */
+      target_type = build_reference_type (target_type);
+      is_reference = 1;
+    }
+  else 
+    {
+      if (complain)
+       cp_error("cannot resolve overloaded function `%D' based on conversion to type `%T'", 
+                DECL_NAME (OVL_FUNCTION (overload)), target_type);
+      return error_mark_node;
+    }
+  
+  /* If we can find a non-template function that matches, we can just
+     use it.  There's no point in generating template instantiations
+     if we're just going to throw them out anyhow.  But, of course, we
+     can only do this when we don't *need* a template function.  */
+  if (!template_only)
+    {
+      tree fns;
+
+      for (fns = overload; fns; fns = OVL_CHAIN (fns))
+       {
+         tree fn = OVL_FUNCTION (fns);
+         tree fntype;
 
-  if (TREE_CODE (lhstype) == POINTER_TYPE)
+         if (TREE_CODE (fn) == TEMPLATE_DECL)
+           /* We're not looking for templates just yet.  */
+           continue;
+
+         if ((TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE)
+             != is_ptrmem)
+           /* We're looking for a non-static member, and this isn't
+              one, or vice versa.  */
+           continue;
+       
+         /* See if there's a match.  */
+         fntype = TREE_TYPE (fn);
+         if (is_ptrmem)
+           fntype = build_ptrmemfunc_type (build_pointer_type (fntype));
+         else if (!is_reference)
+           fntype = build_pointer_type (fntype);
+
+         if (can_convert_arg (target_type, fntype, fn))
+           matches = scratch_tree_cons (fn, NULL_TREE, matches);
+       }
+    }
+
+  /* Now, if we've already got a match (or matches), there's no need
+     to proceed to the template functions.  But, if we don't have a
+     match we need to look at them, too.  */
+  if (!matches) 
     {
-      if (TREE_CODE (TREE_TYPE (lhstype)) == FUNCTION_TYPE
-         || TREE_CODE (TREE_TYPE (lhstype)) == METHOD_TYPE)
-       lhstype = TREE_TYPE (lhstype);
+      tree target_fn_type;
+      tree target_arg_types;
+      tree fns;
+
+      if (is_ptrmem)
+       {
+         target_fn_type
+           = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (target_type));
+         target_arg_types = TREE_CHAIN (TYPE_ARG_TYPES (target_fn_type));
+       }
       else
        {
-         if (complain)
-           error ("invalid type combination for overload");
-         return error_mark_node;
+         target_fn_type = TREE_TYPE (target_type);
+         target_arg_types = TYPE_ARG_TYPES (target_fn_type);
+       }
+
+      for (fns = overload; fns; fns = OVL_CHAIN (fns))
+       {
+         tree fn = OVL_FUNCTION (fns);
+         tree fn_arg_types;
+         tree instantiation;
+         tree instantiation_type;
+         tree targs;
+
+         if (TREE_CODE (fn) != TEMPLATE_DECL)
+           /* We're only looking for templates.  */
+           continue;
+
+         if ((TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE)
+             != is_ptrmem)
+           /* We're looking for a non-static member, and this isn't
+              one, or vice versa.  */
+           continue;
+
+         /* We don't use the `this' argument to do argument deduction
+            since that would prevent us from converting a base class
+            pointer-to-member to a derived class pointer-to-member.  */
+         fn_arg_types = TYPE_ARG_TYPES (TREE_TYPE (fn));
+         if (is_ptrmem)
+           fn_arg_types = TREE_CHAIN (fn_arg_types);
+
+         /* Try to do argument deduction.  */
+         targs = make_scratch_vec (DECL_NTPARMS (fn));
+         if (type_unification (DECL_INNERMOST_TEMPLATE_PARMS (fn),
+                               targs,
+                               fn_arg_types,
+                               target_arg_types,
+                               explicit_targs,
+                               DEDUCE_EXACT,
+                               /*allow_incomplete=*/1) != 0)
+           /* Argument deduction failed.  */
+           continue;
+
+         /* Instantiate the template.  */
+         instantiation = instantiate_template (fn, targs);
+         if (instantiation == error_mark_node)
+           /* Instantiation failed.  */
+           continue;
+
+         /* See if there's a match.  */
+         instantiation_type = TREE_TYPE (instantiation);
+         if (is_ptrmem)
+           instantiation_type = 
+             build_ptrmemfunc_type (build_pointer_type (instantiation_type));
+         else if (!is_reference)
+           instantiation_type = build_pointer_type (instantiation_type);
+         if (can_convert_arg (target_type, instantiation_type, instantiation))
+           matches = scratch_tree_cons (instantiation, fn, matches);
+       }
+
+      /* Now, remove all but the most specialized of the matches.  */
+      if (matches)
+       {
+         tree match = most_specialized_instantiation (matches, 
+                                                      explicit_targs);
+
+         if (match != error_mark_node)
+           matches = scratch_tree_cons (match, NULL_TREE, NULL_TREE);
+       }
+    }
+
+  /* Now we should have exactly one function in MATCHES.  */
+  if (matches == NULL_TREE)
+    {
+      /* There were *no* matches.  */
+      if (complain)
+       {
+         cp_error ("cannot convert overloaded function `%D' to type `%#T'", 
+                   DECL_NAME (OVL_FUNCTION (overload)),
+                   target_type);
+         cp_error ("because no suitable overload exists");
+       }
+      return error_mark_node;
+    }
+  else if (TREE_CHAIN (matches))
+    {
+      /* There were too many matches.  */
+
+      if (complain)
+       {
+         tree match;
+
+         cp_error ("converting overloaded function `%D' to type `%#T' is ambiguous", 
+                   DECL_NAME (OVL_FUNCTION (overload)),
+                   target_type);
+
+         /* Since print_candidates expects the functions in the
+            TREE_VALUE slot, we flip them here.  */
+         for (match = matches; match; match = TREE_CHAIN (match))
+           TREE_VALUE (match) = TREE_PURPOSE (match);
+
+         print_candidates (matches);
        }
+      
+      return error_mark_node;
     }
-  return lhstype;
+
+  /* Good, exactly one match.  */
+  return TREE_PURPOSE (matches);
 }
 
 /* This function will instantiate the type of the expression given in
@@ -5009,9 +5227,6 @@ instantiate_type (lhstype, rhs, complain)
      tree lhstype, rhs;
      int complain;
 {
-  tree explicit_targs = NULL_TREE;
-  int template_only = 0;
-
   if (TREE_CODE (lhstype) == UNKNOWN_TYPE)
     {
       if (complain)
@@ -5109,141 +5324,20 @@ instantiate_type (lhstype, rhs, complain)
       /* Fall through.  */
 
     case TEMPLATE_ID_EXPR:
-      {
-       explicit_targs = TREE_OPERAND (rhs, 1);
-       template_only = 1;
-       rhs = TREE_OPERAND (rhs, 0);
-      }
-      /* fall through */
-      my_friendly_assert (TREE_CODE (rhs) == OVERLOAD, 980401);
+      return 
+       resolve_address_of_overloaded_function (lhstype,
+                                               TREE_OPERAND (rhs, 0),
+                                               complain,
+                                               /*template_only=*/1,
+                                               TREE_OPERAND (rhs, 1));
 
     case OVERLOAD:
-      {
-       tree elem, elems;
-
-       /* Check that the LHSTYPE and the RHS are reasonable.  */
-       lhstype = validate_lhs (lhstype, complain);
-       if (lhstype == error_mark_node)
-         return lhstype;
-
-       if (TREE_CODE (lhstype) != FUNCTION_TYPE
-           && TREE_CODE (lhstype) != METHOD_TYPE)
-         {
-           if (complain)
-             cp_error("cannot resolve overloaded function `%D' " 
-                      "based on non-function type `%T'", 
-                      DECL_NAME (OVL_FUNCTION (rhs)), lhstype);
-           return error_mark_node;
-         }
-       
-       /* Look for an exact match, by searching through the
-          overloaded functions.  */
-       if (template_only)
-         /* If we're processing a template-id, only a template
-            function can match, so we don't look through the
-            overloaded functions.  */
-         ;
-       else for (elems = rhs; elems; elems = OVL_CHAIN (elems))
-         {
-           elem = OVL_FUNCTION (elems);
-           if (TREE_CODE (elem) == FUNCTION_DECL
-               && same_type_p (lhstype, TREE_TYPE (elem)))
-             {
-               mark_used (elem);
-               return elem;
-             }
-         }
-
-       /* No overloaded function was an exact match.  See if we can
-          instantiate some template to match.  */
-       {
-         tree save_elem = 0;
-         elems = rhs;
-         if (TREE_CODE (elems) == TREE_LIST)
-           elems = TREE_VALUE (rhs);
-         for (; elems; elems = OVL_NEXT (elems))
-           if (TREE_CODE (elem = OVL_CURRENT (elems)) == TEMPLATE_DECL)
-             {
-               int n = DECL_NTPARMS (elem);
-               tree t = make_scratch_vec (n);
-               int i;
-               i = type_unification
-                 (DECL_INNERMOST_TEMPLATE_PARMS (elem), t,
-                  TYPE_ARG_TYPES (TREE_TYPE (elem)),
-                  TYPE_ARG_TYPES (lhstype), explicit_targs, DEDUCE_EXACT, 1);
-               if (i == 0)
-                 {
-                   if (save_elem)
-                     {
-                       cp_error ("ambiguous template instantiation converting to `%#T'", lhstype);
-                       return error_mark_node;
-                     }
-                   save_elem = instantiate_template (elem, t);
-                   /* Check the return type.  */
-                   if (!same_type_p (TREE_TYPE (lhstype),
-                                     TREE_TYPE (TREE_TYPE (save_elem))))
-                     save_elem = 0;
-                 }
-             }
-         if (save_elem)
-           {
-             mark_used (save_elem);
-             return save_elem;
-           }
-       }
-
-       /* There's no exact match, and no templates can be
-          instantiated to match.  The last thing we try is to see if
-          some ordinary overloaded function is close enough.  If
-          we're only looking for template functions, we don't do
-          this.  */
-       if (!template_only)
-         {
-           for (elems = rhs; elems; elems = OVL_NEXT (elems))
-             {
-               elem = OVL_CURRENT (elems);
-               if (TREE_CODE (elem) == FUNCTION_DECL
-                   && comp_target_types (lhstype, TREE_TYPE (elem), 1) > 0)
-                 break;
-             }
-           if (elems)
-             {
-               tree save_elem = elem;
-               for (elems = OVL_CHAIN (elems); elems; 
-                    elems = OVL_CHAIN (elems))
-                 {
-                   elem = OVL_FUNCTION (elems);
-                   if (TREE_CODE (elem) == FUNCTION_DECL
-                       && comp_target_types (lhstype, TREE_TYPE (elem), 0) >0)
-                     break;
-                 }
-               if (elems)
-                 {
-                   if (complain)
-                     {
-                       cp_error 
-                         ("cannot resolve overload to target type `%#T'",
-                          lhstype);
-                       cp_error_at ("  ambiguity between `%#D'", save_elem); 
-                       cp_error_at ("  and `%#D', at least", elem);
-                     }
-                   return error_mark_node;
-                 }
-               mark_used (save_elem);
-               return save_elem;
-             }
-         }
-
-       /* We failed to find a match.  */
-       if (complain)
-         {
-           cp_error ("cannot resolve overload to target type `%#T'", lhstype);
-           cp_error 
-             ("  because no suitable overload of function `%D' exists",
-              DECL_NAME (OVL_FUNCTION (rhs)));
-         }
-       return error_mark_node;
-      }
+      return 
+       resolve_address_of_overloaded_function (lhstype, 
+                                               rhs,
+                                               complain,
+                                               /*template_only=*/0,
+                                               /*explicit_targs=*/NULL_TREE);
 
     case TREE_LIST:
       {
@@ -5370,16 +5464,8 @@ instantiate_type (lhstype, rhs, complain)
       return rhs;
       
     case ADDR_EXPR:
-      if (TYPE_PTRMEMFUNC_P (lhstype))
-       lhstype = TYPE_PTRMEMFUNC_FN_TYPE (lhstype);
-      else if (TREE_CODE (lhstype) != POINTER_TYPE)
-       {
-         if (complain)
-           error ("type for resolving address of overloaded function must be pointer type");
-         return error_mark_node;
-       }
       {
-       tree fn = instantiate_type (TREE_TYPE (lhstype), TREE_OPERAND (rhs, 0), complain);
+       tree fn = instantiate_type (lhstype, TREE_OPERAND (rhs, 0), complain);
        if (fn == error_mark_node)
          return error_mark_node;
        mark_addressable (fn);
index a515d66..119efdd 100644 (file)
@@ -3030,6 +3030,8 @@ extern int is_specialization_of                 PROTO((tree, tree));
 extern int comp_template_args                   PROTO((tree, tree));
 extern void maybe_process_partial_specialization PROTO((tree));
 extern void maybe_check_template_type           PROTO((tree));
+extern tree most_specialized_instantiation      PROTO((tree, tree));
+extern void print_candidates                    PROTO((tree));
 
 extern int processing_specialization;
 extern int processing_explicit_instantiation;
index 17363b6..a5a91c1 100644 (file)
@@ -414,7 +414,11 @@ convert_to_reference (reftype, expr, convtype, flags, decl)
 
   if (TREE_CODE (type) == FUNCTION_TYPE && intype == unknown_type_node)
     {
-      expr = instantiate_type (type, expr, 0);
+      expr = instantiate_type (type, expr, 
+                              (flags & LOOKUP_COMPLAIN) != 0);
+      if (expr == error_mark_node)
+       return error_mark_node;
+
       intype = TREE_TYPE (expr);
     }
 
index 001b82a..50e44b5 100644 (file)
@@ -112,7 +112,6 @@ static void push_inline_template_parms_recursive PROTO((tree, int));
 static tree retrieve_specialization PROTO((tree, tree));
 static tree register_specialization PROTO((tree, tree, tree));
 static int unregister_specialization PROTO((tree, tree));
-static void print_candidates PROTO((tree));
 static tree reduce_template_parm_level PROTO((tree, tree, int));
 static tree build_template_decl PROTO((tree, tree));
 static int mark_template_parm PROTO((tree, void *));
@@ -883,7 +882,7 @@ unregister_specialization (spec, tmpl)
 
 /* Print the list of candidate FNS in an error message.  */
 
-static void
+void
 print_candidates (fns)
      tree fns;
 {
@@ -1996,7 +1995,7 @@ process_partial_specialization (decl)
                  /* We haven't yet initialized TPD2.  Do so now.  */
                  tpd2.arg_uses_template_parms 
                    =  (int*) alloca (sizeof (int) * nargs);
-                 /* The number of paramters here is the number in the
+                 /* The number of parameters here is the number in the
                     main template, which, as checked in the assertion
                     above, is NARGS.  */
                  tpd2.parms = (int*) alloca (sizeof (int) * nargs);
@@ -2004,7 +2003,7 @@ process_partial_specialization (decl)
                    TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (maintmpl));
                }
 
-             /* Mark the template paramters.  But this time, we're
+             /* Mark the template parameters.  But this time, we're
                 looking for the template parameters of the main
                 template, not in the specialization.  */
              tpd2.current_arg = i;
@@ -2024,7 +2023,7 @@ process_partial_specialization (decl)
                    if (tpd2.parms[j] != 0
                        && tpd.arg_uses_template_parms [j])
                      {
-                       cp_error ("type `%T' of template argument `%E' depends on template paramter(s)", 
+                       cp_error ("type `%T' of template argument `%E' depends on template parameter(s)", 
                                  type,
                                  arg);
                        break;
@@ -2106,7 +2105,7 @@ check_default_tmpl_args (decl, parms, is_primary, is_partial)
 
   if (current_class_type && TYPE_BEING_DEFINED (current_class_type))
     /* If we're inside a class definition, there's no need to
-       examine the paramters to the class itself.  On the one
+       examine the parameters to the class itself.  On the one
        hand, they will be checked when the class is defined, and,
        on the other, default arguments are legal in things like:
          template <class T = double>
@@ -8024,35 +8023,30 @@ get_class_bindings (tparms, parms, args)
   return vec;
 }
 
-/* Return the most specialized of the list of templates in FNS that can
-   produce an instantiation matching DECL, given the explicit template
-   arguments EXPLICIT_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 explicity
+   mentioned in a template-id.  If there is no most specialized
+   tempalte, error_mark_node is returned.  If there are no templates
+   at all, NULL_TREE is returned.  */
 
 tree
-most_specialized (fns, decl, explicit_args)
-     tree fns, decl, explicit_args;
+most_specialized_instantiation (instantiations, explicit_args)
+     tree instantiations;
+     tree explicit_args;
 {
-  tree candidates = NULL_TREE;
-  tree fn, champ, args;
+  tree fn, champ;
   int fate;
 
-  for (fn = fns; fn; fn = TREE_CHAIN (fn))
-    {
-      tree candidate = TREE_VALUE (fn);
-
-      args = get_bindings (candidate, decl, explicit_args);
-      if (args)
-       candidates = scratch_tree_cons (NULL_TREE, candidate, 
-                                       candidates);
-    }
-
-  if (!candidates)
+  if (!instantiations)
     return NULL_TREE;
 
-  champ = TREE_VALUE (candidates);
-  for (fn = TREE_CHAIN (candidates); fn; fn = TREE_CHAIN (fn))
+  champ = instantiations;
+  for (fn = TREE_CHAIN (instantiations); fn; fn = TREE_CHAIN (fn))
     {
-      fate = more_specialized (champ, TREE_VALUE (fn), explicit_args);
+      fate = more_specialized (TREE_VALUE (champ), 
+                              TREE_VALUE (fn), explicit_args);
       if (fate == 1)
        ;
       else
@@ -8063,18 +8057,43 @@ most_specialized (fns, decl, explicit_args)
              if (! fn)
                return error_mark_node;
            }
-         champ = TREE_VALUE (fn);
+         champ = fn;
        }
     }
 
-  for (fn = candidates; fn && TREE_VALUE (fn) != champ; fn = TREE_CHAIN (fn))
+  for (fn = instantiations; fn && fn != champ; fn = TREE_CHAIN (fn))
     {
-      fate = more_specialized (champ, TREE_VALUE (fn), explicit_args);
+      fate = more_specialized (TREE_VALUE (champ), 
+                              TREE_VALUE (fn), explicit_args);
       if (fate != 1)
        return error_mark_node;
     }
 
-  return champ;
+  return TREE_PURPOSE (champ) ? TREE_PURPOSE (champ) : TREE_VALUE (champ);
+}
+
+/* Return the most specialized of the list of templates in FNS that can
+   produce an instantiation matching DECL, given the explicit template
+   arguments EXPLICIT_ARGS.  */
+
+tree
+most_specialized (fns, decl, explicit_args)
+     tree fns, decl, explicit_args;
+{
+  tree candidates = NULL_TREE;
+  tree fn, args;
+
+  for (fn = fns; fn; fn = TREE_CHAIN (fn))
+    {
+      tree candidate = TREE_VALUE (fn);
+
+      args = get_bindings (candidate, decl, explicit_args);
+      if (args)
+       candidates = scratch_tree_cons (NULL_TREE, candidate, 
+                                       candidates);
+    }
+
+  return most_specialized_instantiation (candidates, explicit_args);
 }
 
 /* If DECL is a specialization of some template, return the most
diff --git a/gcc/testsuite/g++.old-deja/g++.other/overload8.C b/gcc/testsuite/g++.old-deja/g++.other/overload8.C
new file mode 100644 (file)
index 0000000..d2c1483
--- /dev/null
@@ -0,0 +1,22 @@
+class a {
+public:
+  int f()        { return 0; }
+  int f() const  { return 1; }
+};
+
+class b : public a {
+};
+
+int main() 
+{
+  int (b::* ptr1)()       = &b::f; 
+  int (b::* ptr2)() const = &b::f; 
+  
+  b ao;
+  
+  if ((ao.*ptr1)() != 0)
+    return 1;
+  if ((ao.*ptr2)() != 1)
+    return 1;
+}
+
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/overload10.C b/gcc/testsuite/g++.old-deja/g++.pt/overload10.C
new file mode 100644 (file)
index 0000000..19dd174
--- /dev/null
@@ -0,0 +1,16 @@
+struct B {
+  int f(int) { return 1; }
+};
+
+struct D {
+  template <class T>
+  int f(T) { return 0; }
+};
+
+int main()
+{
+  int (D::*g)(int) = &D::f;
+  
+  D d;
+  return (d.*g)(0);
+}
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/overload9.C b/gcc/testsuite/g++.old-deja/g++.pt/overload9.C
new file mode 100644 (file)
index 0000000..bd9eeb1
--- /dev/null
@@ -0,0 +1,21 @@
+template <class T>
+int f(T)
+{
+  return 1;
+}
+
+
+template <class T>
+int f(T*)
+{
+  return 0;
+}
+
+
+int main()
+{
+  int (*h)(int*) = &f;
+  int (&k)(int*) = f;
+
+  return (*h)(0) || (*k)(0);
+}