diff options
author | Nathan Sidwell <nathan@acm.org> | 2020-07-21 12:37:58 -0700 |
---|---|---|
committer | Nathan Sidwell <nathan@acm.org> | 2020-07-21 12:42:09 -0700 |
commit | 4d6e94960aa199b2fe7bf5a66f98bd7691884c1d (patch) | |
tree | a9e4bce1eb8d4b9514d0baa8322d95d61fb1e0fa /gcc | |
parent | 28f2a080cc27531a8c78aec9f44aeff4961c2a4c (diff) | |
download | gcc-4d6e94960aa199b2fe7bf5a66f98bd7691884c1d.zip gcc-4d6e94960aa199b2fe7bf5a66f98bd7691884c1d.tar.gz gcc-4d6e94960aa199b2fe7bf5a66f98bd7691884c1d.tar.bz2 |
c++: Fix scan forward over pragma [PR96257]
It turns out that the paren scanning code is used for speculatively searching
to see if we're looking at a compound_literal. So we shouldn't always purge
pragma tokens.
gcc/cp/
* parser.c (cp_lexer_consume_token): Drop PRAGMA_EOL assert.
(cp_parser_skip_to_closing_parenthesis_1): Only pass start token
to pragma skipper if recovering.
(cp_parser_skip_to_pragma_eol): Only purge and change pragma
state when recovering.
gcc/testsuite/
* g++.dg/parse/pr96257.C: New.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/parser.c | 17 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/parse/pr96257.C | 18 |
2 files changed, 27 insertions, 8 deletions
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 11db024..5a2d73d 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -1121,8 +1121,6 @@ cp_lexer_consume_token (cp_lexer* lexer) { cp_token *token = lexer->next_token; - gcc_assert (!lexer->in_pragma || token->type != CPP_PRAGMA_EOL); - do { gcc_assert (token->type != CPP_EOF); @@ -3691,7 +3689,7 @@ cp_parser_skip_to_closing_parenthesis_1 (cp_parser *parser, case CPP_PRAGMA: /* We fell into a pragma. Skip it, and continue. */ - cp_parser_skip_to_pragma_eol (parser, token); + cp_parser_skip_to_pragma_eol (parser, recovering ? token : nullptr); continue; default: @@ -3930,15 +3928,14 @@ cp_parser_skip_to_closing_brace (cp_parser *parser) /* Consume tokens until we reach the end of the pragma. The PRAGMA_TOK parameter is the PRAGMA token, allowing us to purge the entire pragma - sequence. */ + sequence. PRAGMA_TOK can be NULL, if we're speculatively scanning + forwards (not error recovery). */ static void cp_parser_skip_to_pragma_eol (cp_parser* parser, cp_token *pragma_tok) { cp_token *token; - parser->lexer->in_pragma = false; - do { /* The preprocessor makes sure that a PRAGMA_EOL token appears @@ -3950,8 +3947,12 @@ cp_parser_skip_to_pragma_eol (cp_parser* parser, cp_token *pragma_tok) } while (token->type != CPP_PRAGMA_EOL); - /* Ensure that the pragma is not parsed again. */ - cp_lexer_purge_tokens_after (parser->lexer, pragma_tok); + if (pragma_tok) + { + /* Ensure that the pragma is not parsed again. */ + cp_lexer_purge_tokens_after (parser->lexer, pragma_tok); + parser->lexer->in_pragma = false; + } } /* Require pragma end of line, resyncing with it as necessary. The diff --git a/gcc/testsuite/g++.dg/parse/pr96257.C b/gcc/testsuite/g++.dg/parse/pr96257.C new file mode 100644 index 0000000..34b0208 --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/pr96257.C @@ -0,0 +1,18 @@ +// PR96257 we scan forwards checking for a compound literal. Do not +// eat the tokens when doing that! +/* { dg-require-effective-target fopenmp } */ +/* { dg-additional-options -fopenmp } */ + +int +f2 () +{ + int s = (int // { dg-error "expected" } +#pragma omp atomic capture + ){1}; + + int t = (int // { dg-error "expected" } +#pragma omp atomic capture ){ + {1}; + + return s + t; +} // { dg-bogus "expected" } |