diff options
author | Jakub Jelinek <jakub@gcc.gnu.org> | 2016-09-02 20:38:07 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2016-09-02 20:38:07 +0200 |
commit | 9dc5773f4b529dd0fefffaf2a2bf9b9ff0195edd (patch) | |
tree | 4e53b18a2fda99a485292dfd9bf30c8fbd9145b7 /gcc/c | |
parent | c65236d682789b6a33510aaebfd7e83fe0f30d1a (diff) | |
download | gcc-9dc5773f4b529dd0fefffaf2a2bf9b9ff0195edd.zip gcc-9dc5773f4b529dd0fefffaf2a2bf9b9ff0195edd.tar.gz gcc-9dc5773f4b529dd0fefffaf2a2bf9b9ff0195edd.tar.bz2 |
re PR c/65467 ([libgomp] sorry, unimplemented: '_Atomic' with OpenMP)
PR c/65467
* gimplify.c (gimplify_adjust_omp_clauses_1): Diagnose implicit
map and firstprivate clauses on target construct for _Atomic
qualified decls.
(gimplify_adjust_omp_clauses): Diagnose explicit firstprivate clauses
on target construct for _Atomic qualified decls.
* omp-low.c (use_pointer_for_field): Return true for _Atomic qualified
decls.
* omp-simd-clone.c (simd_clone_clauses_extract): Warn and give up for
_Atomic qualified arguments not mentioned in uniform clause.
c/
* c-parser.c (c_parser_declspecs): Don't sorry about _Atomic if
flag_openmp.
(c_parser_omp_variable_list): Use convert_lvalue_to_rvalue
instead of mark_exp_read on low_bound/length expression.
(c_parser_omp_clause_num_gangs, c_parser_omp_clause_num_threads,
c_parser_omp_clause_num_tasks, c_parser_omp_clause_grainsize,
c_parser_omp_clause_priority, c_parser_omp_clause_hint,
c_parser_omp_clause_num_workers, c_parser_oacc_shape_clause,
c_parser_oacc_clause_tile, c_parser_omp_clause_schedule,
c_parser_omp_clause_vector_length, c_parser_omp_clause_num_teams,
c_parser_omp_clause_thread_limit, c_parser_omp_clause_aligned,
c_parser_omp_clause_linear, c_parser_omp_clause_safelen,
c_parser_omp_clause_simdlen, c_parser_omp_clause_device,
c_parser_omp_clause_dist_schedule): Use convert_lvalue_to_rvalue
instead of mark_expr_read.
(c_parser_omp_declare_reduction): Reject _Atomic qualified types.
* c-objc-common.h (LANG_HOOKS_OMP_CLAUSE_COPY_CTOR,
LANG_HOOKS_OMP_CLAUSE_ASSIGN_OP): Redefine.
* c-tree.h (c_omp_clause_copy_ctor): New prototype.
* c-typeck.c (handle_omp_array_sections_1): Diagnose _Atomic qualified
array section bases outside of depend clause, for depend clause
use convert_lvalue_to_rvalue on the base.
(c_finish_omp_clauses): Reject _Atomic qualified vars in reduction,
linear, aligned, map, to and from clauses.
(c_omp_clause_copy_ctor): New function.
c-family/
* c-omp.c (c_finish_omp_atomic): Reject _Atomic qualified expressions.
(c_finish_omp_for): Reject _Atomic qualified iterators.
testsuite/
* gcc.dg/gomp/_Atomic-1.c: New test.
* gcc.dg/gomp/_Atomic-2.c: New test.
* gcc.dg/gomp/_Atomic-3.c: New test.
* gcc.dg/gomp/_Atomic-4.c: New test.
* gcc.dg/gomp/_Atomic-5.c: New test.
From-SVN: r239964
Diffstat (limited to 'gcc/c')
-rw-r--r-- | gcc/c/ChangeLog | 29 | ||||
-rw-r--r-- | gcc/c/c-objc-common.h | 6 | ||||
-rw-r--r-- | gcc/c/c-parser.c | 125 | ||||
-rw-r--r-- | gcc/c/c-tree.h | 1 | ||||
-rw-r--r-- | gcc/c/c-typeck.c | 121 |
5 files changed, 234 insertions, 48 deletions
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 6b00f9a..d10dd6d 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,32 @@ +2016-09-02 Jakub Jelinek <jakub@redhat.com> + + PR c/65467 + * c-parser.c (c_parser_declspecs): Don't sorry about _Atomic if + flag_openmp. + (c_parser_omp_variable_list): Use convert_lvalue_to_rvalue + instead of mark_exp_read on low_bound/length expression. + (c_parser_omp_clause_num_gangs, c_parser_omp_clause_num_threads, + c_parser_omp_clause_num_tasks, c_parser_omp_clause_grainsize, + c_parser_omp_clause_priority, c_parser_omp_clause_hint, + c_parser_omp_clause_num_workers, c_parser_oacc_shape_clause, + c_parser_oacc_clause_tile, c_parser_omp_clause_schedule, + c_parser_omp_clause_vector_length, c_parser_omp_clause_num_teams, + c_parser_omp_clause_thread_limit, c_parser_omp_clause_aligned, + c_parser_omp_clause_linear, c_parser_omp_clause_safelen, + c_parser_omp_clause_simdlen, c_parser_omp_clause_device, + c_parser_omp_clause_dist_schedule): Use convert_lvalue_to_rvalue + instead of mark_expr_read. + (c_parser_omp_declare_reduction): Reject _Atomic qualified types. + * c-objc-common.h (LANG_HOOKS_OMP_CLAUSE_COPY_CTOR, + LANG_HOOKS_OMP_CLAUSE_ASSIGN_OP): Redefine. + * c-tree.h (c_omp_clause_copy_ctor): New prototype. + * c-typeck.c (handle_omp_array_sections_1): Diagnose _Atomic qualified + array section bases outside of depend clause, for depend clause + use convert_lvalue_to_rvalue on the base. + (c_finish_omp_clauses): Reject _Atomic qualified vars in reduction, + linear, aligned, map, to and from clauses. + (c_omp_clause_copy_ctor): New function. + 2016-09-01 Marek Polacek <polacek@redhat.com> PR c/7652 diff --git a/gcc/c/c-objc-common.h b/gcc/c/c-objc-common.h index ccb4903..14554ac 100644 --- a/gcc/c/c-objc-common.h +++ b/gcc/c/c-objc-common.h @@ -100,6 +100,12 @@ along with GCC; see the file COPYING3. If not see #undef LANG_HOOKS_OMP_PREDETERMINED_SHARING #define LANG_HOOKS_OMP_PREDETERMINED_SHARING c_omp_predetermined_sharing +#undef LANG_HOOKS_OMP_CLAUSE_COPY_CTOR +#define LANG_HOOKS_OMP_CLAUSE_COPY_CTOR c_omp_clause_copy_ctor + +#undef LANG_HOOKS_OMP_CLAUSE_ASSIGN_OP +#define LANG_HOOKS_OMP_CLAUSE_ASSIGN_OP c_omp_clause_copy_ctor + #undef LANG_HOOKS_TREE_INLINING_VAR_MOD_TYPE_P #define LANG_HOOKS_TREE_INLINING_VAR_MOD_TYPE_P c_vla_unspec_p #endif /* GCC_C_OBJC_COMMON */ diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index 0581899..0aba51c 100644 --- a/gcc/c/c-parser.c +++ b/gcc/c/c-parser.c @@ -2600,10 +2600,6 @@ c_parser_declspecs (c_parser *parser, struct c_declspecs *specs, and objc_types_are_equivalent may also need updates. */ if (c_dialect_objc ()) sorry ("%<_Atomic%> in Objective-C"); - /* C parser handling of OpenMP constructs needs checking for - correct lvalue-to-rvalue conversions. */ - if (flag_openmp) - sorry ("%<_Atomic%> with OpenMP"); if (flag_isoc99) pedwarn_c99 (loc, OPT_Wpedantic, "ISO C99 does not support the %<_Atomic%> qualifier"); @@ -10718,8 +10714,12 @@ c_parser_omp_variable_list (c_parser *parser, c_parser_consume_token (parser); if (!c_parser_next_token_is (parser, CPP_COLON)) { - low_bound = c_parser_expression (parser).value; - mark_exp_read (low_bound); + location_t expr_loc + = c_parser_peek_token (parser)->location; + c_expr expr = c_parser_expression (parser); + expr = convert_lvalue_to_rvalue (expr_loc, expr, + false, true); + low_bound = expr.value; } if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE)) length = integer_one_node; @@ -10734,8 +10734,12 @@ c_parser_omp_variable_list (c_parser *parser, } if (!c_parser_next_token_is (parser, CPP_CLOSE_SQUARE)) { - length = c_parser_expression (parser).value; - mark_exp_read (length); + location_t expr_loc + = c_parser_peek_token (parser)->location; + c_expr expr = c_parser_expression (parser); + expr = convert_lvalue_to_rvalue (expr_loc, expr, + false, true); + length = expr.value; } } /* Look for the closing `]'. */ @@ -11257,8 +11261,9 @@ c_parser_omp_clause_num_gangs (c_parser *parser, tree list) if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) { location_t expr_loc = c_parser_peek_token (parser)->location; - tree c, t = c_parser_expression (parser).value; - mark_exp_read (t); + c_expr expr = c_parser_expression (parser); + expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true); + tree c, t = expr.value; t = c_fully_fold (t, false, NULL); c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); @@ -11301,8 +11306,9 @@ c_parser_omp_clause_num_threads (c_parser *parser, tree list) if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) { location_t expr_loc = c_parser_peek_token (parser)->location; - tree c, t = c_parser_expression (parser).value; - mark_exp_read (t); + c_expr expr = c_parser_expression (parser); + expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true); + tree c, t = expr.value; t = c_fully_fold (t, false, NULL); c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); @@ -11345,8 +11351,9 @@ c_parser_omp_clause_num_tasks (c_parser *parser, tree list) if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) { location_t expr_loc = c_parser_peek_token (parser)->location; - tree c, t = c_parser_expression (parser).value; - mark_exp_read (t); + c_expr expr = c_parser_expression (parser); + expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true); + tree c, t = expr.value; t = c_fully_fold (t, false, NULL); c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); @@ -11389,8 +11396,9 @@ c_parser_omp_clause_grainsize (c_parser *parser, tree list) if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) { location_t expr_loc = c_parser_peek_token (parser)->location; - tree c, t = c_parser_expression (parser).value; - mark_exp_read (t); + c_expr expr = c_parser_expression (parser); + expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true); + tree c, t = expr.value; t = c_fully_fold (t, false, NULL); c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); @@ -11433,8 +11441,9 @@ c_parser_omp_clause_priority (c_parser *parser, tree list) if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) { location_t expr_loc = c_parser_peek_token (parser)->location; - tree c, t = c_parser_expression (parser).value; - mark_exp_read (t); + c_expr expr = c_parser_expression (parser); + expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true); + tree c, t = expr.value; t = c_fully_fold (t, false, NULL); c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); @@ -11477,8 +11486,10 @@ c_parser_omp_clause_hint (c_parser *parser, tree list) location_t hint_loc = c_parser_peek_token (parser)->location; if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) { - tree c, t = c_parser_expression (parser).value; - mark_exp_read (t); + location_t expr_loc = c_parser_peek_token (parser)->location; + c_expr expr = c_parser_expression (parser); + expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true); + tree c, t = expr.value; t = c_fully_fold (t, false, NULL); c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); @@ -11581,8 +11592,9 @@ c_parser_omp_clause_num_workers (c_parser *parser, tree list) if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) { location_t expr_loc = c_parser_peek_token (parser)->location; - tree c, t = c_parser_expression (parser).value; - mark_exp_read (t); + c_expr expr = c_parser_expression (parser); + expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true); + tree c, t = expr.value; t = c_fully_fold (t, false, NULL); c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); @@ -11703,11 +11715,12 @@ c_parser_oacc_shape_clause (c_parser *parser, omp_clause_code kind, } location_t expr_loc = c_parser_peek_token (parser)->location; - tree expr = c_parser_expr_no_commas (parser, NULL).value; + c_expr cexpr = c_parser_expr_no_commas (parser, NULL); + cexpr = convert_lvalue_to_rvalue (expr_loc, cexpr, false, true); + tree expr = cexpr.value; if (expr == error_mark_node) goto cleanup_error; - mark_exp_read (expr); expr = c_fully_fold (expr, false, NULL); /* Attempt to statically determine when the number isn't a @@ -11842,7 +11855,9 @@ c_parser_oacc_clause_tile (c_parser *parser, tree list) else { expr_loc = c_parser_peek_token (parser)->location; - expr = c_parser_expr_no_commas (parser, NULL).value; + c_expr cexpr = c_parser_expr_no_commas (parser, NULL); + cexpr = convert_lvalue_to_rvalue (expr_loc, cexpr, false, true); + expr = cexpr.value; if (expr == error_mark_node) { @@ -11857,7 +11872,6 @@ c_parser_oacc_clause_tile (c_parser *parser, tree list) return list; } - mark_exp_read (expr); expr = c_fully_fold (expr, false, NULL); /* Attempt to statically determine when expr isn't positive. */ @@ -12180,8 +12194,9 @@ c_parser_omp_clause_schedule (c_parser *parser, tree list) c_parser_consume_token (parser); here = c_parser_peek_token (parser)->location; - t = c_parser_expr_no_commas (parser, NULL).value; - mark_exp_read (t); + c_expr expr = c_parser_expr_no_commas (parser, NULL); + expr = convert_lvalue_to_rvalue (here, expr, false, true); + t = expr.value; t = c_fully_fold (t, false, NULL); if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_RUNTIME) @@ -12266,8 +12281,9 @@ c_parser_omp_clause_vector_length (c_parser *parser, tree list) if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) { location_t expr_loc = c_parser_peek_token (parser)->location; - tree c, t = c_parser_expression (parser).value; - mark_exp_read (t); + c_expr expr = c_parser_expression (parser); + expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true); + tree c, t = expr.value; t = c_fully_fold (t, false, NULL); c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); @@ -12369,8 +12385,9 @@ c_parser_omp_clause_num_teams (c_parser *parser, tree list) if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) { location_t expr_loc = c_parser_peek_token (parser)->location; - tree c, t = c_parser_expression (parser).value; - mark_exp_read (t); + c_expr expr = c_parser_expression (parser); + expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true); + tree c, t = expr.value; t = c_fully_fold (t, false, NULL); c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); @@ -12412,8 +12429,9 @@ c_parser_omp_clause_thread_limit (c_parser *parser, tree list) if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) { location_t expr_loc = c_parser_peek_token (parser)->location; - tree c, t = c_parser_expression (parser).value; - mark_exp_read (t); + c_expr expr = c_parser_expression (parser); + expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true); + tree c, t = expr.value; t = c_fully_fold (t, false, NULL); c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); @@ -12465,8 +12483,10 @@ c_parser_omp_clause_aligned (c_parser *parser, tree list) if (c_parser_next_token_is (parser, CPP_COLON)) { c_parser_consume_token (parser); - tree alignment = c_parser_expr_no_commas (parser, NULL).value; - mark_exp_read (alignment); + location_t expr_loc = c_parser_peek_token (parser)->location; + c_expr expr = c_parser_expr_no_commas (parser, NULL); + expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true); + tree alignment = expr.value; alignment = c_fully_fold (alignment, false, NULL); if (TREE_CODE (alignment) != INTEGER_CST || !INTEGRAL_TYPE_P (TREE_TYPE (alignment)) @@ -12528,8 +12548,10 @@ c_parser_omp_clause_linear (c_parser *parser, tree list, bool is_cilk_simd_fn) if (c_parser_next_token_is (parser, CPP_COLON)) { c_parser_consume_token (parser); - step = c_parser_expression (parser).value; - mark_exp_read (step); + location_t expr_loc = c_parser_peek_token (parser)->location; + c_expr expr = c_parser_expression (parser); + expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true); + step = expr.value; step = c_fully_fold (step, false, NULL); if (is_cilk_simd_fn && TREE_CODE (step) == PARM_DECL) { @@ -12569,8 +12591,10 @@ c_parser_omp_clause_safelen (c_parser *parser, tree list) if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) return list; - t = c_parser_expr_no_commas (parser, NULL).value; - mark_exp_read (t); + location_t expr_loc = c_parser_peek_token (parser)->location; + c_expr expr = c_parser_expr_no_commas (parser, NULL); + expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true); + t = expr.value; t = c_fully_fold (t, false, NULL); if (TREE_CODE (t) != INTEGER_CST || !INTEGRAL_TYPE_P (TREE_TYPE (t)) @@ -12605,8 +12629,10 @@ c_parser_omp_clause_simdlen (c_parser *parser, tree list) if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) return list; - t = c_parser_expr_no_commas (parser, NULL).value; - mark_exp_read (t); + location_t expr_loc = c_parser_peek_token (parser)->location; + c_expr expr = c_parser_expr_no_commas (parser, NULL); + expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true); + t = expr.value; t = c_fully_fold (t, false, NULL); if (TREE_CODE (t) != INTEGER_CST || !INTEGRAL_TYPE_P (TREE_TYPE (t)) @@ -12921,8 +12947,10 @@ c_parser_omp_clause_device (c_parser *parser, tree list) location_t clause_loc = c_parser_peek_token (parser)->location; if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) { - tree c, t = c_parser_expr_no_commas (parser, NULL).value; - mark_exp_read (t); + location_t expr_loc = c_parser_peek_token (parser)->location; + c_expr expr = c_parser_expr_no_commas (parser, NULL); + expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true); + tree c, t = expr.value; t = c_fully_fold (t, false, NULL); c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); @@ -12970,8 +12998,10 @@ c_parser_omp_clause_dist_schedule (c_parser *parser, tree list) { c_parser_consume_token (parser); - t = c_parser_expr_no_commas (parser, NULL).value; - mark_exp_read (t); + location_t expr_loc = c_parser_peek_token (parser)->location; + c_expr expr = c_parser_expr_no_commas (parser, NULL); + expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true); + t = expr.value; t = c_fully_fold (t, false, NULL); c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); } @@ -16876,6 +16906,9 @@ c_parser_omp_declare_reduction (c_parser *parser, enum pragma_context context) || TREE_CODE (type) == ARRAY_TYPE) error_at (loc, "function or array type in " "%<#pragma omp declare reduction%>"); + else if (TYPE_ATOMIC (type)) + error_at (loc, "%<_Atomic%> qualified type in " + "%<#pragma omp declare reduction%>"); else if (TYPE_QUALS_NO_ADDR_SPACE (type)) error_at (loc, "const, volatile or restrict qualified type in " "%<#pragma omp declare reduction%>"); diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h index 5a8ab6d..e8060f8 100644 --- a/gcc/c/c-tree.h +++ b/gcc/c/c-tree.h @@ -682,6 +682,7 @@ extern tree c_finish_transaction (location_t, tree, int); extern bool c_tree_equal (tree, tree); extern tree c_build_function_call_vec (location_t, vec<location_t>, tree, vec<tree, va_gc> *, vec<tree, va_gc> *); +extern tree c_omp_clause_copy_ctor (tree, tree, tree); /* Set to 0 at beginning of a function definition, set to 1 if a return statement that specifies a return value is seen. */ diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c index fc7a71e..d56c3d6 100644 --- a/gcc/c/c-typeck.c +++ b/gcc/c/c-typeck.c @@ -12072,6 +12072,13 @@ handle_omp_array_sections_1 (tree c, tree t, vec<tree> &types, if (error_operand_p (t)) return error_mark_node; ret = t; + if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND + && TYPE_ATOMIC (strip_array_types (TREE_TYPE (t)))) + { + error_at (OMP_CLAUSE_LOCATION (c), "%<_Atomic%> %qE in %qs clause", + t, omp_clause_code_name[OMP_CLAUSE_CODE (c)]); + return error_mark_node; + } if (TREE_CODE (t) == COMPONENT_REF && ort == C_ORT_OMP && (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP @@ -12109,13 +12116,35 @@ handle_omp_array_sections_1 (tree c, tree t, vec<tree> &types, return error_mark_node; } else if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND - && VAR_P (t) && DECL_THREAD_LOCAL_P (t)) + && TYPE_ATOMIC (TREE_TYPE (t))) + { + error_at (OMP_CLAUSE_LOCATION (c), "%<_Atomic%> %qD in %qs clause", + t, omp_clause_code_name[OMP_CLAUSE_CODE (c)]); + return error_mark_node; + } + else if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND + && VAR_P (t) + && DECL_THREAD_LOCAL_P (t)) { error_at (OMP_CLAUSE_LOCATION (c), "%qD is threadprivate variable in %qs clause", t, omp_clause_code_name[OMP_CLAUSE_CODE (c)]); return error_mark_node; } + if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND + && TYPE_ATOMIC (TREE_TYPE (t)) + && POINTER_TYPE_P (TREE_TYPE (t))) + { + /* If the array section is pointer based and the pointer + itself is _Atomic qualified, we need to atomically load + the pointer. */ + c_expr expr; + memset (&expr, 0, sizeof (expr)); + expr.value = ret; + expr = convert_lvalue_to_rvalue (OMP_CLAUSE_LOCATION (c), + expr, false, false); + ret = expr.value; + } return ret; } @@ -12675,7 +12704,7 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort) oacc_async = true; break; } - + for (pc = &clauses, c = clauses; c ; c = *pc) { bool remove = false; @@ -12750,6 +12779,13 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort) t = build2 (MEM_REF, atype, t, build_int_cst (ptype, 0)); OMP_CLAUSE_DECL (c) = t; } + if (TYPE_ATOMIC (type)) + { + error_at (OMP_CLAUSE_LOCATION (c), + "%<_Atomic%> %qE in %<reduction%> clause", t); + remove = true; + break; + } if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) == NULL_TREE && (FLOAT_TYPE_P (type) || TREE_CODE (type) == COMPLEX_TYPE)) @@ -12964,6 +13000,13 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort) remove = true; break; } + if (TYPE_ATOMIC (TREE_TYPE (t))) + { + error_at (OMP_CLAUSE_LOCATION (c), + "%<_Atomic%> %qD in %<linear%> clause", t); + remove = true; + break; + } } if (ort == C_ORT_OMP_DECLARE_SIMD) { @@ -13112,6 +13155,13 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort) "an array", t); remove = true; } + else if (TYPE_ATOMIC (TREE_TYPE (t))) + { + error_at (OMP_CLAUSE_LOCATION (c), + "%<_Atomic%> %qD in %<aligned%> clause", t); + remove = true; + break; + } else if (bitmap_bit_p (&aligned_head, DECL_UID (t))) { error_at (OMP_CLAUSE_LOCATION (c), @@ -13197,6 +13247,13 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort) omp_clause_code_name[OMP_CLAUSE_CODE (c)]); remove = true; } + else if (TYPE_ATOMIC (TREE_TYPE (t))) + { + error_at (OMP_CLAUSE_LOCATION (c), + "%<_Atomic%> %qE in %qs clause", t, + omp_clause_code_name[OMP_CLAUSE_CODE (c)]); + remove = true; + } while (TREE_CODE (t) == ARRAY_REF) t = TREE_OPERAND (t, 0); if (TREE_CODE (t) == COMPONENT_REF @@ -13251,6 +13308,13 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort) t, omp_clause_code_name[OMP_CLAUSE_CODE (c)]); remove = true; } + else if (TYPE_ATOMIC (TREE_TYPE (t))) + { + error_at (OMP_CLAUSE_LOCATION (c), + "%<_Atomic%> %qE in %qs clause", t, + omp_clause_code_name[OMP_CLAUSE_CODE (c)]); + remove = true; + } while (TREE_CODE (t) == COMPONENT_REF) { if (TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 0))) @@ -13304,6 +13368,15 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort) omp_clause_code_name[OMP_CLAUSE_CODE (c)]); remove = true; } + else if (TREE_TYPE (t) == error_mark_node) + remove = true; + else if (TYPE_ATOMIC (strip_array_types (TREE_TYPE (t)))) + { + error_at (OMP_CLAUSE_LOCATION (c), + "%<_Atomic%> %qE in %qs clause", t, + omp_clause_code_name[OMP_CLAUSE_CODE (c)]); + remove = true; + } else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER) { @@ -13644,6 +13717,50 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort) return clauses; } +/* Return code to initialize DST with a copy constructor from SRC. + C doesn't have copy constructors nor assignment operators, only for + _Atomic vars we need to perform __atomic_load from src into a temporary + followed by __atomic_store of the temporary to dst. */ + +tree +c_omp_clause_copy_ctor (tree clause, tree dst, tree src) +{ + if (!really_atomic_lvalue (dst) && !really_atomic_lvalue (src)) + return build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src); + + location_t loc = OMP_CLAUSE_LOCATION (clause); + tree type = TREE_TYPE (dst); + tree nonatomic_type = build_qualified_type (type, TYPE_UNQUALIFIED); + tree tmp = create_tmp_var (nonatomic_type); + tree tmp_addr = build_fold_addr_expr (tmp); + TREE_ADDRESSABLE (tmp) = 1; + TREE_NO_WARNING (tmp) = 1; + tree src_addr = build_fold_addr_expr (src); + tree dst_addr = build_fold_addr_expr (dst); + tree seq_cst = build_int_cst (integer_type_node, MEMMODEL_SEQ_CST); + vec<tree, va_gc> *params; + /* Expansion of a generic atomic load may require an addition + element, so allocate enough to prevent a resize. */ + vec_alloc (params, 4); + + /* Build __atomic_load (&src, &tmp, SEQ_CST); */ + tree fndecl = builtin_decl_explicit (BUILT_IN_ATOMIC_LOAD); + params->quick_push (src_addr); + params->quick_push (tmp_addr); + params->quick_push (seq_cst); + tree load = c_build_function_call_vec (loc, vNULL, fndecl, params, NULL); + + vec_alloc (params, 4); + + /* Build __atomic_store (&dst, &tmp, SEQ_CST); */ + fndecl = builtin_decl_explicit (BUILT_IN_ATOMIC_STORE); + params->quick_push (dst_addr); + params->quick_push (tmp_addr); + params->quick_push (seq_cst); + tree store = c_build_function_call_vec (loc, vNULL, fndecl, params, NULL); + return build2 (COMPOUND_EXPR, void_type_node, load, store); +} + /* Create a transaction node. */ tree |