aboutsummaryrefslogtreecommitdiff
path: root/gcc/c/c-parser.cc
diff options
context:
space:
mode:
authorJulian Brown <julian@codesourcery.com>2021-11-15 02:23:49 -0800
committerJulian Brown <julian@codesourcery.com>2024-01-11 23:42:30 +0000
commitb5476e4c881b0d2bfbbfb84ee38d791123acf8e1 (patch)
treeb7ee968932cad31e8c6dd021f72dfcf40fcbda30 /gcc/c/c-parser.cc
parent61b493f17e6fea5a0fb45b6a050259ca326c13a7 (diff)
downloadgcc-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.cc155
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)