aboutsummaryrefslogtreecommitdiff
path: root/gcc/c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/c')
-rw-r--r--gcc/c/ChangeLog23
-rw-r--r--gcc/c/c-decl.cc70
-rw-r--r--gcc/c/c-parser.cc38
-rw-r--r--gcc/c/c-tree.h1
4 files changed, 103 insertions, 29 deletions
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog
index 241e71b..6f51dd9 100644
--- a/gcc/c/ChangeLog
+++ b/gcc/c/ChangeLog
@@ -1,3 +1,26 @@
+2025-10-21 Martin Uecker <uecker@tugraz.at>
+
+ * c-decl.cc (build_array_declarator): Remove error.
+ (grokgenassoc): New function.
+ (grokdeclarator): Add error.
+ * c-parser.cc (c_parser_generic_selection): Use grokgenassoc.
+ * c-tree.h (grokgenassoc): Add prototype.
+
+2025-10-21 Paul-Antoine Arras <parras@baylibre.com>
+
+ PR c/120180
+ PR fortran/122306
+ * c-parser.cc (c_parser_pragma): Accept a subset of non-executable
+ OpenMP directives in intervening code.
+ (c_parser_omp_error): Reject 'error at(execution)' in intervening code.
+ (c_parser_omp_metadirective): Return early if only one selector matches
+ and it resolves to 'omp nothing'.
+
+2025-10-21 Tobias Burnus <tburnus@baylibre.com>
+
+ * c-parser.cc (c_parser_omp_assumption_clauses): Switch to
+ 'unknown' not 'invalid' directive name for end directives.
+
2025-10-08 Joseph Myers <josmyers@redhat.com>
* c-typeck.cc (in_generic, save_maybe_used, restore_maybe_used):
diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index 4a940d5..061892a 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -71,7 +71,8 @@ enum decl_context
FUNCDEF, /* Function definition */
PARM, /* Declaration of parm before function body */
FIELD, /* Declaration inside struct or union */
- TYPENAME}; /* Typename (inside cast or sizeof) */
+ TYPENAME, /* Typename (inside cast or sizeof) */
+ GENERIC_ASSOC }; /* Typename in generic association */
/* States indicating how grokdeclarator() should handle declspecs marked
with __attribute__((deprecated)) or __attribute__((unavailable)).
@@ -5456,19 +5457,11 @@ build_array_declarator (location_t loc,
"ISO C90 does not support %<static%> or type "
"qualifiers in parameter array declarators");
if (vla_unspec_p)
- pedwarn_c90 (loc, OPT_Wpedantic,
- "ISO C90 does not support %<[*]%> array declarators");
- if (vla_unspec_p)
{
- if (!current_scope->parm_flag)
- {
- /* C99 6.7.5.2p4 */
- error_at (loc, "%<[*]%> not allowed in other than "
- "function prototype scope");
- declarator->u.array.vla_unspec_p = false;
- return NULL;
- }
- current_scope->had_vla_unspec = true;
+ pedwarn_c90 (loc, OPT_Wpedantic,
+ "ISO C90 does not support %<[*]%> array declarators");
+ if (current_scope->parm_flag)
+ current_scope->had_vla_unspec = true;
}
return declarator;
}
@@ -5574,6 +5567,29 @@ groktypename (struct c_type_name *type_name, tree *expr,
return type;
}
+
+/* Decode a "typename", such as "int **", returning a ..._TYPE node,
+ as for groktypename but setting the context to GENERIC_ASSOC. */
+
+tree
+grokgenassoc (struct c_type_name *type_name)
+{
+ tree type;
+ tree attrs = type_name->specs->attrs;
+
+ type_name->specs->attrs = NULL_TREE;
+
+ type = grokdeclarator (type_name->declarator, type_name->specs, GENERIC_ASSOC,
+ false, NULL, &attrs, NULL, NULL, DEPRECATED_NORMAL);
+
+ /* Apply attributes. */
+ attrs = c_warn_type_attributes (type, attrs);
+ decl_attributes (&type, attrs, 0);
+
+ return type;
+}
+
+
/* Looks up the most recent pushed declaration corresponding to DECL. */
static tree
@@ -6772,6 +6788,7 @@ build_arg_spec_attribute (tree type, bool static_p, tree attrs)
or before a function body). Make a PARM_DECL, or return void_type_node.
TYPENAME if for a typename (in a cast or sizeof).
Don't make a DECL node; just return the ..._TYPE node.
+ GENERIC_ASSOC for typenames in a generic association.
FIELD for a struct or union field; make a FIELD_DECL.
INITIALIZED is true if the decl has an initializer.
WIDTH is non-NULL for bit-fields, and is a pointer to an INTEGER_CST node
@@ -6908,6 +6925,7 @@ grokdeclarator (const struct c_declarator *declarator,
{
gcc_assert (decl_context == PARM
|| decl_context == TYPENAME
+ || decl_context == GENERIC_ASSOC
|| (decl_context == FIELD
&& declarator->kind == cdk_id));
gcc_assert (!initialized);
@@ -7481,14 +7499,6 @@ grokdeclarator (const struct c_declarator *declarator,
itype = build_index_type (NULL_TREE);
}
- if (array_parm_vla_unspec_p)
- {
- /* C99 6.7.5.2p4 */
- if (decl_context == TYPENAME)
- warning (0, "%<[*]%> not in a declaration");
- size_varies = true;
- }
-
/* Complain about arrays of incomplete types. */
if (!COMPLETE_TYPE_P (type))
{
@@ -7527,6 +7537,22 @@ grokdeclarator (const struct c_declarator *declarator,
type = c_build_array_type (type, itype);
}
+ if (array_parm_vla_unspec_p)
+ {
+ /* C99 6.7.5.2p4 */
+ if (decl_context == TYPENAME)
+ warning (0, "%<[*]%> not in a declaration");
+ else if (decl_context != GENERIC_ASSOC
+ && decl_context != PARM
+ && decl_context != FIELD)
+ {
+ error ("%<[*]%> not allowed in other than function prototype scope "
+ "or generic association");
+ type = error_mark_node;
+ }
+ size_varies = true;
+ }
+
if (type != error_mark_node)
{
/* The GCC extension for zero-length arrays differs from
@@ -7898,7 +7924,7 @@ grokdeclarator (const struct c_declarator *declarator,
/* If this is a type name (such as, in a cast or sizeof),
compute the type and return it now. */
- if (decl_context == TYPENAME)
+ if (decl_context == TYPENAME || decl_context == GENERIC_ASSOC)
{
/* Note that the grammar rejects storage classes in typenames
and fields. */
diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc
index ea0294f..56fb0be 100644
--- a/gcc/c/c-parser.cc
+++ b/gcc/c/c-parser.cc
@@ -11240,7 +11240,7 @@ c_parser_generic_selection (c_parser *parser)
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
return error_expr;
}
- assoc.type = groktypename (type_name, NULL, NULL);
+ assoc.type = grokgenassoc (type_name);
if (assoc.type == error_mark_node)
{
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
@@ -15787,11 +15787,15 @@ c_parser_pragma (c_parser *parser, enum pragma_context context, bool *if_p,
gcc_assert (id != PRAGMA_NONE);
if (parser->omp_for_parse_state
&& parser->omp_for_parse_state->in_intervening_code
- && id >= PRAGMA_OMP__START_
- && id <= PRAGMA_OMP__LAST_)
- {
- error_at (input_location,
- "intervening code must not contain OpenMP directives");
+ && id >= PRAGMA_OMP__START_ && id <= PRAGMA_OMP__LAST_
+ /* Allow a safe subset of non-executable directives. See classification in
+ array c_omp_directives. */
+ && id != PRAGMA_OMP_METADIRECTIVE && id != PRAGMA_OMP_NOTHING
+ && id != PRAGMA_OMP_ASSUME && id != PRAGMA_OMP_ERROR)
+ {
+ error_at (
+ input_location,
+ "intervening code must not contain executable OpenMP directives");
parser->omp_for_parse_state->fail = true;
c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
return false;
@@ -29334,6 +29338,14 @@ c_parser_omp_error (c_parser *parser, enum pragma_context context)
"may only be used in compound statements");
return true;
}
+ if (parser->omp_for_parse_state
+ && parser->omp_for_parse_state->in_intervening_code)
+ {
+ error_at (loc, "%<#pragma omp error%> with %<at(execution)%> clause "
+ "may not be used in intervening code");
+ parser->omp_for_parse_state->fail = true;
+ return true;
+ }
tree fndecl
= builtin_decl_explicit (severity_fatal ? BUILT_IN_GOMP_ERROR
: BUILT_IN_GOMP_WARNING);
@@ -29480,6 +29492,7 @@ c_parser_omp_assumption_clauses (c_parser *parser, bool is_assume)
directive[1],
directive[2]);
if (dir
+ && dir->id != PRAGMA_OMP_END
&& (dir->kind == C_OMP_DIR_DECLARATIVE
|| dir->kind == C_OMP_DIR_INFORMATIONAL
|| dir->kind == C_OMP_DIR_META))
@@ -29863,6 +29876,17 @@ c_parser_omp_metadirective (c_parser *parser, bool *if_p)
}
c_parser_skip_to_pragma_eol (parser);
+ /* If only one selector matches and it evaluates to 'omp nothing', no need to
+ proceed. */
+ if (ctxs.length () == 1)
+ {
+ tree ctx = ctxs[0];
+ if (ctx == NULL_TREE
+ || (omp_context_selector_matches (ctx, NULL_TREE, false) == 1
+ && directive_tokens[0].pragma_kind == PRAGMA_OMP_NOTHING))
+ return;
+ }
+
if (!default_seen)
{
/* Add a default clause that evaluates to 'omp nothing'. */
@@ -29943,7 +29967,7 @@ c_parser_omp_metadirective (c_parser *parser, bool *if_p)
if (standalone_body == NULL_TREE)
{
standalone_body = push_stmt_list ();
- c_parser_statement (parser, if_p);
+ c_parser_statement (parser, if_p); // TODO skip this
standalone_body = pop_stmt_list (standalone_body);
}
else
diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h
index 162add0..f367cda 100644
--- a/gcc/c/c-tree.h
+++ b/gcc/c/c-tree.h
@@ -713,6 +713,7 @@ extern struct c_arg_info *get_parm_info (bool, tree);
extern tree grokfield (location_t, struct c_declarator *,
struct c_declspecs *, tree, tree *, tree *);
extern tree groktypename (struct c_type_name *, tree *, bool *);
+extern tree grokgenassoc (struct c_type_name *);
extern tree grokparm (const struct c_parm *, tree *);
extern tree implicitly_declare (location_t, tree);
extern void keep_next_level (void);