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