diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 202e416cb571d4d70a317934f8bf61f52acce7cf..696349f7be88c9cce58d99cd4d264d56b3611ecb 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2004-12-09 Alexandre Oliva <aoliva@redhat.com> + + PR c++/18757 + * parser.c (cp_parser_template_id): Don't create a CPP_TEMPLATE_ID + if parsing failed. + 2004-12-09 Volker Reichelt <reichelt@igpm.rwth-aachen.de> PR c++/18073 diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index dae68f36578e16025c9cb1cb8ddcd9702cfde462..ce3c7a6838daeb588ea86a41abd1f5f0602d6c3b 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 54b1dfe9da3d51c28605172e5b06c8f8b3933c17..51d6be53469aa79700fd87684fafb29a56fce916 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2004-12-09 Alexandre Oliva <aoliva@redhat.com> + + * g++.dg/parse/typename5.C: Adjust for new error. + * g++.dg/parse/typename7.C: New. + 2004-12-09 Volker Reichelt <reichelt@igpm.rwth-aachen.de> PR c++/18073 diff --git a/gcc/testsuite/g++.dg/parse/typename5.C b/gcc/testsuite/g++.dg/parse/typename5.C index 6b2ed894a86d5bf735fa6da15aa12fc1b7fa5644..36647519fe61b3de710066237c60f6105e849de5 100644 --- a/gcc/testsuite/g++.dg/parse/typename5.C +++ b/gcc/testsuite/g++.dg/parse/typename5.C @@ -8,5 +8,5 @@ template <typename> struct A {}; template <typename> struct B { - typedef A<typename X::Y> C; // { dg-error "declared|invalid|no type" } + typedef A<typename X::Y> 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 0000000000000000000000000000000000000000..211931781394c037c071e58ad304e3edf99054b0 --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/typename7.C @@ -0,0 +1,31 @@ +// { dg-do compile } + +// Origin: Volker Reichelt <reichelt@igpm.rwth-aachen.de> and +// Alexandre Oliva <aoliva@redhat.com> + +// PR c++/18757: ICE in get_innermost_template_args + +struct A +{ + template<typename> void foo(int); + template<typename T> void bar(T t) { + this->foo<typename T>(t); } // { dg-error "expected" } + template<typename T> void bad(T t) { + foo<typename T>(t); } // { dg-error "expected" } +}; + +template <typename T> +struct B +{ + void bar(T t) { + A().bar<typename T>(t); } // { dg-error "expected" } + void bad(T t) { + B<typename T>::bar(t); } // { dg-error "invalid|not a template" } +}; + +void baz() +{ + A().bar(0); + A().bad(0); + B<int>().bar(0); +}