From c97692d5403cce37a9882ab118a24dca7b202f6c Mon Sep 17 00:00:00 2001 From: Sandra Loosemore Date: Fri, 3 Jan 2025 17:35:03 +0000 Subject: OpenMP: Robustify C front end handling of attribute-syntax pragmas Presently, the code to handle OpenMP attribute-syntax pragmas in the C front end assumes nothing else is messing with redirecting parser->tokens, and makes no provision for restoring it from anything other than parser->tokens_buf when the buffer allocated for the pragma is exhausted. Adding support for metadirectives will change that, since it also needs to buffer tokens for the metadirective alternatives, and an attribute-syntax directive can appear inside a metadirective. This patch adds a more general save/restore mechanism attached to the parser via a pointer to a new struct omp_attribute_pragma_state. gcc/c/ChangeLog * c-parser.cc (struct c_parser): Change in_omp_attribute_pragma field to be of type struct omp_attribute_pragma_state. (struct omp_attribute_pragma_state): New. (c_parser_skip_until_found): Use the new way to restore state on EOF. (c_parser_skip_to_pragma_eol): Likewise. (c_parser_handle_statement_omp_attributes): Create an omp_attribute_pragma_state to hold the restore state. Do not store state in tok.flags. (omp_maybe_parse_omp_decl): Likewise. --- gcc/c/c-parser.cc | 46 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 32 insertions(+), 14 deletions(-) (limited to 'gcc/c/c-parser.cc') diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc index f72b0f0..c46aac5 100644 --- a/gcc/c/c-parser.cc +++ b/gcc/c/c-parser.cc @@ -262,15 +262,25 @@ struct GTY(()) c_parser { struct omp_for_parse_data * GTY((skip)) omp_for_parse_state; /* If we're in the context of OpenMP directives written as C23 - attributes turned into pragma, vector of tokens created from that, - otherwise NULL. */ - vec *in_omp_attribute_pragma; + attributes turned into pragma, the tokens field is temporarily + redirected. This holds data needed to restore state afterwards. + It's NULL otherwise. */ + struct omp_attribute_pragma_state *in_omp_attribute_pragma; /* Set for omp::decl attribute parsing to the decl to which it appertains. */ tree in_omp_decl_attribute; }; +/* Holds data needed to restore the token stream to its previous state + after parsing an OpenMP attribute-syntax pragma. */ +struct GTY(()) omp_attribute_pragma_state +{ + vec *token_vec; + c_token * GTY((skip)) save_tokens; + unsigned int save_tokens_avail; +}; + /* Return a pointer to the Nth token in PARSERs tokens_buf. */ c_token * @@ -1312,8 +1322,9 @@ c_parser_skip_until_found (c_parser *parser, c_token *token = c_parser_peek_token (parser); if (token->type == CPP_EOF) { - parser->tokens = &parser->tokens_buf[0]; - parser->tokens_avail = token->flags; + parser->tokens = parser->in_omp_attribute_pragma->save_tokens; + parser->tokens_avail + = parser->in_omp_attribute_pragma->save_tokens_avail; parser->in_omp_attribute_pragma = NULL; } } @@ -1335,8 +1346,9 @@ c_parser_skip_until_found (c_parser *parser, c_token *token = c_parser_peek_token (parser); if (token->type == CPP_EOF) { - parser->tokens = &parser->tokens_buf[0]; - parser->tokens_avail = token->flags; + parser->tokens = parser->in_omp_attribute_pragma->save_tokens; + parser->tokens_avail + = parser->in_omp_attribute_pragma->save_tokens_avail; parser->in_omp_attribute_pragma = NULL; } } @@ -1429,8 +1441,9 @@ c_parser_skip_to_pragma_eol (c_parser *parser, bool error_if_not_eol = true) c_token *token = c_parser_peek_token (parser); if (token->type == CPP_EOF) { - parser->tokens = &parser->tokens_buf[0]; - parser->tokens_avail = token->flags; + parser->tokens = parser->in_omp_attribute_pragma->save_tokens; + parser->tokens_avail + = parser->in_omp_attribute_pragma->save_tokens_avail; parser->in_omp_attribute_pragma = NULL; } } @@ -7184,7 +7197,6 @@ c_parser_handle_statement_omp_attributes (c_parser *parser, tree &attrs, return false; unsigned int tokens_avail = parser->tokens_avail; - gcc_assert (parser->tokens == &parser->tokens_buf[0]); tokens++; vec *toks = NULL; @@ -7216,12 +7228,15 @@ c_parser_handle_statement_omp_attributes (c_parser *parser, tree &attrs, tok.type = CPP_EOF; tok.keyword = RID_MAX; tok.location = toks->last ().location; - tok.flags = tokens_avail; toks->quick_push (tok); + gcc_assert (!parser->in_omp_attribute_pragma); + parser->in_omp_attribute_pragma = ggc_alloc (); + parser->in_omp_attribute_pragma->token_vec = toks; + parser->in_omp_attribute_pragma->save_tokens = parser->tokens; + parser->in_omp_attribute_pragma->save_tokens_avail = tokens_avail; parser->tokens = toks->address (); parser->tokens_avail = tokens; - parser->in_omp_attribute_pragma = toks; return true; } @@ -27374,12 +27389,15 @@ c_maybe_parse_omp_decl (tree decl, tree d) tok.type = CPP_EOF; tok.keyword = RID_MAX; tok.location = last[-1].location; - tok.flags = tokens_avail; toks->quick_push (tok); parser->in_omp_decl_attribute = decl; + gcc_assert (!parser->in_omp_attribute_pragma); + parser->in_omp_attribute_pragma = ggc_alloc (); + parser->in_omp_attribute_pragma->token_vec = toks; + parser->in_omp_attribute_pragma->save_tokens = parser->tokens; + parser->in_omp_attribute_pragma->save_tokens_avail = tokens_avail; parser->tokens = toks->address (); parser->tokens_avail = toks->length (); - parser->in_omp_attribute_pragma = toks; c_parser_pragma (parser, pragma_external, NULL, NULL_TREE); parser->in_omp_decl_attribute = NULL_TREE; return true; -- cgit v1.1