Index: gcc/testsuite/g++.old-deja/g++.pt/crash4.C =================================================================== --- gcc/testsuite/g++.old-deja/g++.pt/crash4.C (revision 116698) +++ gcc/testsuite/g++.old-deja/g++.pt/crash4.C (working copy) @@ -7,5 +7,5 @@ class Tensor template class Tensor<2> : Tensor { // { dg-error "" } template parameters not used -}; +}; // { dg-error "extra" } Index: gcc/testsuite/g++.dg/parse/crash9.C =================================================================== --- gcc/testsuite/g++.dg/parse/crash9.C (revision 116698) +++ gcc/testsuite/g++.dg/parse/crash9.C (working copy) @@ -6,4 +6,4 @@ // contains error. template struct A {}; -template struct A : A { }; // { dg-error "not declared|invalid" } +template struct A : A { }; // { dg-error "not declared|invalid|token|extra" } Index: gcc/testsuite/g++.dg/template/spec34.C =================================================================== --- gcc/testsuite/g++.dg/template/spec34.C (revision 0) +++ gcc/testsuite/g++.dg/template/spec34.C (revision 0) @@ -0,0 +1,17 @@ +//PR c++/28301 + +template struct A +{ // { dg-error "declaration" } + template void foo() +}; // { dg-error "initializer|extra" } + +template<> struct A // { dg-error "specialization|template" } +{ + template void foo(); +}; + +void bar() +{ + A a; + a.foo<0>(); // { dg-error "invalid use|primary-expression" } +} // { dg-error "end of input" } Index: gcc/cp/pt.c =================================================================== --- gcc/cp/pt.c (revision 116698) +++ gcc/cp/pt.c (working copy) @@ -709,7 +709,10 @@ maybe_process_partial_specialization (tr check_specialization_namespace (CLASSTYPE_TI_TEMPLATE (type)); SET_CLASSTYPE_TEMPLATE_SPECIALIZATION (type); if (processing_template_decl) - push_template_decl (TYPE_MAIN_DECL (type)); + { + if (push_template_decl (TYPE_MAIN_DECL (type)) == error_mark_node) + return error_mark_node; + } } else if (CLASSTYPE_TEMPLATE_INSTANTIATION (type)) error ("specialization of %qT after instantiation", type); @@ -2720,6 +2723,9 @@ process_partial_specialization (tree dec error (" %qD", TREE_VALUE (TREE_VEC_ELT (inner_parms, i))); } + if (did_error_intro) + return error_mark_node; + /* [temp.class.spec] The argument list of the specialization shall not be identical to Index: gcc/cp/parser.c =================================================================== --- gcc/cp/parser.c (revision 116698) +++ gcc/cp/parser.c (working copy) @@ -13295,6 +13295,10 @@ cp_parser_class_head (cp_parser* parser, { type = TREE_TYPE (id); type = maybe_process_partial_specialization (type); + + if (type == error_mark_node) + goto done; + if (nested_name_specifier) pushed_scope = push_scope (nested_name_specifier); }