aboutsummaryrefslogtreecommitdiff
path: root/gcc/c
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
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')
-rw-r--r--gcc/c/c-parser.cc155
-rw-r--r--gcc/c/c-tree.h2
-rw-r--r--gcc/c/c-typeck.cc109
3 files changed, 229 insertions, 37 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)
diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h
index 1823151..cf29534 100644
--- a/gcc/c/c-tree.h
+++ b/gcc/c/c-tree.h
@@ -737,6 +737,7 @@ extern int in_alignof;
extern int in_sizeof;
extern int in_typeof;
extern bool c_in_omp_for;
+extern bool c_omp_array_section_p;
extern tree c_last_sizeof_arg;
extern location_t c_last_sizeof_loc;
@@ -777,6 +778,7 @@ extern tree composite_type (tree, tree);
extern tree build_component_ref (location_t, tree, tree, location_t,
location_t);
extern tree build_array_ref (location_t, tree, tree);
+extern tree build_omp_array_section (location_t, tree, tree, tree);
extern tree build_external_ref (location_t, tree, bool, tree *);
extern void pop_maybe_used (bool);
extern struct c_expr c_expr_sizeof_expr (location_t, struct c_expr);
diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
index 2b90fa7..774dc1b 100644
--- a/gcc/c/c-typeck.cc
+++ b/gcc/c/c-typeck.cc
@@ -76,6 +76,9 @@ int in_typeof;
/* True when parsing OpenMP loop expressions. */
bool c_in_omp_for;
+/* True when parsing OpenMP map clause. */
+bool c_omp_array_section_p;
+
/* The argument of last parsed sizeof expression, only to be tested
if expr.original_code == SIZEOF_EXPR. */
tree c_last_sizeof_arg;
@@ -1987,6 +1990,13 @@ mark_exp_read (tree exp)
case C_MAYBE_CONST_EXPR:
mark_exp_read (TREE_OPERAND (exp, 1));
break;
+ case OMP_ARRAY_SECTION:
+ mark_exp_read (TREE_OPERAND (exp, 0));
+ if (TREE_OPERAND (exp, 1))
+ mark_exp_read (TREE_OPERAND (exp, 1));
+ if (TREE_OPERAND (exp, 2))
+ mark_exp_read (TREE_OPERAND (exp, 2));
+ break;
default:
break;
}
@@ -2899,6 +2909,53 @@ build_array_ref (location_t loc, tree array, tree index)
return ret;
}
}
+
+/* Build an OpenMP array section reference, creating an exact type for the
+ resulting expression based on the element type and bounds if possible. If
+ we have variable bounds, create an incomplete array type for the result
+ instead. */
+
+tree
+build_omp_array_section (location_t loc, tree array, tree index, tree length)
+{
+ tree type = TREE_TYPE (array);
+ gcc_assert (type);
+
+ tree sectype, eltype = TREE_TYPE (type);
+
+ /* It's not an array or pointer type. Just reuse the type of the original
+ expression as the type of the array section (an error will be raised
+ anyway, later). */
+ if (eltype == NULL_TREE || error_operand_p (eltype))
+ sectype = TREE_TYPE (array);
+ else
+ {
+ tree idxtype = NULL_TREE;
+
+ if (index != NULL_TREE
+ && length != NULL_TREE
+ && INTEGRAL_TYPE_P (TREE_TYPE (index))
+ && INTEGRAL_TYPE_P (TREE_TYPE (length)))
+ {
+ tree low = fold_convert (sizetype, index);
+ tree high = fold_convert (sizetype, length);
+ high = size_binop (PLUS_EXPR, low, high);
+ high = size_binop (MINUS_EXPR, high, size_one_node);
+ idxtype = build_range_type (sizetype, low, high);
+ }
+ else if ((index == NULL_TREE || integer_zerop (index))
+ && length != NULL_TREE
+ && INTEGRAL_TYPE_P (TREE_TYPE (length)))
+ idxtype = build_index_type (length);
+
+ gcc_assert (!error_operand_p (idxtype));
+
+ sectype = build_array_type (eltype, idxtype);
+ }
+
+ return build3_loc (loc, OMP_ARRAY_SECTION, sectype, array, index, length);
+}
+
/* Build an external reference to identifier ID. FUN indicates
whether this will be used for a function call. LOC is the source
@@ -2938,7 +2995,11 @@ build_external_ref (location_t loc, tree id, bool fun, tree *type)
return error_mark_node;
}
- if (TREE_TYPE (ref) == error_mark_node)
+ /* For an OpenMP map clause, we can get better diagnostics for decls with
+ unmappable types if we return the decl with an error_mark_node type,
+ rather than returning error_mark_node for the decl itself. */
+ if (TREE_TYPE (ref) == error_mark_node
+ && !c_omp_array_section_p)
return error_mark_node;
if (TREE_UNAVAILABLE (ref))
@@ -13762,7 +13823,7 @@ handle_omp_array_sections_1 (tree c, tree t, vec<tree> &types,
{
tree ret, low_bound, length, type;
bool openacc = (ort & C_ORT_ACC) != 0;
- if (TREE_CODE (t) != TREE_LIST)
+ if (TREE_CODE (t) != OMP_ARRAY_SECTION)
{
if (error_operand_p (t))
return error_mark_node;
@@ -13787,7 +13848,9 @@ handle_omp_array_sections_1 (tree c, tree t, vec<tree> &types,
t = ai.unconverted_ref_origin ();
if (t == error_mark_node)
return error_mark_node;
- if (!VAR_P (t) && TREE_CODE (t) != PARM_DECL)
+ if (!VAR_P (t)
+ && (ort == C_ORT_ACC || !EXPR_P (t))
+ && TREE_CODE (t) != PARM_DECL)
{
if (DECL_P (t))
error_at (OMP_CLAUSE_LOCATION (c),
@@ -13835,14 +13898,14 @@ handle_omp_array_sections_1 (tree c, tree t, vec<tree> &types,
return ret;
}
- ret = handle_omp_array_sections_1 (c, TREE_CHAIN (t), types,
+ ret = handle_omp_array_sections_1 (c, TREE_OPERAND (t, 0), types,
maybe_zero_len, first_non_one, ort);
if (ret == error_mark_node || ret == NULL_TREE)
return ret;
type = TREE_TYPE (ret);
- low_bound = TREE_PURPOSE (t);
- length = TREE_VALUE (t);
+ low_bound = TREE_OPERAND (t, 1);
+ length = TREE_OPERAND (t, 2);
if (low_bound == error_mark_node || length == error_mark_node)
return error_mark_node;
@@ -14035,7 +14098,7 @@ handle_omp_array_sections_1 (tree c, tree t, vec<tree> &types,
tree lb = save_expr (low_bound);
if (lb != low_bound)
{
- TREE_PURPOSE (t) = lb;
+ TREE_OPERAND (t, 1) = lb;
low_bound = lb;
}
}
@@ -14066,14 +14129,15 @@ handle_omp_array_sections_1 (tree c, tree t, vec<tree> &types,
array-section-subscript, the array section could be non-contiguous. */
if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND
&& OMP_CLAUSE_CODE (c) != OMP_CLAUSE_AFFINITY
- && TREE_CODE (TREE_CHAIN (t)) == TREE_LIST)
+ && TREE_CODE (TREE_OPERAND (t, 0)) == OMP_ARRAY_SECTION)
{
/* If any prior dimension has a non-one length, then deem this
array section as non-contiguous. */
- for (tree d = TREE_CHAIN (t); TREE_CODE (d) == TREE_LIST;
- d = TREE_CHAIN (d))
+ for (tree d = TREE_OPERAND (t, 0);
+ TREE_CODE (d) == OMP_ARRAY_SECTION;
+ d = TREE_OPERAND (d, 0))
{
- tree d_length = TREE_VALUE (d);
+ tree d_length = TREE_OPERAND (d, 2);
if (d_length == NULL_TREE || !integer_onep (d_length))
{
error_at (OMP_CLAUSE_LOCATION (c),
@@ -14096,7 +14160,7 @@ handle_omp_array_sections_1 (tree c, tree t, vec<tree> &types,
tree lb = save_expr (low_bound);
if (lb != low_bound)
{
- TREE_PURPOSE (t) = lb;
+ TREE_OPERAND (t, 1) = lb;
low_bound = lb;
}
ret = build_array_ref (OMP_CLAUSE_LOCATION (c), ret, low_bound);
@@ -14159,10 +14223,10 @@ handle_omp_array_sections (tree &c, enum c_omp_region_type ort)
maybe_zero_len = true;
for (i = num, t = OMP_CLAUSE_DECL (c); i > 0;
- t = TREE_CHAIN (t))
+ t = TREE_OPERAND (t, 0))
{
- tree low_bound = TREE_PURPOSE (t);
- tree length = TREE_VALUE (t);
+ tree low_bound = TREE_OPERAND (t, 1);
+ tree length = TREE_OPERAND (t, 2);
i--;
if (low_bound
@@ -14587,8 +14651,8 @@ c_oacc_check_attachments (tree c)
{
tree t = OMP_CLAUSE_DECL (c);
- while (TREE_CODE (t) == TREE_LIST)
- t = TREE_CHAIN (t);
+ while (TREE_CODE (t) == OMP_ARRAY_SECTION)
+ t = TREE_OPERAND (t, 0);
if (TREE_CODE (TREE_TYPE (t)) != POINTER_TYPE)
{
@@ -14696,7 +14760,7 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
case OMP_CLAUSE_TASK_REDUCTION:
need_implicitly_determined = true;
t = OMP_CLAUSE_DECL (c);
- if (TREE_CODE (t) == TREE_LIST)
+ if (TREE_CODE (t) == OMP_ARRAY_SECTION)
{
if (handle_omp_array_sections (c, ort))
{
@@ -15317,7 +15381,7 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
}
else
last_iterators = NULL_TREE;
- if (TREE_CODE (t) == TREE_LIST)
+ if (TREE_CODE (t) == OMP_ARRAY_SECTION)
{
if (handle_omp_array_sections (c, ort))
remove = true;
@@ -15427,7 +15491,7 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
auto_vec<omp_addr_token *, 10> addr_tokens;
t = OMP_CLAUSE_DECL (c);
- if (TREE_CODE (t) == TREE_LIST)
+ if (TREE_CODE (t) == OMP_ARRAY_SECTION)
{
grp_start_p = pc;
grp_sentinel = OMP_CLAUSE_CHAIN (c);
@@ -15597,6 +15661,9 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
if (!VAR_P (t) && TREE_CODE (t) != PARM_DECL)
{
+ if (ort != C_ORT_ACC && EXPR_P (t))
+ break;
+
error_at (OMP_CLAUSE_LOCATION (c),
"%qE is not a variable in %qs clause", t,
omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
@@ -15827,7 +15894,7 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
case OMP_CLAUSE_HAS_DEVICE_ADDR:
t = OMP_CLAUSE_DECL (c);
- if (TREE_CODE (t) == TREE_LIST)
+ if (TREE_CODE (t) == OMP_ARRAY_SECTION)
{
if (handle_omp_array_sections (c, ort))
remove = true;