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 for 3.3/3.4] Fix PR6440, a regression


Hi

This patch fixes the regression PR6440 present in 3.2/3.3/3.4.
The problem is that when we are processing a specialization
(see complete test case in the patch):

	template<> template<class X> 
	struct A<int>::B { ... };

i.e., the outer template class is specialized, the tree node
for 'A<int>::B' is already implicitly instantiated as an
instantiation of 'A<T>::B' during name lookup inside 'A<int>'
to find 'B'.  However in the above code, 'A<int>::B' should be 
treated as a primary template.  My patch simply undo the 
instantiation when the above case happens.

Tested on i686-pc-linux-gnu, OK for 3.3 branch and trunk?

--Kriang


2003-02-05  Kriang Lerdsuwanakij  <lerdsuwa@users.sourceforge.net>

	PR c++/6440
	* pt.c (unregister_instantiation): New function.
	(maybe_process_partial_specialization): Handle when outer
	template class is specialized.

2003-02-05  Kriang Lerdsuwanakij  <lerdsuwa@users.sourceforge.net>

	PR c++/8591
	* g++.dg/template/spec6.C: New test.


diff -cprN gcc-main-save/gcc/cp/pt.c gcc-main-new/gcc/cp/pt.c
*** gcc-main-save/gcc/cp/pt.c	Fri Jan 31 23:27:32 2003
--- gcc-main-new/gcc/cp/pt.c	Tue Feb  4 22:41:15 2003
*************** static tree retrieve_local_specializatio
*** 129,134 ****
--- 129,135 ----
  static tree register_specialization PARAMS ((tree, tree, tree));
  static void register_local_specialization PARAMS ((tree, tree));
  static int unregister_specialization PARAMS ((tree, tree));
+ static int unregister_instantiation PARAMS ((tree, tree));
  static tree reduce_template_parm_level PARAMS ((tree, tree, int));
  static tree build_template_decl PARAMS ((tree, tree));
  static int mark_template_parm PARAMS ((tree, void *));
*************** void 
*** 776,781 ****
--- 777,806 ----
  maybe_process_partial_specialization (type)
       tree type;
  {
+   if (CLASS_TYPE_P (type) && TYPE_TEMPLATE_INFO (type)
+       && DECL_TEMPLATE_INFO (TYPE_TI_TEMPLATE (type)))
+     {
+       /* This happens when we want to specialize an outer class template.
+ 	 For example:
+ 
+ 	   template <typename T> struct A {
+ 	     template <typename U> struct B { ... };
+ 	   };
+ 	   template <> template <typename U> struct A<int>::B { ... };
+ 
+ 	 When processing the class body of specialization A<int>::B, we
+ 	 have already registered A<int>::B as an implicit instantiation
+ 	 of A<T>::B in lookup_template_class.  Undo that here so it
+ 	 becomes a primary template.  */
+ 
+       tree template = TYPE_TI_TEMPLATE (type);
+       tree gen_tmpl = DECL_TI_TEMPLATE (template);
+ 
+       unregister_instantiation (TREE_TYPE (template), gen_tmpl);
+       DECL_TEMPLATE_INFO (template) = NULL_TREE;
+       DECL_USE_TEMPLATE (template) = 0;
+     }
+ 
    if (CLASS_TYPE_P (type) && CLASSTYPE_USE_TEMPLATE (type))
      {
        if (CLASSTYPE_IMPLICIT_INSTANTIATION (type)
*************** unregister_specialization (spec, tmpl)
*** 1000,1005 ****
--- 1025,1053 ----
        {
  	*s = TREE_CHAIN (*s);
  	return 1;
+       }
+ 
+   return 0;
+ }
+ 
+ /* Unregister the instantiation INST as a instantiation of TMPL.
+    Returns nonzero if the INST was listed as a instantiation of
+    TMPL.  */
+ 
+ static int
+ unregister_instantiation (inst, tmpl)
+      tree inst;
+      tree tmpl;
+ {
+   tree* s;
+ 
+   for (s = &DECL_TEMPLATE_INSTANTIATIONS (tmpl);
+        *s != NULL_TREE;
+        s = &TREE_CHAIN (*s))
+     if (TREE_VALUE (*s) == inst)
+       {
+ 	*s = TREE_CHAIN (*s);
+ 	return 1;
        }
  
    return 0;
diff -cprN gcc-main-save/gcc/testsuite/g++.dg/template/spec6.C gcc-main-new/gcc/testsuite/g++.dg/template/spec6.C
*** gcc-main-save/gcc/testsuite/g++.dg/template/spec6.C	Thu Jan  1 07:00:00 1970
--- gcc-main-new/gcc/testsuite/g++.dg/template/spec6.C	Tue Feb  4 22:45:49 2003
***************
*** 0 ****
--- 1,20 ----
+ // { dg-do compile }
+ 
+ // Origin: Jens Maurer <Jens.Maurer@gmx.net>
+ 
+ // PR 6040.  Specialization of outer template class.
+ 
+ template<class T1> struct A { 
+   template<class T2> struct B { 
+     template<class T3> void mf1(T3);
+     void mf2();
+   }; 
+ }; 
+ 
+ template<> template<class X> 
+ struct A<int>::B {
+   template<class T> void mf1(T);
+ }; 
+ 
+ template<> template<> template<class T> 
+   void A<int>::B<double>::mf1(T t) { } 


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