mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-12-18 16:44:57 +08:00
re PR c/27358 (ICE with invalid variable after #pragma omp parallel)
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. From-SVN: r113421
This commit is contained in:
parent
0f57299d37
commit
2a83cc5254
@ -1,3 +1,10 @@
|
||||
2006-05-01 Richard Henderson <rth@redhat.com>
|
||||
|
||||
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 <roger@eyesopen.com>
|
||||
|
||||
* c-typeck.c (parser_build_binary_op): Don't call the function
|
||||
|
117
gcc/c-parser.c
117
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
|
||||
|
8
gcc/testsuite/gcc.dg/gomp/pr27358.c
Normal file
8
gcc/testsuite/gcc.dg/gomp/pr27358.c
Normal file
@ -0,0 +1,8 @@
|
||||
/* PR c/27358 */
|
||||
/* { dg-do compile } */
|
||||
|
||||
void foo(error i) /* { dg-error "" } */
|
||||
{
|
||||
#pragma omp parallel
|
||||
i = 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user