PR c++/25855
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 28 Jan 2006 19:28:01 +0000 (19:28 +0000)
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 28 Jan 2006 19:28:01 +0000 (19:28 +0000)
* class.c (resolve_address_of_overloaded_function): Adjust use of
return value from most_specialized_instantiation.
* pt.c (determine_specialization): Avoid multiple calls to
get_bindings.
(most_specialized_instantiation): When a tie occurs, set the
current presumed champion to the next template.  Return the
TREE_LIST node containing the template, rather than the template
itself.
(most_specialized): Remove.
* name-lookup.c (push_overloaded_decl): When duplicate_decls
indicates a failed redeclaration, report that to callers.
PR c++/25855
* g++.dg/template/spec29.C: New test.

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

gcc/cp/ChangeLog
gcc/cp/class.c
gcc/cp/name-lookup.c
gcc/cp/pt.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/template/spec29.C [new file with mode: 0644]

index 741d3de..ad3be50 100644 (file)
@@ -1,3 +1,18 @@
+2006-01-28  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c++/25855
+       * class.c (resolve_address_of_overloaded_function): Adjust use of
+       return value from most_specialized_instantiation.
+       * pt.c (determine_specialization): Avoid multiple calls to
+       get_bindings.
+       (most_specialized_instantiation): When a tie occurs, set the
+       current presumed champion to the next template.  Return the
+       TREE_LIST node containing the template, rather than the template
+       itself.
+       (most_specialized): Remove.
+       * name-lookup.c (push_overloaded_decl): When duplicate_decls
+       indicates a failed redeclaration, report that to callers.
+
 2006-01-26  Jason Merrill  <jason@redhat.com>
 
        PR c++/16021
index bcbed7b..b9abaa8 100644 (file)
@@ -5819,7 +5819,9 @@ resolve_address_of_overloaded_function (tree target_type,
          tree match = most_specialized_instantiation (matches);
 
          if (match != error_mark_node)
-           matches = tree_cons (match, NULL_TREE, NULL_TREE);
+           matches = tree_cons (TREE_PURPOSE (match), 
+                                NULL_TREE, 
+                                NULL_TREE);
        }
     }
 
index 2f33b09..ed7dd53 100644 (file)
@@ -1892,6 +1892,7 @@ push_overloaded_decl (tree decl, int flags, bool is_friend)
          for (tmp = old; tmp; tmp = OVL_NEXT (tmp))
            {
              tree fn = OVL_CURRENT (tmp);
+             tree dup;
 
              if (TREE_CODE (tmp) == OVERLOAD && OVL_USED (tmp)
                  && !(flags & PUSH_USING)
@@ -1901,8 +1902,11 @@ push_overloaded_decl (tree decl, int flags, bool is_friend)
                error ("%q#D conflicts with previous using declaration %q#D",
                       decl, fn);
 
-             if (duplicate_decls (decl, fn, is_friend) == fn)
-               POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, fn);
+             dup = duplicate_decls (decl, fn, is_friend);
+             /* If DECL was a redeclaration of FN -- even an invalid
+                one -- pass that information along to our caller.  */
+             if (dup == fn || dup == error_mark_node)
+               POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, dup);
            }
 
          /* We don't overload implicit built-ins.  duplicate_decls()
index d3d8961..e02cca4 100644 (file)
@@ -135,7 +135,6 @@ static tree tsubst_template_arg (tree, tree, tsubst_flags_t, tree);
 static tree tsubst_template_args (tree, tree, tsubst_flags_t, tree);
 static tree tsubst_template_parms (tree, tree, tsubst_flags_t);
 static void regenerate_decl_from_template (tree, tree);
-static tree most_specialized (tree, tree, tree);
 static tree most_specialized_class (tree, tree);
 static tree tsubst_aggr_type (tree, tree, tsubst_flags_t, tree, int);
 static tree tsubst_arg_types (tree, tree, tsubst_flags_t, tree);
@@ -1343,6 +1342,11 @@ determine_specialization (tree template_id,
   tree targs;
   tree explicit_targs;
   tree candidates = NULL_TREE;
+  /* A TREE_LIST of templates of which DECL may be a specialization.
+     The TREE_VALUE of each node is a TEMPLATE_DECL.  The
+     corresponding TREE_PURPOSE is the set of template arguments that,
+     when used to instantiate the template, would produce a function
+     with the signature of DECL.  */
   tree templates = NULL_TREE;
   int header_count;
   struct cp_binding_level *b;
@@ -1547,12 +1551,12 @@ determine_specialization (tree template_id,
         the EDG front-end has that behavior, and John Spicer claims
         that the committee simply forgot to delete the wording in
         [temp.expl.spec].  */
-     tree tmpl = most_specialized (templates, decl, explicit_targs);
-     if (tmpl && tmpl != error_mark_node)
-       {
-        targs = get_bindings (tmpl, decl, explicit_targs, /*check_ret=*/true);
-        templates = tree_cons (targs, tmpl, NULL_TREE);
-       }
+      tree tmpl = most_specialized_instantiation (templates);
+      if (tmpl != error_mark_node)
+       {
+         templates = tmpl;
+         TREE_CHAIN (templates) = NULL_TREE;
+       }
     }
 
   if (templates == NULL_TREE && candidates == NULL_TREE)
@@ -10826,25 +10830,26 @@ get_class_bindings (tree tparms, tree parms, tree args)
   return vec;
 }
 
-/* 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.  If there is no most specialized template,
-   error_mark_node is returned.  If there are no templates at all,
-   NULL_TREE is returned.  */
+/* TEMPLATES is a TREE_LIST.  Each TREE_VALUE is a TEMPLATE_DECL.
+   Return the TREE_LIST node with the most specialized template, if
+   any.  If there is no most specialized template, the error_mark_node
+   is returned.
+
+   Note that this function does not look at, or modify, the
+   TREE_PURPOSE or TREE_TYPE of any of the nodes.  Since the node
+   returned is one of the elements of INSTANTIATIONS, callers may
+   store information in the TREE_PURPOSE or TREE_TYPE of the nodes,
+   and retrieve it from the value returned.  */
 
 tree
-most_specialized_instantiation (tree instantiations)
+most_specialized_instantiation (tree templates)
 {
   tree fn, champ;
 
-  if (!instantiations)
-    return NULL_TREE;
-
   ++processing_template_decl;
 
-  champ = instantiations;
-  for (fn = TREE_CHAIN (instantiations); fn; fn = TREE_CHAIN (fn))
+  champ = templates;
+  for (fn = TREE_CHAIN (templates); fn; fn = TREE_CHAIN (fn))
     {
       int fate = 0;
 
@@ -10865,6 +10870,7 @@ most_specialized_instantiation (tree instantiations)
          /* Equally specialized, move to next function.  If there
             is no next function, nothing's most specialized.  */
          fn = TREE_CHAIN (fn);
+         champ = fn;
          if (!fn)
            break;
        }
@@ -10873,7 +10879,7 @@ most_specialized_instantiation (tree instantiations)
   if (champ)
     /* Now verify that champ is better than everything earlier in the
        instantiation list.  */
-    for (fn = instantiations; fn != champ; fn = TREE_CHAIN (fn))
+    for (fn = templates; fn != champ; fn = TREE_CHAIN (fn))
       if (get_bindings (TREE_VALUE (champ),
                        DECL_TEMPLATE_RESULT (TREE_VALUE (fn)),
                        NULL_TREE, /*check_ret=*/false)
@@ -10890,29 +10896,7 @@ most_specialized_instantiation (tree instantiations)
   if (!champ)
     return error_mark_node;
 
-  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.  */
-
-static tree
-most_specialized (tree fns, tree decl, tree 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, /*check_ret=*/true);
-      if (args)
-       candidates = tree_cons (NULL_TREE, candidate, candidates);
-    }
-
-  return most_specialized_instantiation (candidates);
+  return champ;
 }
 
 /* If DECL is a specialization of some template, return the most
index 2f2f8c6..70b6dee 100644 (file)
@@ -1,3 +1,8 @@
+2006-01-28  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c++/25855
+       * g++.dg/template/spec29.C: New test.
+
 2006-01-28  Kazu Hirata  <kazu@codesourcery.com>
 
        PR c/19606.
diff --git a/gcc/testsuite/g++.dg/template/spec29.C b/gcc/testsuite/g++.dg/template/spec29.C
new file mode 100644 (file)
index 0000000..4df00ee
--- /dev/null
@@ -0,0 +1,13 @@
+// PR c++/25855
+// { dg-do run }
+
+template <typename T>  int qCompare(const T *t1, const T *t2) { return 1; }
+template <typename T>  int qCompare(T *t1, T *t2) { return 2; }
+template <typename T1, typename T2> int qCompare(const T1 *t1, const T2 *t2) {
+  return 3; }
+template<> int qCompare(const char *t1, const char *t2) { return 4; }
+int main()
+{
+  if (qCompare("a", "b") != 4)
+    return 1;
+}