From 2ecfae77e4f790562a78722b048d068e521c9c47 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Fri, 1 Aug 2014 14:33:41 -0400 Subject: [PATCH] re PR c++/60241 (internal compiler error: in finish_member_declaration, at cp/semantics.c:2617) PR c++/60241 * pt.c (lookup_template_class_1): Update DECL_TEMPLATE_INSTANTIATIONS of the partial instantiation, not the most general template. (maybe_process_partial_specialization): Reassign everything on that list. From-SVN: r213500 --- gcc/cp/ChangeLog | 8 +++++++ gcc/cp/pt.c | 16 ++++++++------ gcc/testsuite/g++.dg/template/memclass5.C | 26 +++++++++++++++++++++++ 3 files changed, 43 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/g++.dg/template/memclass5.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index eda7f4e2e90b..9c49b5c66938 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +2014-02-21 Jason Merrill + + PR c++/60241 + * pt.c (lookup_template_class_1): Update DECL_TEMPLATE_INSTANTIATIONS + of the partial instantiation, not the most general template. + (maybe_process_partial_specialization): Reassign everything on + that list. + 2014-03-05 Jason Merrill PR c++/60361 diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index a1888921a2fa..a8e2cd90fce9 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -907,11 +907,13 @@ maybe_process_partial_specialization (tree type) t; t = TREE_CHAIN (t)) { tree inst = TREE_VALUE (t); - if (CLASSTYPE_TEMPLATE_SPECIALIZATION (inst)) + if (CLASSTYPE_TEMPLATE_SPECIALIZATION (inst) + || !COMPLETE_OR_OPEN_TYPE_P (inst)) { /* We already have a full specialization of this partial - instantiation. Reassign it to the new member - specialization template. */ + instantiation, or a full specialization has been + looked up but not instantiated. Reassign it to the + new member specialization template. */ spec_entry elt; spec_entry *entry; void **slot; @@ -930,7 +932,7 @@ maybe_process_partial_specialization (tree type) *entry = elt; *slot = entry; } - else if (COMPLETE_OR_OPEN_TYPE_P (inst)) + else /* But if we've had an implicit instantiation, that's a problem ([temp.expl.spec]/6). */ error ("specialization %qT after instantiation %qT", @@ -7455,7 +7457,7 @@ lookup_template_class_1 (tree d1, tree arglist, tree in_decl, tree context, } /* Let's consider the explicit specialization of a member - of a class template specialization that is implicitely instantiated, + of a class template specialization that is implicitly instantiated, e.g.: template struct S @@ -7553,9 +7555,9 @@ lookup_template_class_1 (tree d1, tree arglist, tree in_decl, tree context, /* Note this use of the partial instantiation so we can check it later in maybe_process_partial_specialization. */ - DECL_TEMPLATE_INSTANTIATIONS (templ) + DECL_TEMPLATE_INSTANTIATIONS (found) = tree_cons (arglist, t, - DECL_TEMPLATE_INSTANTIATIONS (templ)); + DECL_TEMPLATE_INSTANTIATIONS (found)); if (TREE_CODE (template_type) == ENUMERAL_TYPE && !is_dependent_type) /* Now that the type has been registered on the instantiations diff --git a/gcc/testsuite/g++.dg/template/memclass5.C b/gcc/testsuite/g++.dg/template/memclass5.C new file mode 100644 index 000000000000..eb32f13c916e --- /dev/null +++ b/gcc/testsuite/g++.dg/template/memclass5.C @@ -0,0 +1,26 @@ +// PR c++/60241 + +template +struct x +{ + template + struct y + { + typedef T result2; + }; + + typedef y zy; +}; + +template<> +template +struct x::y +{ + typedef double result2; +}; + +int main() +{ + x::zy::result2 xxx; + x::y::result2 xxx2; +} -- 2.47.2