PR c++/24139

Mark Mitchell mark@codesourcery.com
Mon Oct 10 14:54:00 GMT 2005


This patch fixes PR 24139, a regression in the processing of template
specializations.  It's tricky to work out exactly how many
"template <>" you need for an explicit specialization for a member of
a class template; that depends on whether or not the containing class
is also an explicit specialization, which we failed to take into
account. 

Also, our error-reporting routines were printing template argument
lists for specializations that were not primary templates, which
was wrong, and confused people helping to analyze the PR.

Tested on x86_64-unknown-linux-gnu, applied on the 4.0 branch and on
the mainline.

--
Mark Mitchell
CodeSourcery, LLC
mark@codesourcery.com

2005-10-10  Mark Mitchell  <mark@codesourcery.com>

	PR c++/24139
	* decl.c (grokdeclarator): Do not require template parameter lists
	for explicitly specialized class.
	* error.c (dump_aggr_type): Do not dump template arguments for
	non-primary specializations.
	(dump_function_name): Likewise.

2005-10-10  Mark Mitchell  <mark@codesourcery.com>

	PR c++/24139
	* g++.dg/template/spec27.C: New test. 

Index: gcc/cp/decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl.c,v
retrieving revision 1.1429
diff -c -5 -p -r1.1429 decl.c
*** gcc/cp/decl.c	28 Sep 2005 14:49:23 -0000	1.1429
--- gcc/cp/decl.c	8 Oct 2005 23:20:59 -0000
*************** grokdeclarator (const cp_declarator *dec
*** 7549,7561 ****
  	       template <> struct S<int> { void f(); };
  	       void S<int>::f () {}
  
  	     is correct; there shouldn't be a `template <>' for the
  	     definition of `S<int>::f'.  */
! 	  if (CLASSTYPE_TEMPLATE_INFO (t)
! 	      && (CLASSTYPE_TEMPLATE_INSTANTIATION (t)
! 		  || uses_template_parms (CLASSTYPE_TI_ARGS (t)))
  	      && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (t)))
  	    template_count += 1;
  
  	  t = TYPE_MAIN_DECL (t);
  	  t = DECL_CONTEXT (t);
--- 7549,7565 ----
  	       template <> struct S<int> { void f(); };
  	       void S<int>::f () {}
  
  	     is correct; there shouldn't be a `template <>' for the
  	     definition of `S<int>::f'.  */
! 	  if (CLASSTYPE_TEMPLATE_SPECIALIZATION (t)
! 	      && !any_dependent_template_arguments_p (CLASSTYPE_TI_ARGS (t)))
! 	    /* T is an explicit (not partial) specialization.  All
! 	       containing classes must therefore also be explicitly
! 	       specialized.  */
! 	    break;
! 	  if ((CLASSTYPE_USE_TEMPLATE (t) || CLASSTYPE_IS_TEMPLATE (t))
  	      && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (t)))
  	    template_count += 1;
  
  	  t = TYPE_MAIN_DECL (t);
  	  t = DECL_CONTEXT (t);
Index: gcc/cp/error.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/error.c,v
retrieving revision 1.292
diff -c -5 -p -r1.292 error.c
*** gcc/cp/error.c	15 Sep 2005 11:27:12 -0000	1.292
--- gcc/cp/error.c	8 Oct 2005 23:20:59 -0000
*************** dump_aggr_type (tree t, int flags)
*** 435,447 ****
    if (name)
      {
        typdef = !DECL_ARTIFICIAL (name);
        tmplate = !typdef && TREE_CODE (t) != ENUMERAL_TYPE
  		&& TYPE_LANG_SPECIFIC (t) && CLASSTYPE_TEMPLATE_INFO (t)
! 		&& (CLASSTYPE_TEMPLATE_SPECIALIZATION (t)
! 		    || TREE_CODE (CLASSTYPE_TI_TEMPLATE (t)) != TEMPLATE_DECL
! 		    || DECL_TEMPLATE_SPECIALIZATION (CLASSTYPE_TI_TEMPLATE (t))
  		    || PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (t)));
        dump_scope (CP_DECL_CONTEXT (name), flags | TFF_SCOPE);
        if (tmplate)
  	{
  	  /* Because the template names are mangled, we have to locate
--- 435,445 ----
    if (name)
      {
        typdef = !DECL_ARTIFICIAL (name);
        tmplate = !typdef && TREE_CODE (t) != ENUMERAL_TYPE
  		&& TYPE_LANG_SPECIFIC (t) && CLASSTYPE_TEMPLATE_INFO (t)
! 		&& (TREE_CODE (CLASSTYPE_TI_TEMPLATE (t)) != TEMPLATE_DECL
  		    || PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (t)));
        dump_scope (CP_DECL_CONTEXT (name), flags | TFF_SCOPE);
        if (tmplate)
  	{
  	  /* Because the template names are mangled, we have to locate
*************** dump_function_name (tree t, int flags)
*** 1180,1192 ****
    else
      dump_decl (name, flags);
  
    if (DECL_TEMPLATE_INFO (t)
        && !DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (t)
!       && (DECL_TEMPLATE_SPECIALIZATION (t)
! 	  || TREE_CODE (DECL_TI_TEMPLATE (t)) != TEMPLATE_DECL
! 	  || DECL_TEMPLATE_SPECIALIZATION (DECL_TI_TEMPLATE (t))
  	  || PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (t))))
      dump_template_parms (DECL_TEMPLATE_INFO (t), !DECL_USE_TEMPLATE (t), flags);
  }
  
  /* Dump the template parameters from the template info INFO under control of
--- 1178,1188 ----
    else
      dump_decl (name, flags);
  
    if (DECL_TEMPLATE_INFO (t)
        && !DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (t)
!       && (TREE_CODE (DECL_TI_TEMPLATE (t)) != TEMPLATE_DECL
  	  || PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (t))))
      dump_template_parms (DECL_TEMPLATE_INFO (t), !DECL_USE_TEMPLATE (t), flags);
  }
  
  /* Dump the template parameters from the template info INFO under control of
Index: gcc/testsuite/g++.dg/template/spec27.C
===================================================================
RCS file: gcc/testsuite/g++.dg/template/spec27.C
diff -N gcc/testsuite/g++.dg/template/spec27.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- gcc/testsuite/g++.dg/template/spec27.C	8 Oct 2005 23:21:00 -0000
***************
*** 0 ****
--- 1,14 ----
+ // PR c++/24139
+ 
+ template<typename T>
+ struct O {
+   struct I;
+ };
+ 
+ template<>
+ struct O<int>::I
+ {
+   I();
+ };
+ 
+ O<int>::I::I() {}



More information about the Gcc-patches mailing list