aboutsummaryrefslogtreecommitdiff
path: root/gcc/c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@gcc.gnu.org>2016-09-02 20:38:07 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2016-09-02 20:38:07 +0200
commit9dc5773f4b529dd0fefffaf2a2bf9b9ff0195edd (patch)
tree4e53b18a2fda99a485292dfd9bf30c8fbd9145b7 /gcc/c
parentc65236d682789b6a33510aaebfd7e83fe0f30d1a (diff)
downloadgcc-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/ChangeLog29
-rw-r--r--gcc/c/c-objc-common.h6
-rw-r--r--gcc/c/c-parser.c125
-rw-r--r--gcc/c/c-tree.h1
-rw-r--r--gcc/c/c-typeck.c121
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