aboutsummaryrefslogtreecommitdiff
path: root/gcc/c/c-parser.cc
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2023-06-21 11:04:04 -0700
committerIan Lance Taylor <iant@golang.org>2023-06-21 11:04:04 -0700
commit97e31a0a2a2d2273687fcdb4e5416aab1a2186e1 (patch)
treed5c1cae4de436a0fe54a5f0a2a197d309f3d654c /gcc/c/c-parser.cc
parent6612f4f8cb9b0d5af18ec69ad04e56debc3e6ced (diff)
parent577223aebc7acdd31e62b33c1682fe54a622ae27 (diff)
downloadgcc-97e31a0a2a2d2273687fcdb4e5416aab1a2186e1.zip
gcc-97e31a0a2a2d2273687fcdb4e5416aab1a2186e1.tar.gz
gcc-97e31a0a2a2d2273687fcdb4e5416aab1a2186e1.tar.bz2
Merge from trunk revision 577223aebc7acdd31e62b33c1682fe54a622ae27.
Diffstat (limited to 'gcc/c/c-parser.cc')
-rw-r--r--gcc/c/c-parser.cc201
1 files changed, 162 insertions, 39 deletions
diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc
index 21bc316..24a6eb6 100644
--- a/gcc/c/c-parser.cc
+++ b/gcc/c/c-parser.cc
@@ -1541,7 +1541,7 @@ static void c_parser_static_assert_declaration_no_semi (c_parser *);
static void c_parser_static_assert_declaration (c_parser *);
static struct c_typespec c_parser_enum_specifier (c_parser *);
static struct c_typespec c_parser_struct_or_union_specifier (c_parser *);
-static tree c_parser_struct_declaration (c_parser *);
+static tree c_parser_struct_declaration (c_parser *, tree *);
static struct c_typespec c_parser_typeof_specifier (c_parser *);
static tree c_parser_alignas_specifier (c_parser *);
static struct c_declarator *c_parser_direct_declarator (c_parser *, bool,
@@ -2263,6 +2263,9 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
if (!handled_assume)
pedwarn (here, 0, "empty declaration");
}
+ /* We still have to evaluate size expressions. */
+ if (specs->expr)
+ add_stmt (fold_convert (void_type_node, specs->expr));
c_parser_consume_token (parser);
if (oacc_routine_data)
c_finish_oacc_routine (oacc_routine_data, NULL_TREE, false);
@@ -3179,7 +3182,19 @@ c_parser_declspecs (c_parser *parser, struct c_declspecs *specs,
attrs_ok = true;
if (kind == C_ID_ID)
{
- error_at (loc, "unknown type name %qE", value);
+ auto_diagnostic_group d;
+ name_hint hint = lookup_name_fuzzy (value, FUZZY_LOOKUP_TYPENAME,
+ loc);
+ if (const char *suggestion = hint.suggestion ())
+ {
+ gcc_rich_location richloc (loc);
+ richloc.add_fixit_replace (suggestion);
+ error_at (&richloc,
+ "unknown type name %qE; did you mean %qs?",
+ value, suggestion);
+ }
+ else
+ error_at (loc, "unknown type name %qE", value);
t.kind = ctsk_typedef;
t.spec = error_mark_node;
}
@@ -3782,6 +3797,7 @@ c_parser_struct_or_union_specifier (c_parser *parser)
so we'll be minimizing the number of node traversals required
by chainon. */
tree contents;
+ tree expr = NULL;
timevar_push (TV_PARSE_STRUCT);
contents = NULL_TREE;
c_parser_consume_token (parser);
@@ -3843,7 +3859,7 @@ c_parser_struct_or_union_specifier (c_parser *parser)
}
/* Parse some comma-separated declarations, but not the
trailing semicolon if any. */
- decls = c_parser_struct_declaration (parser);
+ decls = c_parser_struct_declaration (parser, &expr);
contents = chainon (decls, contents);
/* If no semicolon follows, either we have a parse error or
are at the end of the struct or union and should
@@ -3874,7 +3890,7 @@ c_parser_struct_or_union_specifier (c_parser *parser)
chainon (attrs, postfix_attrs)),
struct_info);
ret.kind = ctsk_tagdef;
- ret.expr = NULL_TREE;
+ ret.expr = expr;
ret.expr_const_operands = true;
ret.has_enum_type_specifier = false;
timevar_pop (TV_PARSE_STRUCT);
@@ -3936,7 +3952,7 @@ c_parser_struct_or_union_specifier (c_parser *parser)
expressions will be diagnosed as non-constant. */
static tree
-c_parser_struct_declaration (c_parser *parser)
+c_parser_struct_declaration (c_parser *parser, tree *expr)
{
struct c_declspecs *specs;
tree prefix_attrs;
@@ -3949,7 +3965,7 @@ c_parser_struct_declaration (c_parser *parser)
tree decl;
ext = disable_extension_diagnostics ();
c_parser_consume_token (parser);
- decl = c_parser_struct_declaration (parser);
+ decl = c_parser_struct_declaration (parser, expr);
restore_extension_diagnostics (ext);
return decl;
}
@@ -3995,7 +4011,7 @@ c_parser_struct_declaration (c_parser *parser)
ret = grokfield (c_parser_peek_token (parser)->location,
build_id_declarator (NULL_TREE), specs,
- NULL_TREE, &attrs);
+ NULL_TREE, &attrs, expr);
if (ret)
decl_attributes (&ret, attrs, 0);
}
@@ -4056,7 +4072,7 @@ c_parser_struct_declaration (c_parser *parser)
if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
postfix_attrs = c_parser_gnu_attributes (parser);
d = grokfield (c_parser_peek_token (parser)->location,
- declarator, specs, width, &all_prefix_attrs);
+ declarator, specs, width, &all_prefix_attrs, expr);
decl_attributes (&d, chainon (postfix_attrs,
all_prefix_attrs), 0);
DECL_CHAIN (d) = decls;
@@ -5677,11 +5693,14 @@ c_parser_initializer (c_parser *parser, tree decl)
{
struct c_expr ret;
location_t loc = c_parser_peek_token (parser)->location;
- if (decl != error_mark_node && C_DECL_VARIABLE_SIZE (decl))
- error_at (loc,
- "variable-sized object may not be initialized except "
- "with an empty initializer");
ret = c_parser_expr_no_commas (parser, NULL);
+ if (decl != error_mark_node && C_DECL_VARIABLE_SIZE (decl))
+ {
+ error_at (loc,
+ "variable-sized object may not be initialized except "
+ "with an empty initializer");
+ ret.set_error ();
+ }
/* This is handled mostly by gimplify.cc, but we have to deal with
not warning about int x = x; as it is a GCC extension to turn off
this warning but only if warn_init_self is zero. */
@@ -11729,7 +11748,7 @@ c_parser_objc_class_instance_variables (c_parser *parser)
}
/* Parse some comma-separated declarations. */
- decls = c_parser_struct_declaration (parser);
+ decls = c_parser_struct_declaration (parser, NULL);
if (decls == NULL)
{
/* There is a syntax error. We want to skip the offending
@@ -12868,7 +12887,7 @@ c_parser_objc_at_property_declaration (c_parser *parser)
/* 'properties' is the list of properties that we read. Usually a
single one, but maybe more (eg, in "@property int a, b, c;" there
are three). */
- tree properties = c_parser_struct_declaration (parser);
+ tree properties = c_parser_struct_declaration (parser, NULL);
if (properties == error_mark_node)
c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
@@ -14932,6 +14951,13 @@ c_parser_omp_clause_defaultmap (c_parser *parser, tree list)
goto invalid_behavior;
break;
+ case 'p':
+ if (strcmp ("present", p) == 0)
+ behavior = OMP_CLAUSE_DEFAULTMAP_PRESENT;
+ else
+ goto invalid_behavior;
+ break;
+
case 't':
if (strcmp ("tofrom", p) == 0)
behavior = OMP_CLAUSE_DEFAULTMAP_TOFROM;
@@ -15727,7 +15753,7 @@ c_parser_omp_clause_reduction (c_parser *parser, enum omp_clause_code kind,
OMP_CLAUSE_REDUCTION_INSCAN (c) = 1;
if (code == ERROR_MARK
|| !(INTEGRAL_TYPE_P (type)
- || TREE_CODE (type) == REAL_TYPE
+ || SCALAR_FLOAT_TYPE_P (type)
|| TREE_CODE (type) == COMPLEX_TYPE))
OMP_CLAUSE_REDUCTION_PLACEHOLDER (c)
= c_omp_reduction_lookup (reduc_id,
@@ -17102,6 +17128,7 @@ c_parser_omp_clause_map (c_parser *parser, tree list)
int always_modifier = 0;
int close_modifier = 0;
+ int present_modifier = 0;
for (int pos = 1; pos < map_kind_pos; ++pos)
{
c_token *tok = c_parser_peek_token (parser);
@@ -17133,11 +17160,20 @@ c_parser_omp_clause_map (c_parser *parser, tree list)
}
close_modifier++;
}
+ else if (strcmp ("present", p) == 0)
+ {
+ if (present_modifier)
+ {
+ c_parser_error (parser, "too many %<present%> modifiers");
+ parens.skip_until_found_close (parser);
+ return list;
+ }
+ present_modifier++;
+ }
else
{
- c_parser_error (parser, "%<#pragma omp target%> with "
- "modifier other than %<always%> or "
- "%<close%> on %<map%> clause");
+ c_parser_error (parser, "%<map%> clause with map-type modifier other "
+ "than %<always%>, %<close%> or %<present%>");
parens.skip_until_found_close (parser);
return list;
}
@@ -17149,14 +17185,25 @@ c_parser_omp_clause_map (c_parser *parser, tree list)
&& c_parser_peek_2nd_token (parser)->type == CPP_COLON)
{
const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
+ int always_present_modifier = always_modifier && present_modifier;
+
if (strcmp ("alloc", p) == 0)
- kind = GOMP_MAP_ALLOC;
+ kind = present_modifier ? GOMP_MAP_PRESENT_ALLOC : GOMP_MAP_ALLOC;
else if (strcmp ("to", p) == 0)
- kind = always_modifier ? GOMP_MAP_ALWAYS_TO : GOMP_MAP_TO;
+ kind = (always_present_modifier ? GOMP_MAP_ALWAYS_PRESENT_TO
+ : present_modifier ? GOMP_MAP_PRESENT_TO
+ : always_modifier ? GOMP_MAP_ALWAYS_TO
+ : GOMP_MAP_TO);
else if (strcmp ("from", p) == 0)
- kind = always_modifier ? GOMP_MAP_ALWAYS_FROM : GOMP_MAP_FROM;
+ kind = (always_present_modifier ? GOMP_MAP_ALWAYS_PRESENT_FROM
+ : present_modifier ? GOMP_MAP_PRESENT_FROM
+ : always_modifier ? GOMP_MAP_ALWAYS_FROM
+ : GOMP_MAP_FROM);
else if (strcmp ("tofrom", p) == 0)
- kind = always_modifier ? GOMP_MAP_ALWAYS_TOFROM : GOMP_MAP_TOFROM;
+ kind = (always_present_modifier ? GOMP_MAP_ALWAYS_PRESENT_TOFROM
+ : present_modifier ? GOMP_MAP_PRESENT_TOFROM
+ : always_modifier ? GOMP_MAP_ALWAYS_TOFROM
+ : GOMP_MAP_TOFROM);
else if (strcmp ("release", p) == 0)
kind = GOMP_MAP_RELEASE;
else if (strcmp ("delete", p) == 0)
@@ -17412,21 +17459,42 @@ c_parser_omp_clause_device_type (c_parser *parser, tree list)
}
/* OpenMP 4.0:
- to ( variable-list ) */
+ from ( variable-list )
+ to ( variable-list )
+
+ OpenMP 5.1:
+ from ( [present :] variable-list )
+ to ( [present :] variable-list ) */
static tree
-c_parser_omp_clause_to (c_parser *parser, tree list)
+c_parser_omp_clause_from_to (c_parser *parser, enum omp_clause_code kind,
+ tree list)
{
- return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_TO, list, true);
-}
+ location_t loc = c_parser_peek_token (parser)->location;
+ matching_parens parens;
+ if (!parens.require_open (parser))
+ return list;
-/* OpenMP 4.0:
- from ( variable-list ) */
+ bool present = false;
+ c_token *token = c_parser_peek_token (parser);
-static tree
-c_parser_omp_clause_from (c_parser *parser, tree list)
-{
- return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_FROM, list, true);
+ if (token->type == CPP_NAME
+ && strcmp (IDENTIFIER_POINTER (token->value), "present") == 0
+ && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
+ {
+ present = true;
+ c_parser_consume_token (parser);
+ c_parser_consume_token (parser);
+ }
+
+ tree nl = c_parser_omp_variable_list (parser, loc, kind, list);
+ parens.skip_until_found_close (parser);
+
+ if (present)
+ for (tree c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
+ OMP_CLAUSE_MOTION_PRESENT (c) = 1;
+
+ return nl;
}
/* OpenMP 4.0:
@@ -17685,7 +17753,7 @@ c_parser_oacc_all_clauses (c_parser *parser, omp_clause_mask mask,
c_name, clauses);
break;
default:
- c_parser_error (parser, "expected %<#pragma acc%> clause");
+ c_parser_error (parser, "expected an OpenACC clause");
goto saw_error;
}
@@ -17933,11 +18001,13 @@ c_parser_omp_all_clauses (c_parser *parser, omp_clause_mask mask,
clauses = nl;
}
else
- clauses = c_parser_omp_clause_to (parser, clauses);
+ clauses = c_parser_omp_clause_from_to (parser, OMP_CLAUSE_TO,
+ clauses);
c_name = "to";
break;
case PRAGMA_OMP_CLAUSE_FROM:
- clauses = c_parser_omp_clause_from (parser, clauses);
+ clauses = c_parser_omp_clause_from_to (parser, OMP_CLAUSE_FROM,
+ clauses);
c_name = "from";
break;
case PRAGMA_OMP_CLAUSE_UNIFORM:
@@ -18043,7 +18113,7 @@ c_parser_omp_all_clauses (c_parser *parser, omp_clause_mask mask,
c_name = "enter";
break;
default:
- c_parser_error (parser, "expected %<#pragma omp%> clause");
+ c_parser_error (parser, "expected an OpenMP clause");
goto saw_error;
}
@@ -20112,6 +20182,7 @@ c_parser_omp_scan_loop_body (c_parser *parser, bool open_brace_parsed)
tree substmt;
location_t loc;
tree clauses = NULL_TREE;
+ bool found_scan = false;
loc = c_parser_peek_token (parser)->location;
if (!open_brace_parsed
@@ -20122,7 +20193,15 @@ c_parser_omp_scan_loop_body (c_parser *parser, bool open_brace_parsed)
return;
}
- substmt = c_parser_omp_structured_block_sequence (parser, PRAGMA_OMP_SCAN);
+ if (c_parser_peek_token (parser)->pragma_kind != PRAGMA_OMP_SCAN)
+ substmt = c_parser_omp_structured_block_sequence (parser, PRAGMA_OMP_SCAN);
+ else
+ {
+ warning_at (c_parser_peek_token (parser)->location, 0,
+ "%<#pragma omp scan%> with zero preceding executable "
+ "statements");
+ substmt = build_empty_stmt (loc);
+ }
substmt = build2 (OMP_SCAN, void_type_node, substmt, NULL_TREE);
SET_EXPR_LOCATION (substmt, loc);
add_stmt (substmt);
@@ -20131,6 +20210,7 @@ c_parser_omp_scan_loop_body (c_parser *parser, bool open_brace_parsed)
if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_OMP_SCAN)
{
enum omp_clause_code clause = OMP_CLAUSE_ERROR;
+ found_scan = true;
c_parser_consume_pragma (parser);
@@ -20160,7 +20240,15 @@ c_parser_omp_scan_loop_body (c_parser *parser, bool open_brace_parsed)
error ("expected %<#pragma omp scan%>");
clauses = c_finish_omp_clauses (clauses, C_ORT_OMP);
- substmt = c_parser_omp_structured_block_sequence (parser, PRAGMA_NONE);
+ if (!c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
+ substmt = c_parser_omp_structured_block_sequence (parser, PRAGMA_NONE);
+ else
+ {
+ if (found_scan)
+ warning_at (loc, 0, "%<#pragma omp scan%> with zero succeeding "
+ "executable statements");
+ substmt = build_empty_stmt (loc);
+ }
substmt = build2 (OMP_SCAN, void_type_node, substmt, clauses);
SET_EXPR_LOCATION (substmt, loc);
add_stmt (substmt);
@@ -21743,11 +21831,18 @@ c_parser_omp_target_data (location_t loc, c_parser *parser, bool *if_p)
{
case GOMP_MAP_TO:
case GOMP_MAP_ALWAYS_TO:
+ case GOMP_MAP_PRESENT_TO:
+ case GOMP_MAP_ALWAYS_PRESENT_TO:
case GOMP_MAP_FROM:
case GOMP_MAP_ALWAYS_FROM:
+ case GOMP_MAP_PRESENT_FROM:
+ case GOMP_MAP_ALWAYS_PRESENT_FROM:
case GOMP_MAP_TOFROM:
case GOMP_MAP_ALWAYS_TOFROM:
+ case GOMP_MAP_PRESENT_TOFROM:
+ case GOMP_MAP_ALWAYS_PRESENT_TOFROM:
case GOMP_MAP_ALLOC:
+ case GOMP_MAP_PRESENT_ALLOC:
map_seen = 3;
break;
case GOMP_MAP_FIRSTPRIVATE_POINTER:
@@ -21893,7 +21988,10 @@ c_parser_omp_target_enter_data (location_t loc, c_parser *parser,
{
case GOMP_MAP_TO:
case GOMP_MAP_ALWAYS_TO:
+ case GOMP_MAP_PRESENT_TO:
+ case GOMP_MAP_ALWAYS_PRESENT_TO:
case GOMP_MAP_ALLOC:
+ case GOMP_MAP_PRESENT_ALLOC:
map_seen = 3;
break;
case GOMP_MAP_TOFROM:
@@ -21904,6 +22002,14 @@ c_parser_omp_target_enter_data (location_t loc, c_parser *parser,
OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_ALWAYS_TO);
map_seen = 3;
break;
+ case GOMP_MAP_PRESENT_TOFROM:
+ OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_PRESENT_TO);
+ map_seen = 3;
+ break;
+ case GOMP_MAP_ALWAYS_PRESENT_TOFROM:
+ OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_ALWAYS_PRESENT_TO);
+ map_seen = 3;
+ break;
case GOMP_MAP_FIRSTPRIVATE_POINTER:
case GOMP_MAP_ALWAYS_POINTER:
case GOMP_MAP_ATTACH_DETACH:
@@ -21991,6 +22097,8 @@ c_parser_omp_target_exit_data (location_t loc, c_parser *parser,
{
case GOMP_MAP_FROM:
case GOMP_MAP_ALWAYS_FROM:
+ case GOMP_MAP_PRESENT_FROM:
+ case GOMP_MAP_ALWAYS_PRESENT_FROM:
case GOMP_MAP_RELEASE:
case GOMP_MAP_DELETE:
map_seen = 3;
@@ -22003,6 +22111,14 @@ c_parser_omp_target_exit_data (location_t loc, c_parser *parser,
OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_ALWAYS_FROM);
map_seen = 3;
break;
+ case GOMP_MAP_PRESENT_TOFROM:
+ OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_PRESENT_FROM);
+ map_seen = 3;
+ break;
+ case GOMP_MAP_ALWAYS_PRESENT_TOFROM:
+ OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_ALWAYS_PRESENT_FROM);
+ map_seen = 3;
+ break;
case GOMP_MAP_FIRSTPRIVATE_POINTER:
case GOMP_MAP_ALWAYS_POINTER:
case GOMP_MAP_ATTACH_DETACH:
@@ -22248,11 +22364,18 @@ check_clauses:
{
case GOMP_MAP_TO:
case GOMP_MAP_ALWAYS_TO:
+ case GOMP_MAP_PRESENT_TO:
+ case GOMP_MAP_ALWAYS_PRESENT_TO:
case GOMP_MAP_FROM:
case GOMP_MAP_ALWAYS_FROM:
+ case GOMP_MAP_PRESENT_FROM:
+ case GOMP_MAP_ALWAYS_PRESENT_FROM:
case GOMP_MAP_TOFROM:
case GOMP_MAP_ALWAYS_TOFROM:
+ case GOMP_MAP_PRESENT_TOFROM:
+ case GOMP_MAP_ALWAYS_PRESENT_TOFROM:
case GOMP_MAP_ALLOC:
+ case GOMP_MAP_PRESENT_ALLOC:
case GOMP_MAP_FIRSTPRIVATE_POINTER:
case GOMP_MAP_ALWAYS_POINTER:
case GOMP_MAP_ATTACH_DETACH:
@@ -23272,7 +23395,7 @@ c_parser_omp_declare_reduction (c_parser *parser, enum pragma_context context)
if (type == error_mark_node)
;
else if ((INTEGRAL_TYPE_P (type)
- || TREE_CODE (type) == REAL_TYPE
+ || SCALAR_FLOAT_TYPE_P (type)
|| TREE_CODE (type) == COMPLEX_TYPE)
&& orig_reduc_id == NULL_TREE)
error_at (loc, "predeclared arithmetic type in "