diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 202e416cb57..696349f7be8 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2004-12-09 Alexandre Oliva + + PR c++/18757 + * parser.c (cp_parser_template_id): Don't create a CPP_TEMPLATE_ID + if parsing failed. + 2004-12-09 Volker Reichelt PR c++/18073 diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index dae68f36578..ce3c7a6838d 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -8416,8 +8416,9 @@ cp_parser_template_id (cp_parser *parser, should we re-parse the token stream, we will not have to repeat the effort required to do the parse, nor will we issue duplicate error messages about problems during instantiation of the - template. */ - if (start_of_id) + template. Do so only if parsing succeeded, otherwise we may + silently accept template arguments with syntax errors. */ + if (start_of_id && !cp_parser_error_occurred (parser)) { cp_token *token = cp_lexer_token_at (parser->lexer, start_of_id); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 54b1dfe9da3..51d6be53469 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2004-12-09 Alexandre Oliva + + * g++.dg/parse/typename5.C: Adjust for new error. + * g++.dg/parse/typename7.C: New. + 2004-12-09 Volker Reichelt PR c++/18073 diff --git a/gcc/testsuite/g++.dg/parse/typename5.C b/gcc/testsuite/g++.dg/parse/typename5.C index 6b2ed894a86..36647519fe6 100644 --- a/gcc/testsuite/g++.dg/parse/typename5.C +++ b/gcc/testsuite/g++.dg/parse/typename5.C @@ -8,5 +8,5 @@ template struct A {}; template struct B { - typedef A C; // { dg-error "declared|invalid|no type" } + typedef A C; // { dg-error "declared|invalid|no type|expected" } }; diff --git a/gcc/testsuite/g++.dg/parse/typename7.C b/gcc/testsuite/g++.dg/parse/typename7.C new file mode 100644 index 00000000000..21193178139 --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/typename7.C @@ -0,0 +1,31 @@ +// { dg-do compile } + +// Origin: Volker Reichelt and +// Alexandre Oliva + +// PR c++/18757: ICE in get_innermost_template_args + +struct A +{ + template void foo(int); + template void bar(T t) { + this->foo(t); } // { dg-error "expected" } + template void bad(T t) { + foo(t); } // { dg-error "expected" } +}; + +template +struct B +{ + void bar(T t) { + A().bar(t); } // { dg-error "expected" } + void bad(T t) { + B::bar(t); } // { dg-error "invalid|not a template" } +}; + +void baz() +{ + A().bar(0); + A().bad(0); + B().bar(0); +}