aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/parser.c85
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/noexcept16.C2
-rw-r--r--gcc/testsuite/g++.dg/parse/close-brace.C5
-rw-r--r--gcc/testsuite/g++.old-deja/g++.other/crash32.C6
6 files changed, 58 insertions, 52 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 9ec7c8b..da443d9 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 5e83b20..76ff836 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 4bca601..df8f70c 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
diff --git a/gcc/testsuite/g++.dg/cpp0x/noexcept16.C b/gcc/testsuite/g++.dg/cpp0x/noexcept16.C
index 10e0be9..873d9b2 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<char32_t> 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 0000000..3dde6b3
--- /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 b9c4cf9..d0b68db 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<bar> c;
}
-{
+{ // { dg-error "expected" }
int a;
};