diff options
author | lerdsuwa <lerdsuwa@138bc75d-0d04-0410-961f-82ee72b054a4> | 2000-12-07 07:17:09 +0000 |
---|---|---|
committer | lerdsuwa <lerdsuwa@138bc75d-0d04-0410-961f-82ee72b054a4> | 2000-12-07 07:17:09 +0000 |
commit | 25963226109e376cd4b5bccdd5d1dae9355ad47e (patch) | |
tree | 42bc9043447773d2eac4ced16950fa0b3283cbb2 /gcc/cp | |
parent | 41a9aa85e255a4f2cf8d2dcab82a1a7a82429e0b (diff) | |
download | gcc-25963226109e376cd4b5bccdd5d1dae9355ad47e.tar.gz |
* pt.c (verify_class_unification): New function.
(get_class_bindings): Use it.
(try_class_unification): Tidy.
(unify): Handle when argument of a template-id is not
template parameter dependent.
(template_args_equal): Handle when TREE_CODE's do not match.
* g++.old-deja/g++.oliva/partspec1.C: Remove XFAIL.
* g++.old-deja/g++.pt/partial4.C: New test.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@38102 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/cp/pt.c | 110 |
2 files changed, 92 insertions, 27 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 585e8154a8f..49c3d64f856 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,12 @@ +2000-12-06 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> + + * pt.c (verify_class_unification): New function. + (get_class_bindings): Use it. + (try_class_unification): Tidy. + (unify): Handle when argument of a template-id is not + template parameter dependent. + (template_args_equal): Handle when TREE_CODE's do not match. + 2000-12-06 Alexandre Oliva <aoliva@redhat.com> * lang-specs.h (c++): When invoking the stand-alone preprocessor diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index d975a7d0a04..900ef3c6c62 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -157,6 +157,7 @@ static tree tsubst_call_declarator_parms PARAMS ((tree, tree, int, tree)); static tree get_template_base_recursive PARAMS ((tree, tree, tree, tree, tree, int)); static tree get_template_base PARAMS ((tree, tree, tree, tree)); +static int verify_class_unification PARAMS ((tree, tree, tree)); static tree try_class_unification PARAMS ((tree, tree, tree, tree)); static int coerce_template_template_parms PARAMS ((tree, tree, int, tree, tree)); @@ -3464,13 +3465,14 @@ template_args_equal (ot, nt) { if (nt == ot) return 1; - if (TREE_CODE (nt) != TREE_CODE (ot)) - return 0; + if (TREE_CODE (nt) == TREE_VEC) /* For member templates */ - return comp_template_args (ot, nt); - else if (TYPE_P (ot)) - return same_type_p (ot, nt); + return TREE_CODE (ot) == TREE_VEC && comp_template_args (ot, nt); + else if (TYPE_P (nt)) + return TYPE_P (ot) && same_type_p (ot, nt); + else if (TREE_CODE (ot) == TREE_VEC || TYPE_P (ot)) + return 0; else return (cp_tree_equal (ot, nt) > 0); } @@ -8039,6 +8041,52 @@ try_one_overload (tparms, orig_targs, targs, parm, arg, strict, return 1; } +/* Verify that nondeduce template argument agrees with the type + obtained from argument deduction. Return nonzero if the + verification fails. + + For example: + + struct A { typedef int X; }; + template <class T, class U> struct C {}; + template <class T> struct C<T, typename T::X> {}; + + Then with the instantiation `C<A, int>', we can deduce that + `T' is `A' but unify () does not check whether `typename T::X' + is `int'. This function ensure that they agree. + + TARGS, PARMS are the same as the arguments of unify. + ARGS contains template arguments from all levels. */ + +static int +verify_class_unification (targs, parms, args) + tree targs, parms, args; +{ + int i; + int nparms = TREE_VEC_LENGTH (parms); + tree new_parms = tsubst (parms, add_outermost_template_args (args, targs), + /*complain=*/0, NULL_TREE); + if (new_parms == error_mark_node) + return 1; + + args = INNERMOST_TEMPLATE_ARGS (args); + + for (i = 0; i < nparms; i++) + { + tree parm = TREE_VEC_ELT (new_parms, i); + tree arg = TREE_VEC_ELT (args, i); + + /* In case we are deducing from a function argument of a function + templates, some parameters may not be deduced yet. So we + make sure that only fully substituted elements of PARM are + compared below. */ + + if (!uses_template_parms (parm) && !template_args_equal (parm, arg)) + return 1; + } + return 0; +} + /* PARM is a template class (perhaps with unbound template parameters). ARG is a fully instantiated type. If ARG can be bound to PARM, return ARG, otherwise return NULL_TREE. TPARMS and @@ -8051,7 +8099,6 @@ try_class_unification (tparms, targs, parm, arg) tree parm; tree arg; { - int i; tree copy_of_targs; if (!CLASSTYPE_TEMPLATE_INFO (arg) @@ -8089,14 +8136,13 @@ try_class_unification (tparms, targs, parm, arg) with S<I, I, I>. If we kept the already deduced knowledge, we would reject the possibility I=1. */ copy_of_targs = make_tree_vec (TREE_VEC_LENGTH (targs)); - i = unify (tparms, copy_of_targs, CLASSTYPE_TI_ARGS (parm), - CLASSTYPE_TI_ARGS (arg), UNIFY_ALLOW_NONE); /* If unification failed, we're done. */ - if (i != 0) + if (unify (tparms, copy_of_targs, CLASSTYPE_TI_ARGS (parm), + CLASSTYPE_TI_ARGS (arg), UNIFY_ALLOW_NONE)) return NULL_TREE; - else - return arg; + + return arg; } /* Subroutine of get_template_base. RVAL, if non-NULL, is a base we @@ -8699,25 +8745,33 @@ unify (tparms, targs, parm, arg, strict) default: if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (parm)))) - /* We're looking at an expression. This can happen with - something like: + { + + /* We're looking at an expression. This can happen with + something like: - template <int I> - void foo(S<I>, S<I + 2>); + template <int I> + void foo(S<I>, S<I + 2>); - This is a "nondeduced context": + This is a "nondeduced context": - [deduct.type] + [deduct.type] - The nondeduced contexts are: + The nondeduced contexts are: - --A type that is a template-id in which one or more of - the template-arguments is an expression that references - a template-parameter. + --A type that is a template-id in which one or more of + the template-arguments is an expression that references + a template-parameter. - In these cases, we assume deduction succeeded, but don't - actually infer any unifications. */ - return 0; + In these cases, we assume deduction succeeded, but don't + actually infer any unifications. */ + + if (!uses_template_parms (parm) + && !template_args_equal (parm, arg)) + return 1; + else + return 0; + } else sorry ("use of `%s' in template type unification", tree_code_name [(int) TREE_CODE (parm)]); @@ -8923,15 +8977,17 @@ get_class_bindings (tparms, parms, args) int i, ntparms = TREE_VEC_LENGTH (tparms); tree vec = make_tree_vec (ntparms); - args = INNERMOST_TEMPLATE_ARGS (args); - - if (unify (tparms, vec, parms, args, UNIFY_ALLOW_NONE)) + if (unify (tparms, vec, parms, INNERMOST_TEMPLATE_ARGS (args), + UNIFY_ALLOW_NONE)) return NULL_TREE; for (i = 0; i < ntparms; ++i) if (! TREE_VEC_ELT (vec, i)) return NULL_TREE; + if (verify_class_unification (vec, parms, args)) + return NULL_TREE; + return vec; } |