diff options
author | Ian Lance Taylor <iant@golang.org> | 2023-06-21 11:04:04 -0700 |
---|---|---|
committer | Ian Lance Taylor <iant@golang.org> | 2023-06-21 11:04:04 -0700 |
commit | 97e31a0a2a2d2273687fcdb4e5416aab1a2186e1 (patch) | |
tree | d5c1cae4de436a0fe54a5f0a2a197d309f3d654c /gcc/c/c-parser.cc | |
parent | 6612f4f8cb9b0d5af18ec69ad04e56debc3e6ced (diff) | |
parent | 577223aebc7acdd31e62b33c1682fe54a622ae27 (diff) | |
download | gcc-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.cc | 201 |
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 " |