This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[C++ PATCH] Fix PR11154 regression (3.3.1 version)


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;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]