On 1/2/25 11:44, Tobias Burnus wrote:
[snip]
Otherwise, LGTM.
I've pushed the attached version of the patch after making the requested
trivial changes and re-testing this piece of the series in isolation.
It's independent of parts 1, 2, and 3 which are still pending, but a
prerequisite for part 5, the C support for metadirective.
-Sandra
From 83e9dbbac718d439724f81c0f3a706d5cea389cf Mon Sep 17 00:00:00 2001
From: Sandra Loosemore <sloosem...@baylibre.com>
Date: Fri, 3 Jan 2025 17:35:03 +0000
Subject: [PATCH] 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(-)
diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc
index f72b0f0e39f..c46aac5f0a2 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<c_token, va_gc> *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<c_token, va_gc> *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<c_token, va_gc> *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<omp_attribute_pragma_state> ();
+ 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<omp_attribute_pragma_state> ();
+ 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;
--
2.34.1