diff options
author | mmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-01-28 19:28:01 +0000 |
---|---|---|
committer | mmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-01-28 19:28:01 +0000 |
commit | d9db88e121564148b221a34fab10908b13f1b294 (patch) | |
tree | cf01e7e1711bb0a24daf243f5df6daba7b5aa587 /gcc | |
parent | e0464104c4927c8cd7cb2bf07f157762120df8e0 (diff) | |
download | gcc-d9db88e121564148b221a34fab10908b13f1b294.tar.gz |
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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@110332 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-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 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/spec29.C | 13 |
6 files changed, 69 insertions, 46 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 741d3de0a0e..ad3be507d4e 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 bcbed7be4d2..b9abaa82ddc 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 2f33b096d4e..ed7dd5361c9 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 d3d8961cfd0..e02cca47dc0 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 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 2f2f8c67727..70b6deef740 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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 index 00000000000..4df00ee7d28 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/spec29.C @@ -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; +} |