This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[C++ PATCH] Fix PR11154 regression (3.3.1 version)
- From: Kriang Lerdsuwanakij <lerdsuwa at users dot sourceforge dot net>
- To: <gcc-patches at gcc dot gnu dot org>
- Date: Sat, 12 Jul 2003 20:48:35 +0700 (ICT)
- Subject: [C++ PATCH] Fix PR11154 regression (3.3.1 version)
- Reply-to: <lerdsuwa at users dot sourceforge dot net>
Hi
This patch fixes the regression PR11154 which appears in both 3.3
and trunk. The problem is that 'verify_class_unification' expects
a complete set of template arguments for argument substitution.
However this is not true when this function is called by
'get_class_bindings' inside 'more_specialized_class'.
This patch fixes the bug by making 'get_class_bindings' always get
the full template arguments. The patch below is the version for 3.3.
The one for mainline differs slightly, with all K&R styled declarations
replaced ANSI ones and will be posted in a separate email.
Tested on i686-pc-linux-gnu. OK for 3.3 branch and trunk?
--Kriang
2003-07-12 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
PR c++/11154
* pt.c (more_specialized_class): Add full_args parameter.
(most_specialized_class): Adjust calls to more_specialized_class.
* cp-tree.h (more_specialized_class): Adjust declaration.
2003-07-12 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
PR c++/11154
* g++.dg/template/partial2.C: New test.
diff -cprN gcc-33-save/gcc/cp/cp-tree.h gcc-33-new/gcc/cp/cp-tree.h
*** gcc-33-save/gcc/cp/cp-tree.h Thu Jul 10 19:40:37 2003
--- gcc-33-new/gcc/cp/cp-tree.h Fri Jul 11 21:44:55 2003
*************** extern tree instantiate_decl PARAMS ((
*** 4081,4087 ****
extern tree get_bindings PARAMS ((tree, tree, tree));
extern int push_tinst_level PARAMS ((tree));
extern void pop_tinst_level PARAMS ((void));
! extern int more_specialized_class PARAMS ((tree, tree));
extern int is_member_template PARAMS ((tree));
extern int comp_template_parms PARAMS ((tree, tree));
extern int template_class_depth PARAMS ((tree));
--- 4081,4087 ----
extern tree get_bindings PARAMS ((tree, tree, tree));
extern int push_tinst_level PARAMS ((tree));
extern void pop_tinst_level PARAMS ((void));
! extern int more_specialized_class PARAMS ((tree, tree, tree));
extern int is_member_template PARAMS ((tree));
extern int comp_template_parms PARAMS ((tree, tree));
extern int template_class_depth PARAMS ((tree));
diff -cprN gcc-33-save/gcc/cp/pt.c gcc-33-new/gcc/cp/pt.c
*** gcc-33-save/gcc/cp/pt.c Sun Jul 6 17:19:35 2003
--- gcc-33-new/gcc/cp/pt.c Fri Jul 11 21:58:01 2003
*************** more_specialized (pat1, pat2, deduce, le
*** 9450,9471 ****
1 if PAT1 is more specialized than PAT2 as described in [temp.class.order].
-1 if PAT2 is more specialized than PAT1.
! 0 if neither is more specialized. */
int
! more_specialized_class (pat1, pat2)
! tree pat1, pat2;
{
tree targs;
int winner = 0;
targs = get_class_bindings (TREE_VALUE (pat1), TREE_PURPOSE (pat1),
! TREE_PURPOSE (pat2));
if (targs)
--winner;
targs = get_class_bindings (TREE_VALUE (pat2), TREE_PURPOSE (pat2),
! TREE_PURPOSE (pat1));
if (targs)
++winner;
--- 9450,9474 ----
1 if PAT1 is more specialized than PAT2 as described in [temp.class.order].
-1 if PAT2 is more specialized than PAT1.
! 0 if neither is more specialized.
!
! FULL_ARGS is the full set of template arguments that triggers this
! partial ordering. */
int
! more_specialized_class (pat1, pat2, full_args)
! tree pat1, pat2, full_args;
{
tree targs;
int winner = 0;
targs = get_class_bindings (TREE_VALUE (pat1), TREE_PURPOSE (pat1),
! add_outermost_template_args (full_args, TREE_PURPOSE (pat2)));
if (targs)
--winner;
targs = get_class_bindings (TREE_VALUE (pat2), TREE_PURPOSE (pat2),
! add_outermost_template_args (full_args, TREE_PURPOSE (pat1)));
if (targs)
++winner;
*************** most_specialized_class (tmpl, args)
*** 9751,9757 ****
t = TREE_CHAIN (t);
for (; t; t = TREE_CHAIN (t))
{
! fate = more_specialized_class (champ, t);
if (fate == 1)
;
else
--- 9754,9760 ----
t = TREE_CHAIN (t);
for (; t; t = TREE_CHAIN (t))
{
! fate = more_specialized_class (champ, t, args);
if (fate == 1)
;
else
*************** most_specialized_class (tmpl, args)
*** 9768,9774 ****
for (t = list; t && t != champ; t = TREE_CHAIN (t))
{
! fate = more_specialized_class (champ, t);
if (fate != 1)
return error_mark_node;
}
--- 9771,9777 ----
for (t = list; t && t != champ; t = TREE_CHAIN (t))
{
! fate = more_specialized_class (champ, t, args);
if (fate != 1)
return error_mark_node;
}
diff -cprN gcc-33-save/gcc/testsuite/g++.dg/template/partial2.C gcc-33-new/gcc/testsuite/g++.dg/template/partial2.C
*** gcc-33-save/gcc/testsuite/g++.dg/template/partial2.C Thu Jan 1 07:00:00 1970
--- gcc-33-new/gcc/testsuite/g++.dg/template/partial2.C Fri Jul 11 21:49:49 2003
***************
*** 0 ****
--- 1,14 ----
+ // { dg-do compile }
+
+ // Origin: lorgon1@yahoo.com
+
+ // PR c++/11154: Multi-level template argument in partial ordering of
+ // class template
+
+ template <class A> struct Outer {
+ template <class T, class U = void, class V = void> struct Foo {};
+ template <class T, class U> struct Foo<T,U,void> {};
+ template <class T> struct Foo<T,void,void> {};
+ };
+
+ Outer<int>::Foo<int,void,void> f;