diff options
author | Julian Brown <julian@codesourcery.com> | 2021-11-15 02:23:49 -0800 |
---|---|---|
committer | Julian Brown <julian@codesourcery.com> | 2024-01-11 23:42:30 +0000 |
commit | b5476e4c881b0d2bfbbfb84ee38d791123acf8e1 (patch) | |
tree | b7ee968932cad31e8c6dd021f72dfcf40fcbda30 /gcc/c/c-parser.cc | |
parent | 61b493f17e6fea5a0fb45b6a050259ca326c13a7 (diff) | |
download | gcc-b5476e4c881b0d2bfbbfb84ee38d791123acf8e1.zip gcc-b5476e4c881b0d2bfbbfb84ee38d791123acf8e1.tar.gz gcc-b5476e4c881b0d2bfbbfb84ee38d791123acf8e1.tar.bz2 |
OpenMP: lvalue parsing for map/to/from clauses (C)
This patch adds support for parsing general lvalues ("locator list item
types") for OpenMP "map", "to" and "from" clauses to the C front-end,
similar to the previously-posted patch for C++. Such syntax is permitted
for OpenMP 5.0 and above. It was previously posted for mainline here:
https://gcc.gnu.org/pipermail/gcc-patches/2022-December/609038.html
and for the og13 branch here:
https://gcc.gnu.org/pipermail/gcc-patches/2023-June/623355.html
2024-01-11 Julian Brown <julian@codesourcery.com>
gcc/c-family/
* c-pretty-print.cc (c_pretty_printer::postfix_expression,
c_pretty_printer::expression): Add OMP_ARRAY_SECTION support.
gcc/c/
* c-parser.cc (c_parser_braced_init, c_parser_conditional_expression):
Don't allow OpenMP array section.
(c_parser_postfix_expression): Don't allow array section in statement
expression.
(c_parser_postfix_expression_after_primary): Add support for OpenMP
array section parsing.
(c_parser_expr_list): Don't allow OpenMP array section here.
(c_parser_omp_variable_list): Change ALLOW_DEREF parameter to
MAP_LVALUE. Support parsing of general lvalues in "map", "to" and
"from" clauses.
(c_parser_omp_var_list_parens): Change ALLOW_DEREF parameter to
MAP_LVALUE. Update call to c_parser_omp_variable_list.
(c_parser_oacc_data_clause): Update calls to
c_parser_omp_var_list_parens.
(c_parser_omp_clause_reduction): Use OMP_ARRAY_SECTION tree node
instead of TREE_LIST for array sections.
(c_parser_omp_target): Allow GOMP_MAP_ATTACH.
* c-tree.h (c_omp_array_section_p): Add extern declaration.
(build_omp_array_section): Add prototype.
* c-typeck.cc (c_omp_array_section_p): Add flag.
(mark_exp_read): Support OMP_ARRAY_SECTION.
(build_omp_array_section): Add function.
(build_external_ref): Tweak error path for OpenMP array sections.
(handle_omp_array_sections_1): Use OMP_ARRAY_SECTION tree code instead
of TREE_LIST. Handle more kinds of expressions.
(c_oacc_check_attachments): Use OMP_ARRAY_SECTION instead of TREE_LIST
for array sections.
(c_finish_omp_clauses): Use OMP_ARRAY_SECTION instead of TREE_LIST.
Check for supported expression types.
gcc/testsuite/
* gcc.dg/gomp/bad-array-section-c-1.c: New test.
* gcc.dg/gomp/bad-array-section-c-2.c: New test.
* gcc.dg/gomp/bad-array-section-c-3.c: New test.
* gcc.dg/gomp/bad-array-section-c-4.c: New test.
* gcc.dg/gomp/bad-array-section-c-5.c: New test.
* gcc.dg/gomp/bad-array-section-c-6.c: New test.
* gcc.dg/gomp/bad-array-section-c-7.c: New test.
* gcc.dg/gomp/bad-array-section-c-8.c: New test.
libgomp/
* libgomp.texi: C/C++ lvalues are supported now for map/to/from.
* testsuite/libgomp.c-c++-common/ind-base-4.c: New test.
* testsuite/libgomp.c-c++-common/unary-ptr-1.c: New test.
Diffstat (limited to 'gcc/c/c-parser.cc')
-rw-r--r-- | gcc/c/c-parser.cc | 155 |
1 files changed, 139 insertions, 16 deletions
diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc index 878f323..c31349d 100644 --- a/gcc/c/c-parser.cc +++ b/gcc/c/c-parser.cc @@ -6146,6 +6146,8 @@ c_parser_braced_init (c_parser *parser, tree type, bool nested_p, location_t brace_loc = c_parser_peek_token (parser)->location; gcc_obstack_init (&braced_init_obstack); gcc_assert (c_parser_next_token_is (parser, CPP_OPEN_BRACE)); + bool save_c_omp_array_section_p = c_omp_array_section_p; + c_omp_array_section_p = false; matching_braces braces; braces.consume_open (parser); if (nested_p) @@ -6184,6 +6186,7 @@ c_parser_braced_init (c_parser *parser, tree type, bool nested_p, break; } } + c_omp_array_section_p = save_c_omp_array_section_p; c_token *next_tok = c_parser_peek_token (parser); if (next_tok->type != CPP_CLOSE_BRACE) { @@ -9149,6 +9152,7 @@ c_parser_conditional_expression (c_parser *parser, struct c_expr *after, { struct c_expr cond, exp1, exp2, ret; location_t start, cond_loc, colon_loc; + bool save_c_omp_array_section_p = c_omp_array_section_p; gcc_assert (!after || c_dialect_objc ()); @@ -9156,6 +9160,7 @@ c_parser_conditional_expression (c_parser *parser, struct c_expr *after, if (c_parser_next_token_is_not (parser, CPP_QUERY)) return cond; + c_omp_array_section_p = false; if (cond.value != error_mark_node) start = cond.get_start (); else @@ -9208,6 +9213,7 @@ c_parser_conditional_expression (c_parser *parser, struct c_expr *after, ret.set_error (); ret.original_code = ERROR_MARK; ret.original_type = NULL; + c_omp_array_section_p = save_c_omp_array_section_p; return ret; } { @@ -9254,6 +9260,7 @@ c_parser_conditional_expression (c_parser *parser, struct c_expr *after, } set_c_expr_source_range (&ret, start, exp2.get_finish ()); ret.m_decimal = 0; + c_omp_array_section_p = save_c_omp_array_section_p; return ret; } @@ -10705,6 +10712,7 @@ c_parser_postfix_expression (c_parser *parser) /* A statement expression. */ tree stmt; location_t brace_loc; + bool save_c_omp_array_section_p = c_omp_array_section_p; c_parser_consume_token (parser); brace_loc = c_parser_peek_token (parser)->location; c_parser_consume_token (parser); @@ -10721,6 +10729,7 @@ c_parser_postfix_expression (c_parser *parser) expr.set_error (); break; } + c_omp_array_section_p = false; stmt = c_begin_stmt_expr (); c_parser_compound_statement_nostart (parser); location_t close_loc = c_parser_peek_token (parser)->location; @@ -10731,6 +10740,7 @@ c_parser_postfix_expression (c_parser *parser) expr.value = c_finish_stmt_expr (brace_loc, stmt); set_c_expr_source_range (&expr, loc, close_loc); mark_exp_read (expr.value); + c_omp_array_section_p = save_c_omp_array_section_p; } else { @@ -12480,7 +12490,7 @@ c_parser_postfix_expression_after_primary (c_parser *parser, struct c_expr expr) { struct c_expr orig_expr; - tree ident, idx; + tree ident, idx, len; location_t sizeof_arg_loc[6], comp_loc; tree sizeof_arg[6]; unsigned int literal_zero_mask; @@ -12499,12 +12509,29 @@ c_parser_postfix_expression_after_primary (c_parser *parser, case CPP_OPEN_SQUARE: /* Array reference. */ c_parser_consume_token (parser); - idx = c_parser_expression (parser).value; + idx = len = NULL_TREE; + if (!c_omp_array_section_p + || c_parser_next_token_is_not (parser, CPP_COLON)) + idx = c_parser_expression (parser).value; + + if (c_omp_array_section_p + && c_parser_next_token_is (parser, CPP_COLON)) + { + c_parser_consume_token (parser); + if (c_parser_next_token_is_not (parser, CPP_CLOSE_SQUARE)) + len = c_parser_expression (parser).value; + + expr.value = build_omp_array_section (op_loc, expr.value, idx, + len); + } + else + expr.value = build_array_ref (op_loc, expr.value, idx); + c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>"); + start = expr.get_start (); finish = parser->tokens_buf[0].location; - expr.value = build_array_ref (op_loc, expr.value, idx); set_c_expr_source_range (&expr, start, finish); expr.original_code = ERROR_MARK; expr.original_type = NULL; @@ -12829,6 +12856,8 @@ c_parser_expr_list (c_parser *parser, bool convert_p, bool fold_p, vec<tree, va_gc> *orig_types; struct c_expr expr; unsigned int idx = 0; + bool save_c_omp_array_section_p = c_omp_array_section_p; + c_omp_array_section_p = false; ret = make_tree_vector (); if (p_orig_types == NULL) @@ -12882,6 +12911,7 @@ c_parser_expr_list (c_parser *parser, bool convert_p, bool fold_p, } if (orig_types) *p_orig_types = orig_types; + c_omp_array_section_p = save_c_omp_array_section_p; return ret; } @@ -15126,7 +15156,7 @@ static tree c_parser_omp_variable_list (c_parser *parser, location_t clause_loc, enum omp_clause_code kind, tree list, - bool allow_deref = false) + bool map_lvalue = false) { auto_vec<omp_dim> dims; bool array_section_p; @@ -15137,6 +15167,8 @@ c_parser_omp_variable_list (c_parser *parser, while (1) { + tree t = NULL_TREE; + if (kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY) { if (c_parser_next_token_is_not (parser, CPP_NAME) @@ -15217,8 +15249,96 @@ c_parser_omp_variable_list (c_parser *parser, parser->tokens = tokens.address (); parser->tokens_avail = tokens.length (); } + else if (map_lvalue + && (kind == OMP_CLAUSE_MAP + || kind == OMP_CLAUSE_TO + || kind == OMP_CLAUSE_FROM)) + { + location_t loc = c_parser_peek_token (parser)->location; + bool save_c_omp_array_section_p = c_omp_array_section_p; + c_omp_array_section_p = true; + c_expr expr = c_parser_expr_no_commas (parser, NULL); + if (expr.value != error_mark_node) + mark_exp_read (expr.value); + c_omp_array_section_p = save_c_omp_array_section_p; + tree decl = expr.value; + + /* This code rewrites a parsed expression containing various tree + codes used to represent array accesses into a more uniform nest of + OMP_ARRAY_SECTION nodes before it is processed by + c-typeck.cc:handle_omp_array_sections_1. It might be more + efficient to move this logic to that function instead, analysing + the parsed expression directly rather than this preprocessed + form. (See also equivalent code in cp/parser.cc, + cp/semantics.cc). */ + dims.truncate (0); + if (TREE_CODE (decl) == OMP_ARRAY_SECTION) + { + while (TREE_CODE (decl) == OMP_ARRAY_SECTION) + { + tree low_bound = TREE_OPERAND (decl, 1); + tree length = TREE_OPERAND (decl, 2); + dims.safe_push (omp_dim (low_bound, length, loc, false)); + decl = TREE_OPERAND (decl, 0); + } - tree t = NULL_TREE; + while (TREE_CODE (decl) == ARRAY_REF + || TREE_CODE (decl) == INDIRECT_REF + || TREE_CODE (decl) == COMPOUND_EXPR) + { + if (TREE_CODE (decl) == COMPOUND_EXPR) + { + decl = TREE_OPERAND (decl, 1); + STRIP_NOPS (decl); + } + else if (TREE_CODE (decl) == INDIRECT_REF) + { + dims.safe_push (omp_dim (integer_zero_node, + integer_one_node, loc, true)); + decl = TREE_OPERAND (decl, 0); + } + else /* ARRAY_REF. */ + { + tree index = TREE_OPERAND (decl, 1); + dims.safe_push (omp_dim (index, integer_one_node, loc, + true)); + decl = TREE_OPERAND (decl, 0); + } + } + + for (int i = dims.length () - 1; i >= 0; i--) + decl = build_omp_array_section (loc, decl, dims[i].low_bound, + dims[i].length); + } + else if (TREE_CODE (decl) == INDIRECT_REF) + { + /* Turn indirection of a pointer "*foo" into "foo[0:1]". */ + decl = TREE_OPERAND (decl, 0); + STRIP_NOPS (decl); + + decl = build_omp_array_section (loc, decl, integer_zero_node, + integer_one_node); + } + else if (TREE_CODE (decl) == ARRAY_REF) + { + tree idx = TREE_OPERAND (decl, 1); + + decl = TREE_OPERAND (decl, 0); + STRIP_NOPS (decl); + + decl = build_omp_array_section (loc, decl, idx, integer_one_node); + } + else if (TREE_CODE (decl) == NON_LVALUE_EXPR + || CONVERT_EXPR_P (decl)) + decl = TREE_OPERAND (decl, 0); + + tree u = build_omp_clause (clause_loc, kind); + OMP_CLAUSE_DECL (u) = decl; + OMP_CLAUSE_CHAIN (u) = list; + list = u; + + goto next_item; + } if (c_parser_next_token_is (parser, CPP_NAME) && c_parser_peek_token (parser)->id_kind == C_ID_ID) @@ -15269,8 +15389,7 @@ c_parser_omp_variable_list (c_parser *parser, case OMP_CLAUSE_TO: start_component_ref: while (c_parser_next_token_is (parser, CPP_DOT) - || (allow_deref - && c_parser_next_token_is (parser, CPP_DEREF))) + || c_parser_next_token_is (parser, CPP_DEREF)) { location_t op_loc = c_parser_peek_token (parser)->location; location_t arrow_loc = UNKNOWN_LOCATION; @@ -15371,9 +15490,7 @@ c_parser_omp_variable_list (c_parser *parser, || kind == OMP_CLAUSE_TO) && !array_section_p && (c_parser_next_token_is (parser, CPP_DOT) - || (allow_deref - && c_parser_next_token_is (parser, - CPP_DEREF)))) + || c_parser_next_token_is (parser, CPP_DEREF))) { for (unsigned i = 0; i < dims.length (); i++) { @@ -15385,7 +15502,9 @@ c_parser_omp_variable_list (c_parser *parser, } else for (unsigned i = 0; i < dims.length (); i++) - t = tree_cons (dims[i].low_bound, dims[i].length, t); + t = build_omp_array_section (clause_loc, t, + dims[i].low_bound, + dims[i].length); } if ((kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY) @@ -15433,6 +15552,8 @@ c_parser_omp_variable_list (c_parser *parser, parser->tokens = saved_tokens; parser->tokens_avail = tokens_avail; } + + next_item: if (c_parser_next_token_is_not (parser, CPP_COMMA)) break; @@ -15449,7 +15570,7 @@ c_parser_omp_variable_list (c_parser *parser, static tree c_parser_omp_var_list_parens (c_parser *parser, enum omp_clause_code kind, - tree list, bool allow_deref = false) + tree list, bool map_lvalue = false) { /* The clauses location. */ location_t loc = c_parser_peek_token (parser)->location; @@ -15470,7 +15591,7 @@ c_parser_omp_var_list_parens (c_parser *parser, enum omp_clause_code kind, matching_parens parens; if (parens.require_open (parser)) { - list = c_parser_omp_variable_list (parser, loc, kind, list, allow_deref); + list = c_parser_omp_variable_list (parser, loc, kind, list, map_lvalue); parens.skip_until_found_close (parser); } return list; @@ -15541,7 +15662,7 @@ c_parser_oacc_data_clause (c_parser *parser, pragma_omp_clause c_kind, gcc_unreachable (); } tree nl, c; - nl = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_MAP, list, true); + nl = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_MAP, list, false); for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c)) OMP_CLAUSE_SET_MAP_KIND (c, kind); @@ -17221,13 +17342,15 @@ c_parser_omp_clause_reduction (c_parser *parser, enum omp_clause_code kind, for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c)) { tree d = OMP_CLAUSE_DECL (c), type; - if (TREE_CODE (d) != TREE_LIST) + if (TREE_CODE (d) != OMP_ARRAY_SECTION) type = TREE_TYPE (d); else { int cnt = 0; tree t; - for (t = d; TREE_CODE (t) == TREE_LIST; t = TREE_CHAIN (t)) + for (t = d; + TREE_CODE (t) == OMP_ARRAY_SECTION; + t = TREE_OPERAND (t, 0)) cnt++; type = TREE_TYPE (t); while (cnt > 0) |