diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 02262fdeaa20d03a57e0c796a562069855ec34c6..f8710774ef30a2b24c47980b2d253f3963678460 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,12 @@ +2003-01-22 Mark Mitchell <mark@codesourcery.com> + + PR c++/9298 + * parser.c (cp_parser_consume_semicolon_at_end_of_statement): New + function. + (cp_parser_expression_statement): Use it. + (cp_parser_explicit_instantiation): Likewise. + * pt.c (do_decl_instantiation): Improve error handling logic. + 2003-01-22 Mark Mitchell <mark@codesourcery.com> PR c++/9384 diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 7f4eeaf67cb1b6b4c09bf86f9b2408bd1349a1c2..d64f0b4ef499b9d1cf5305a4de5604e29df76c16 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -1766,6 +1766,8 @@ static bool cp_parser_skip_to_closing_parenthesis_or_comma (cp_parser *); static void cp_parser_skip_to_end_of_statement PARAMS ((cp_parser *)); +static void cp_parser_consume_semicolon_at_end_of_statement + (cp_parser *); static void cp_parser_skip_to_end_of_block_or_statement PARAMS ((cp_parser *)); static void cp_parser_skip_to_closing_brace @@ -2107,6 +2109,25 @@ cp_parser_skip_to_end_of_statement (parser) } } +/* This function is called at the end of a statement or declaration. + If the next token is a semicolon, it is consumed; otherwise, error + recovery is attempted. */ + +static void +cp_parser_consume_semicolon_at_end_of_statement (cp_parser *parser) +{ + /* Look for the trailing `;'. */ + if (!cp_parser_require (parser, CPP_SEMICOLON, "`;'")) + { + /* If there is additional (erroneous) input, skip to the end of + the statement. */ + cp_parser_skip_to_end_of_statement (parser); + /* If the next token is now a `;', consume it. */ + if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON)) + cp_lexer_consume_token (parser->lexer); + } +} + /* Skip tokens until we have consumed an entire block, or until we have consumed a non-nested `;'. */ @@ -5628,15 +5649,7 @@ cp_parser_expression_statement (parser) statement = NULL_TREE; } /* Consume the final `;'. */ - if (!cp_parser_require (parser, CPP_SEMICOLON, "`;'")) - { - /* If there is additional (erroneous) input, skip to the end of - the statement. */ - cp_parser_skip_to_end_of_statement (parser); - /* If the next token is now a `;', consume it. */ - if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON)) - cp_lexer_consume_token (parser->lexer); - } + cp_parser_consume_semicolon_at_end_of_statement (parser); return statement; } @@ -8256,8 +8269,7 @@ cp_parser_explicit_instantiation (parser) /* Trun access control back on. */ scope_chain->check_access = flag_access_control; - /* Look for the trailing `;'. */ - cp_parser_require (parser, CPP_SEMICOLON, "`;'"); + cp_parser_consume_semicolon_at_end_of_statement (parser); } /* Parse an explicit-specialization. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 9f391ebf0368a57b007c309c5c25e58f7a22675d..ca75cb0b0d65a1cacf85410cca346a8d6c50e121 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -10219,9 +10219,9 @@ do_decl_instantiation (tree decl, tree storage) should handle VAR_DECLs as it currently handles FUNCTION_DECLs. */ result = lookup_field (DECL_CONTEXT (decl), DECL_NAME (decl), 0, 0); - if (result && TREE_CODE (result) != VAR_DECL) + if (!result || TREE_CODE (result) != VAR_DECL) { - error ("no matching template for `%D' found", result); + error ("no matching template for `%D' found", decl); return; } } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 1bc7453636563dca153430b3bc718a96eb884a3a..fed915c899aaee82b36a88f38734f9baab443575 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2003-01-22 Mark Mitchell <mark@codesourcery.com> + PR c++/9298 + * g++.dg/parse/template1.C: New test. + PR c++/9384 * g++.dg/parse/using1.C: New test. diff --git a/gcc/testsuite/g++.dg/parse/template1.C b/gcc/testsuite/g++.dg/parse/template1.C new file mode 100644 index 0000000000000000000000000000000000000000..d7bbb073f812416a38a4a961618050afd428958c --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/template1.C @@ -0,0 +1,11 @@ +struct CPU { + typedef int (*pfun)(); + + template <pfun step1> + static int dispatch(); +}; + +template<int> +static int foo(); + +template int CPU::dispatch<&template foo<2> > (); // { dg-error "" }