This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[C++ PATCH] Fix PR6620
- From: Kriang Lerdsuwanakij <lerdsuwa at users dot sourceforge dot net>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 15 May 2002 22:25:52 +0700
- Subject: [C++ PATCH] Fix PR6620
- Reply-to: lerdsuwa at users dot sourceforge dot net
Hi
The appended patch fixes a partial specialization bug involving
template parameter dependent expression. This has been reported
in GNATS as PR6620. The problem is when gcc is deciding
whether
template <int N> struct Add<HoldInt<N>, HoldInt<-N> >
or
template <int N, int M> struct Add<HoldInt<N>, HoldInt<M> >
is more specialized. Current gcc has 2 different bugs that cause
the partial ordering of the above templates to fail.
The case when PARM is M, and ARG is -N. In function unify(),
ARG is a template parameter dependent expression. So its TREE_TYPE is
NULL_TREE. Attempt to call same_type_p in this case produces a segfault.
On the other hand, when PARM is -N and ARG is M. The function
verify_class_unification think that M and -N are equivalent due to the
uses_template_parms function call. The code no longer applies now and
is simplified in the patch.
Bootstrapped and tested with no regressions. Ok to commit to the main
trunk?
--Kriang
2002-05-15 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
PR c++/6620
* pt.c (verify_class_unification): Don't check if PARM is template
parameter dependent. Simplify.
(unify) [TEMPLATE_PARM_INDEX]: Handle when ARG is a template
parameter dependent expression.
diff -cprN gcc-main-save/gcc/cp/pt.c gcc-main-new/gcc/cp/pt.c
*** gcc-main-save/gcc/cp/pt.c Fri May 10 22:36:23 2002
--- gcc-main-new/gcc/cp/pt.c Wed May 15 22:03:28 2002
*************** static int
*** 8307,8335 ****
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),
! tf_none, 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
--- 8307,8318 ----
verify_class_unification (targs, parms, args)
tree targs, parms, args;
{
! parms = tsubst (parms, add_outermost_template_args (args, targs),
! tf_none, NULL_TREE);
! if (parms == error_mark_node)
return 1;
! return !comp_template_args (parms, INNERMOST_TEMPLATE_ARGS (args));
}
/* PARM is a template class (perhaps with unbound template
*************** unify (tparms, targs, parm, arg, strict)
*** 8812,8819 ****
deduced from an array bound may be of any integral type.
The non-type parameter might use already deduced type parameters. */
tparm = tsubst (TREE_TYPE (parm), targs, 0, NULL_TREE);
! if (same_type_p (TREE_TYPE (arg), tparm))
! /* OK */;
else if ((strict & UNIFY_ALLOW_INTEGER)
&& (TREE_CODE (tparm) == INTEGER_TYPE
|| TREE_CODE (tparm) == BOOLEAN_TYPE))
--- 8795,8806 ----
deduced from an array bound may be of any integral type.
The non-type parameter might use already deduced type parameters. */
tparm = tsubst (TREE_TYPE (parm), targs, 0, NULL_TREE);
! if (!TREE_TYPE (arg))
! /* Template-parameter dependent expression. Just accept it for now.
! It will later be processed in convert_template_argument. */
! ;
! else if (same_type_p (TREE_TYPE (arg), tparm))
! /* OK */;
else if ((strict & UNIFY_ALLOW_INTEGER)
&& (TREE_CODE (tparm) == INTEGER_TYPE
|| TREE_CODE (tparm) == BOOLEAN_TYPE))
diff -cprN gcc-main-save/gcc/testsuite/g++.dg/template/partial1.C gcc-main-new/gcc/testsuite/g++.dg/template/partial1.C
*** gcc-main-save/gcc/testsuite/g++.dg/template/partial1.C Thu Jan 1 07:00:00 1970
--- gcc-main-new/gcc/testsuite/g++.dg/template/partial1.C Wed May 15 22:00:51 2002
***************
*** 0 ****
--- 1,36 ----
+ // { dg-do run }
+ // Origin: Jo Totland <jototland@hotmail.com>
+
+ // PR c++/6620
+ // Partial specialization involving expression of non-type template
+ // parameter causes ICE.
+
+ extern "C" void abort();
+
+ template <int N> struct HoldInt
+ {
+ };
+
+ template <class A, class B> struct Add
+ {
+ };
+
+ template <int N> struct Add<HoldInt<N>, HoldInt<-N> >
+ {
+ typedef int type;
+ int f() { return 0; }
+ };
+
+ template <int N, int M>
+ struct Add<HoldInt<N>, HoldInt<M> >
+ {
+ typedef HoldInt<N+M> type;
+ int f() { return 1; }
+ };
+
+ int main() {
+ Add<HoldInt<1>, HoldInt<-1> > a;
+ Add<HoldInt<1>, HoldInt<-2> > b;
+ if (a.f() != 0 || b.f() != 1)
+ abort();
+ }