Index: gcc/testsuite/g++.dg/template/operator7.C =================================================================== --- gcc/testsuite/g++.dg/template/operator7.C (revision 0) +++ gcc/testsuite/g++.dg/template/operator7.C (revision 0) @@ -0,0 +1,6 @@ +//PR c++/27493 + +template void foo() // { dg-error "before|template" } +{ + struct A {}; +} Index: gcc/testsuite/g++.dg/template/operator8.C =================================================================== --- gcc/testsuite/g++.dg/template/operator8.C (revision 0) +++ gcc/testsuite/g++.dg/template/operator8.C (revision 0) @@ -0,0 +1,12 @@ +//PR c++/27494 + +struct A +{ + template void foo() {} // { dg-error "identifier|non-function|template arguments" } +}; + +struct B +{ + template void foo() {} // { dg-error "identifier|non-function|'void'" } + template void bar() {} // { dg-error "template arguments" } +}; Index: gcc/testsuite/g++.dg/template/operator9.C =================================================================== --- gcc/testsuite/g++.dg/template/operator9.C (revision 0) +++ gcc/testsuite/g++.dg/template/operator9.C (revision 0) @@ -0,0 +1,9 @@ +//PR c++/27670 + +template void foo(); // { dg-error "before|non-function|template" } + +void bar() +{ + foo(); // { dg-error "no matching function" } +} + Index: gcc/testsuite/g++.dg/template/crash56.C =================================================================== --- gcc/testsuite/g++.dg/template/crash56.C (revision 0) +++ gcc/testsuite/g++.dg/template/crash56.C (revision 0) @@ -0,0 +1,10 @@ +//PR c++/27397 + +template struct A; // { dg-error "token" } + +template struct B +{ + template struct C; // { dg-error "token" } +}; + +A a; // { dg-error "type/value mismatch|constant|declaration" } Index: gcc/testsuite/g++.dg/template/typedef4.C =================================================================== --- gcc/testsuite/g++.dg/template/typedef4.C (revision 116592) +++ gcc/testsuite/g++.dg/template/typedef4.C (working copy) @@ -1,7 +1,7 @@ // PR c++/27572 // { dg-do compile } -template void foo(); // { dg-error "no type|typedef declaration" } +template void foo(); // { dg-error "no type|typedef declaration|template" } void bar() { Index: gcc/testsuite/g++.dg/template/typedef5.C =================================================================== --- gcc/testsuite/g++.dg/template/typedef5.C (revision 116592) +++ gcc/testsuite/g++.dg/template/typedef5.C (working copy) @@ -1,7 +1,7 @@ // PR c++/27572 // { dg-do compile } -template struct A1; // { dg-error "no type|typedef declaration" } -template struct A2; // { dg-error "no type|typedef declaration" } -template struct A3; // { dg-error "no type|typedef declaration" } -template struct A4; // { dg-error "typedef declaration" } +template struct A1; // { dg-error "no type|typedef declaration|default argument" } +template struct A2; // { dg-error "no type|typedef declaration|default argument" } +template struct A3; // { dg-error "no type|typedef declaration|default argument" } +template struct A4; // { dg-error "typedef declaration|default argument" } Index: gcc/cp/parser.c =================================================================== --- gcc/cp/parser.c (revision 116592) +++ gcc/cp/parser.c (working copy) @@ -8394,6 +8394,13 @@ cp_parser_template_parameter_list (cp_pa parameter_list = process_template_parm (parameter_list, parameter, is_non_type); + else + { + tree err_parm = build_tree_list (parameter, parameter); + TREE_VALUE (err_parm) = error_mark_node; + parameter_list = chainon (parameter_list, err_parm); + } + /* Peek at the next token. */ token = cp_lexer_peek_token (parser->lexer); /* If it's not a `,', we're done. */