From: Nathan Sidwell Date: Thu, 11 Oct 2018 18:58:55 +0000 (+0000) Subject: [C++ PATCH] parser simplification X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=c7f45560c7856139118f71dd31d1bc2f3eb7b98c;p=gcc.git [C++ PATCH] parser simplification https://gcc.gnu.org/ml/gcc-patches/2018-10/msg00689.html cp/ * parser.c (cp_parser_translation_unit): Return void. Don't fail at first extra }, simplify logic. (c_parse_file): Call finish_translation_unit here. testsuite/ * g++.dg/parse/close-brace.C: New. * g++.dg/cpp0x/noexcept16.C: Avoid warning. * g++.old-deja/g++.other/crash32.C: Add another error From-SVN: r265055 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 9ec7c8b861c..da443d9be40 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2018-10-11 Nathan Sidwell + + * parser.c (cp_parser_translation_unit): Return void. Don't fail + at first extra }, simplify logic. + (c_parse_file): Call finish_translation_unit here. + 2018-10-11 Jakub Jelinek PR c++/87582 diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 5e83b20360a..76ff83616b0 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -2015,8 +2015,7 @@ static cp_expr cp_parser_userdef_numeric_literal /* Basic concepts [gram.basic] */ -static bool cp_parser_translation_unit - (cp_parser *); +static void cp_parser_translation_unit (cp_parser *); /* Expressions [gram.expr] */ @@ -4585,66 +4584,52 @@ cp_parser_userdef_string_literal (tree literal) /* Parse a translation-unit. translation-unit: - declaration-seq [opt] - - Returns TRUE if all went well. */ + declaration-seq [opt] */ -static bool +static void cp_parser_translation_unit (cp_parser* parser) { - /* The address of the first non-permanent object on the declarator - obstack. */ - static void *declarator_obstack_base; - - bool success; + gcc_checking_assert (!cp_error_declarator); + + /* Create the declarator obstack. */ + gcc_obstack_init (&declarator_obstack); + /* Create the error declarator. */ + cp_error_declarator = make_declarator (cdk_error); + /* Create the empty parameter list. */ + no_parameters = make_parameter_declarator (NULL, NULL, NULL_TREE, + UNKNOWN_LOCATION); + /* Remember where the base of the declarator obstack lies. */ + void *declarator_obstack_base = obstack_next_free (&declarator_obstack); - /* Create the declarator obstack, if necessary. */ - if (!cp_error_declarator) + for (;;) { - gcc_obstack_init (&declarator_obstack); - /* Create the error declarator. */ - cp_error_declarator = make_declarator (cdk_error); - /* Create the empty parameter list. */ - no_parameters = make_parameter_declarator (NULL, NULL, NULL_TREE, - UNKNOWN_LOCATION); - /* Remember where the base of the declarator obstack lies. */ - declarator_obstack_base = obstack_next_free (&declarator_obstack); + cp_parser_declaration_seq_opt (parser); + gcc_assert (!cp_parser_parsing_tentatively (parser)); + if (cp_lexer_next_token_is (parser->lexer, CPP_EOF)) + break; + /* Must have been an extra close-brace. */ + cp_parser_error (parser, "expected declaration"); + cp_lexer_consume_token (parser->lexer); + /* 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_declaration_seq_opt (parser); - - /* If there are no tokens left then all went well. */ - if (cp_lexer_next_token_is (parser->lexer, CPP_EOF)) - { - /* Get rid of the token array; we don't need it any more. */ - cp_lexer_destroy (parser->lexer); - parser->lexer = NULL; - - /* This file might have been a context that's implicitly extern - "C". If so, pop the lang context. (Only relevant for PCH.) */ - if (parser->implicit_extern_c) - { - pop_lang_context (); - parser->implicit_extern_c = false; - } - - /* Finish up. */ - finish_translation_unit (); - - success = true; - } - else + /* Get rid of the token array; we don't need it any more. */ + cp_lexer_destroy (parser->lexer); + parser->lexer = NULL; + + /* This file might have been a context that's implicitly extern + "C". If so, pop the lang context. (Only relevant for PCH.) */ + if (parser->implicit_extern_c) { - cp_parser_error (parser, "expected declaration"); - success = false; + pop_lang_context (); + parser->implicit_extern_c = false; } /* Make sure the declarator obstack was fully cleaned up. */ gcc_assert (obstack_next_free (&declarator_obstack) == declarator_obstack_base); - - /* All went well. */ - return success; } /* Return the appropriate tsubst flags for parsing, possibly in N3276 @@ -39130,6 +39115,8 @@ c_parse_file (void) ? dk_no_deferred : dk_no_check); cp_parser_translation_unit (the_parser); the_parser = NULL; + + finish_translation_unit (); } /* Create an identifier for a generic parameter type (a synthesized diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 4bca601358f..df8f70c671e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2018-10-11 Nathan Sidwell + + * g++.dg/parse/close-brace.C: New. + * g++.dg/cpp0x/noexcept16.C: Avoid warning. + * g++.old-deja/g++.other/crash32.C: Add another error + 2018-10-11 Jakub Jelinek PR c++/85070 diff --git a/gcc/testsuite/g++.dg/cpp0x/noexcept16.C b/gcc/testsuite/g++.dg/cpp0x/noexcept16.C index 10e0be95887..873d9b2c48e 100644 --- a/gcc/testsuite/g++.dg/cpp0x/noexcept16.C +++ b/gcc/testsuite/g++.dg/cpp0x/noexcept16.C @@ -124,7 +124,7 @@ swap(_Tp&, _Tp&) ; typedef lexertl::basic_state_machine lexstate; lexstate m_state_machine; -GenerateLexer() +void GenerateLexer() { m_state_machine.minimise(); } diff --git a/gcc/testsuite/g++.dg/parse/close-brace.C b/gcc/testsuite/g++.dg/parse/close-brace.C new file mode 100644 index 00000000000..3dde6b34a09 --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/close-brace.C @@ -0,0 +1,5 @@ +// We used to stop parsing at the first top-level '}' ! + +} // { dg-error "expected declaration" } + +float int c; // { dg-error "two or more data types" } diff --git a/gcc/testsuite/g++.old-deja/g++.other/crash32.C b/gcc/testsuite/g++.old-deja/g++.other/crash32.C index b9c4cf98c06..d0b68db744a 100644 --- a/gcc/testsuite/g++.old-deja/g++.other/crash32.C +++ b/gcc/testsuite/g++.old-deja/g++.other/crash32.C @@ -5,7 +5,9 @@ struct foo { enum e { - not // { dg-error "" } + not // { dg-error "" } + // We think the next close-brace closes the definition of struct + // foo, not enum e. Things go downhill from there }; // { dg-bogus "" } ~foo(); // { dg-bogus "" "" { xfail *-*-* } } void x (foo *&a, bool b = (unsigned char)0); @@ -24,6 +26,6 @@ namespace N typedef baz c; } -{ +{ // { dg-error "expected" } int a; };