[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
This commit is contained in:
Nathan Sidwell 2018-10-11 18:58:55 +00:00 committed by Nathan Sidwell
parent 13c4e4031a
commit c7f45560c7
6 changed files with 60 additions and 54 deletions

View File

@ -1,3 +1,9 @@
2018-10-11 Nathan Sidwell <nathan@acm.org>
* 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 <jakub@redhat.com>
PR c++/87582

View File

@ -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]
declaration-seq [opt] */
Returns TRUE if all went well. */
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;
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);
bool success;
/* Create the declarator obstack, if necessary. */
if (!cp_error_declarator)
{
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);
/* 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
for (;;)
{
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");
success = false;
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);
}
/* 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;
}
/* 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

View File

@ -1,3 +1,9 @@
2018-10-11 Nathan Sidwell <nathan@acm.org>
* 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 <jakub@redhat.com>
PR c++/85070

View File

@ -124,7 +124,7 @@ swap(_Tp&, _Tp&)
;
typedef lexertl::basic_state_machine<char32_t> lexstate;
lexstate m_state_machine;
GenerateLexer()
void GenerateLexer()
{
m_state_machine.minimise();
}

View File

@ -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" }

View File

@ -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<bar> c;
}
{
{ // { dg-error "expected" }
int a;
};