From 747f0d2a917dbbd49282158a6e8b331a1364b1d1 Mon Sep 17 00:00:00 2001 From: jason Date: Thu, 6 Dec 2012 14:37:04 +0000 Subject: [PATCH] PR c++/54653 * parser.c (cp_parser_class_head): A partial specialization scope counts as a template. * pt.c (tsubst_template_parms): Handle template template parm parms. (tsubst_decl) [TEMPLATE_DECL]: Handle getting a template template argument back. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@194249 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/cp/ChangeLog | 7 +++++++ gcc/cp/parser.c | 3 ++- gcc/cp/pt.c | 6 +++++- gcc/testsuite/g++.dg/template/partial-specialization2.C | 8 ++++++++ 4 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/g++.dg/template/partial-specialization2.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 917f3e95a94..04a71f23a41 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,12 @@ 2012-12-06 Jason Merrill + PR c++/54653 + * parser.c (cp_parser_class_head): A partial specialization scope + counts as a template. + * pt.c (tsubst_template_parms): Handle template template parm parms. + (tsubst_decl) [TEMPLATE_DECL]: Handle getting a template template + argument back. + PR c++/55564 * pt.c (unify) [ARRAY_TYPE]: Unify the element type before the bounds. diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 1fe6246f032..190b8d94113 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -18589,7 +18589,8 @@ cp_parser_class_head (cp_parser* parser, && CLASS_TYPE_P (scope) && CLASSTYPE_TEMPLATE_INFO (scope) && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (scope)) - && !CLASSTYPE_TEMPLATE_SPECIALIZATION (scope)) + && (!CLASSTYPE_TEMPLATE_SPECIALIZATION (scope) + || uses_template_parms (CLASSTYPE_TI_ARGS (scope)))) ++num_templates; } } diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 27084a23598..c1e12f060db 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -9552,7 +9552,7 @@ tsubst_template_parms (tree parms, tree args, tsubst_flags_t complain) ++processing_template_decl; for (new_parms = &r; - TMPL_PARMS_DEPTH (parms) > TMPL_ARGS_DEPTH (args); + parms && TMPL_PARMS_DEPTH (parms) > TMPL_ARGS_DEPTH (args); new_parms = &(TREE_CHAIN (*new_parms)), parms = TREE_CHAIN (parms)) { @@ -9831,6 +9831,10 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) tree new_type = tsubst (TREE_TYPE (t), args, complain, in_decl); if (new_type == error_mark_node) RETURN (error_mark_node); + /* If we get a real template back, return it. This can happen in + the context of most_specialized_class. */ + if (TREE_CODE (new_type) == TEMPLATE_DECL) + return new_type; r = copy_decl (t); DECL_CHAIN (r) = NULL_TREE; diff --git a/gcc/testsuite/g++.dg/template/partial-specialization2.C b/gcc/testsuite/g++.dg/template/partial-specialization2.C new file mode 100644 index 00000000000..c22d73989ae --- /dev/null +++ b/gcc/testsuite/g++.dg/template/partial-specialization2.C @@ -0,0 +1,8 @@ +// PR c++/54653 + +template struct A; +template struct A { + template struct B; +}; + +template struct A::B { }; // { dg-error "too few template-parameter-lists" } -- 2.11.4.GIT