From adcd0e5f8e8d019e5742431029c2a0c5108ed1ca Mon Sep 17 00:00:00 2001 From: rth Date: Mon, 1 May 2006 17:46:32 +0000 Subject: [PATCH] PR c/27358 * c-parser.c (c_parser_skip_to_end_of_block_or_statement): Move after c_parser_skip_to_pragma_eol. Convert to switch statement. Handle CPP_PRAGMA. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@113421 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 7 +++ gcc/c-parser.c | 117 ++++++++++++++++++++++-------------- gcc/testsuite/gcc.dg/gomp/pr27358.c | 8 +++ 3 files changed, 88 insertions(+), 44 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/gomp/pr27358.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 30e68000ff2..78bc5a5ab91 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2006-05-01 Richard Henderson + + PR c/27358 + * c-parser.c (c_parser_skip_to_end_of_block_or_statement): Move after + c_parser_skip_to_pragma_eol. Convert to switch statement. Handle + CPP_PRAGMA. + 2006-05-01 Roger Sayle * c-typeck.c (parser_build_binary_op): Don't call the function diff --git a/gcc/c-parser.c b/gcc/c-parser.c index 8cad3108243..48edab70749 100644 --- a/gcc/c-parser.c +++ b/gcc/c-parser.c @@ -829,50 +829,6 @@ c_parser_skip_to_end_of_parameter (c_parser *parser) parser->error = false; } -/* Skip tokens until we have consumed an entire block, or until we - have consumed a non-nested ';'. */ - -static void -c_parser_skip_to_end_of_block_or_statement (c_parser *parser) -{ - unsigned nesting_depth = 0; - - while (true) - { - c_token *token; - - /* Peek at the next token. */ - token = c_parser_peek_token (parser); - /* If we've run out of tokens, stop. */ - if (token->type == CPP_EOF) - return; - if (token->type == CPP_PRAGMA_EOL && parser->in_pragma) - return; - /* If the next token is a ';', we have reached the end of the - statement. */ - if (token->type == CPP_SEMICOLON && !nesting_depth) - { - /* Consume the ';'. */ - c_parser_consume_token (parser); - break; - } - /* If the next token is a non-nested '}', then we have reached - the end of the current block. */ - if (token->type == CPP_CLOSE_BRACE - && (nesting_depth == 0 || --nesting_depth == 0)) - { - c_parser_consume_token (parser); - break; - } - /* If it the next token is a '{', then we are entering a new - block. Consume the entire block. */ - if (token->type == CPP_OPEN_BRACE) - ++nesting_depth; - c_parser_consume_token (parser); - } - parser->error = false; -} - /* Expect to be at the end of the pragma directive and consume an end of line marker. */ @@ -899,6 +855,79 @@ c_parser_skip_to_pragma_eol (c_parser *parser) parser->error = false; } +/* Skip tokens until we have consumed an entire block, or until we + have consumed a non-nested ';'. */ + +static void +c_parser_skip_to_end_of_block_or_statement (c_parser *parser) +{ + unsigned nesting_depth = 0; + bool save_error = parser->error; + + while (true) + { + c_token *token; + + /* Peek at the next token. */ + token = c_parser_peek_token (parser); + + switch (token->type) + { + case CPP_EOF: + return; + + case CPP_PRAGMA_EOL: + if (parser->in_pragma) + return; + break; + + case CPP_SEMICOLON: + /* If the next token is a ';', we have reached the + end of the statement. */ + if (!nesting_depth) + { + /* Consume the ';'. */ + c_parser_consume_token (parser); + goto finished; + } + break; + + case CPP_CLOSE_BRACE: + /* If the next token is a non-nested '}', then we have + reached the end of the current block. */ + if (nesting_depth == 0 || --nesting_depth == 0) + { + c_parser_consume_token (parser); + goto finished; + } + break; + + case CPP_OPEN_BRACE: + /* If it the next token is a '{', then we are entering a new + block. Consume the entire block. */ + ++nesting_depth; + break; + + case CPP_PRAGMA: + /* If we see a pragma, consume the whole thing at once. We + have some safeguards against consuming pragmas willy-nilly. + Normally, we'd expect to be here with parser->error set, + which disables these safeguards. But it's possible to get + here for secondary error recovery, after parser->error has + been cleared. */ + c_parser_consume_pragma (parser); + c_parser_skip_to_pragma_eol (parser); + parser->error = save_error; + continue; + } + + c_parser_consume_token (parser); + } + + finished: + parser->error = false; +} + /* Save the warning flags which are controlled by __extension__. */ static inline int diff --git a/gcc/testsuite/gcc.dg/gomp/pr27358.c b/gcc/testsuite/gcc.dg/gomp/pr27358.c new file mode 100644 index 00000000000..3451284e138 --- /dev/null +++ b/gcc/testsuite/gcc.dg/gomp/pr27358.c @@ -0,0 +1,8 @@ +/* PR c/27358 */ +/* { dg-do compile } */ + +void foo(error i) /* { dg-error "" } */ +{ +#pragma omp parallel + i = 0; +} -- 2.11.4.GIT