aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@acm.org>2020-09-11 08:23:32 -0700
committerNathan Sidwell <nathan@acm.org>2020-09-11 08:27:40 -0700
commit1be7bf7dab86d2fb33561b7eac1d2f527aa98b2c (patch)
treedd4900b73b3e973c7c08212277fe0077a635f1e6 /gcc
parent13144466f11036585389a0dc5826bf23d53d5616 (diff)
downloadgcc-1be7bf7dab86d2fb33561b7eac1d2f527aa98b2c.zip
gcc-1be7bf7dab86d2fb33561b7eac1d2f527aa98b2c.tar.gz
gcc-1be7bf7dab86d2fb33561b7eac1d2f527aa98b2c.tar.bz2
objc++: Always pop scope with method definitions [PR97015]
Syntax errors in method definition lists could leave us in a function scope. My recent change for block scope externs didn't like that. This reimplements the parsing loop to finish the method definition we started. AFAICT the original code was attempting to provide some error recovery. Also while there, simply do the token peeking at the top of the loop, rather than at the two(!) ends. gcc/cp/ * parser.c (cp_parser_objc_method_definition_list): Reimplement loop, make sure we pop scope. gcc/testsuite/ * obj-c++.dg/syntax-error-9.mm: Adjust expected errors.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/parser.c61
-rw-r--r--gcc/testsuite/obj-c++.dg/syntax-error-9.mm2
2 files changed, 27 insertions, 36 deletions
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index fed1689..fba3fcc 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -32980,44 +32980,42 @@ cp_parser_objc_method_prototype_list (cp_parser* parser)
static void
cp_parser_objc_method_definition_list (cp_parser* parser)
{
- cp_token *token = cp_lexer_peek_token (parser->lexer);
-
- while (token->keyword != RID_AT_END && token->type != CPP_EOF)
+ for (;;)
{
- tree meth;
+ cp_token *token = cp_lexer_peek_token (parser->lexer);
- if (token->type == CPP_PLUS || token->type == CPP_MINUS)
+ if (token->keyword == RID_AT_END)
{
- cp_token *ptk;
- tree sig, attribute;
- bool is_class_method;
- if (token->type == CPP_PLUS)
- is_class_method = true;
- else
- is_class_method = false;
+ cp_lexer_consume_token (parser->lexer); /* Eat '@end'. */
+ break;
+ }
+ else if (token->type == CPP_EOF)
+ {
+ cp_parser_error (parser, "expected %<@end%>");
+ break;
+ }
+ else if (token->type == CPP_PLUS || token->type == CPP_MINUS)
+ {
+ bool is_class_method = token->type == CPP_PLUS;
+
push_deferring_access_checks (dk_deferred);
- sig = cp_parser_objc_method_signature (parser, &attribute);
+ tree attribute;
+ tree sig = cp_parser_objc_method_signature (parser, &attribute);
if (sig == error_mark_node)
+ cp_parser_skip_to_end_of_block_or_statement (parser);
+ else
{
- cp_parser_skip_to_end_of_block_or_statement (parser);
- token = cp_lexer_peek_token (parser->lexer);
- continue;
- }
- objc_start_method_definition (is_class_method, sig, attribute,
- NULL_TREE);
+ objc_start_method_definition (is_class_method, sig,
+ attribute, NULL_TREE);
- /* For historical reasons, we accept an optional semicolon. */
- if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
- cp_lexer_consume_token (parser->lexer);
+ /* For historical reasons, we accept an optional semicolon. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
+ cp_lexer_consume_token (parser->lexer);
- ptk = cp_lexer_peek_token (parser->lexer);
- if (!(ptk->type == CPP_PLUS || ptk->type == CPP_MINUS
- || ptk->type == CPP_EOF || ptk->keyword == RID_AT_END))
- {
perform_deferred_access_checks (tf_warning_or_error);
stop_deferring_access_checks ();
- meth = cp_parser_function_definition_after_declarator (parser,
- false);
+ tree meth
+ = cp_parser_function_definition_after_declarator (parser, false);
pop_deferring_access_checks ();
objc_finish_method_definition (meth);
}
@@ -33037,15 +33035,8 @@ cp_parser_objc_method_definition_list (cp_parser* parser)
else
/* Allow for interspersed non-ObjC++ code. */
cp_parser_objc_interstitial_code (parser);
-
- token = cp_lexer_peek_token (parser->lexer);
}
- if (token->type != CPP_EOF)
- cp_lexer_consume_token (parser->lexer); /* Eat '@end'. */
- else
- cp_parser_error (parser, "expected %<@end%>");
-
objc_finish_implementation ();
}
diff --git a/gcc/testsuite/obj-c++.dg/syntax-error-9.mm b/gcc/testsuite/obj-c++.dg/syntax-error-9.mm
index ae104e5..1876c32 100644
--- a/gcc/testsuite/obj-c++.dg/syntax-error-9.mm
+++ b/gcc/testsuite/obj-c++.dg/syntax-error-9.mm
@@ -1,3 +1,3 @@
@implementation SaturnDoc /* { dg-warning "cannot find interface declaration" } */
- read: (void*)aStream ggg /* { dg-error "expected .:. at end of input" } */
-/* { dg-error "-:expected ..end. at end of input" "" { target *-*-* } .+1 } */
+/* { dg-error "-:expected ..*. at end of input" "" { target *-*-* } .+1 } */