aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>2000-12-07 07:17:09 +0000
committerKriang Lerdsuwanakij <lerdsuwa@gcc.gnu.org>2000-12-07 07:17:09 +0000
commit74601d7c09fba7d38715dc1adb1b24fdd98cf1f3 (patch)
tree42bc9043447773d2eac4ced16950fa0b3283cbb2
parent9ba2e1ef8028112b47eb48041ae387c60acea6b1 (diff)
downloadgcc-74601d7c09fba7d38715dc1adb1b24fdd98cf1f3.zip
gcc-74601d7c09fba7d38715dc1adb1b24fdd98cf1f3.tar.gz
gcc-74601d7c09fba7d38715dc1adb1b24fdd98cf1f3.tar.bz2
pt.c (verify_class_unification): New function.
* 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. From-SVN: r38102
-rw-r--r--gcc/cp/ChangeLog9
-rw-r--r--gcc/cp/pt.c110
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.old-deja/g++.oliva/partspec1.C6
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/partial4.C24
5 files changed, 124 insertions, 30 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 585e815..49c3d64 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 d975a7d..900ef3c 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;
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 36b7ef4..340a765 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2000-12-06 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * g++.old-deja/g++.oliva/partspec1.C: Remove XFAIL.
+ * g++.old-deja/g++.pt/partial4.C: New test.
+
2000-12-06 J. David Anglin <dave@hiauly1.hia.nrc.ca>
* gcc.c-torture/execute/ieee/hugeval.x: New.
diff --git a/gcc/testsuite/g++.old-deja/g++.oliva/partspec1.C b/gcc/testsuite/g++.old-deja/g++.oliva/partspec1.C
index 00942c0..067a635 100644
--- a/gcc/testsuite/g++.old-deja/g++.oliva/partspec1.C
+++ b/gcc/testsuite/g++.old-deja/g++.oliva/partspec1.C
@@ -10,11 +10,11 @@ template <typename A, int* P> struct X;
int a;
template <typename A>
-struct X<A,&a> {}; // gets bogus error - candidate - XFAIL *-*-*
+struct X<A,&a> {};
int b;
template <typename A>
-struct X<A,&b> {}; // gets bogus error - candidate - XFAIL *-*-*
+struct X<A,&b> {};
-X<int,&a> x; // gets bogus error - ambiguous - XFAIL *-*-*
+X<int,&a> x;
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/partial4.C b/gcc/testsuite/g++.old-deja/g++.pt/partial4.C
new file mode 100644
index 0000000..3956a0c
--- /dev/null
+++ b/gcc/testsuite/g++.old-deja/g++.pt/partial4.C
@@ -0,0 +1,24 @@
+// Build don't link:
+// Origin: Gabriel Dos Reis <Gabriel.Dos-Reis@cmla.ens-cachan.fr>
+
+// Bug 29. We failed to verify that template argument deduction
+// produces a valid result in nondeduce context.
+
+template<class T> struct Y { typedef T X; };
+
+template<class T, class U> struct Base {};
+
+template<class T> struct Base<T, typename T::X> {};
+
+template<class T> struct Base<typename T::X, T> {};
+
+template<class T, class U> struct Derived : Base <T, U> {};
+
+struct A {};
+
+template<class T> struct Derived<A, T> : Base< Y<T>, Y<T> > {};
+
+int main()
+{
+ Derived<A, int> d;
+}