diff options
author | Mark Mitchell <mark@codesourcery.com> | 2006-01-28 19:28:01 +0000 |
---|---|---|
committer | Mark Mitchell <mmitchel@gcc.gnu.org> | 2006-01-28 19:28:01 +0000 |
commit | 7ca383e6791272a9f99390b5981ae476a9b490f1 (patch) | |
tree | cf01e7e1711bb0a24daf243f5df6daba7b5aa587 /gcc/cp | |
parent | e94aab95ee93fd7c5f31ad1ec5aecdb9c3c97453 (diff) | |
download | gcc-7ca383e6791272a9f99390b5981ae476a9b490f1.zip gcc-7ca383e6791272a9f99390b5981ae476a9b490f1.tar.gz gcc-7ca383e6791272a9f99390b5981ae476a9b490f1.tar.bz2 |
re PR c++/25855 (template specialisation not always found (partial ordering))
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.
PR c++/25855
* g++.dg/template/spec29.C: New test.
From-SVN: r110332
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/ChangeLog | 15 | ||||
-rw-r--r-- | gcc/cp/class.c | 4 | ||||
-rw-r--r-- | gcc/cp/name-lookup.c | 8 | ||||
-rw-r--r-- | gcc/cp/pt.c | 70 |
4 files changed, 51 insertions, 46 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 741d3de..ad3be50 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -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 diff --git a/gcc/cp/class.c b/gcc/cp/class.c index bcbed7b..b9abaa8 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -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); } } diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index 2f33b09..ed7dd53 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -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() diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index d3d8961..e02cca4 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -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 |