summaryrefslogtreecommitdiff
path: root/gcc/c
diff options
context:
space:
mode:
authorburnus <burnus@138bc75d-0d04-0410-961f-82ee72b054a4>2016-09-20 21:49:12 +0000
committerburnus <burnus@138bc75d-0d04-0410-961f-82ee72b054a4>2016-09-20 21:49:12 +0000
commitc9c81ef3c667aaa14c498a5449ec6d134b4b66ff (patch)
tree0ac440db6513ee01deb5e5dc6142769d1e5b7b2d /gcc/c
parent12cdcb9d74f55c165366ca1b1eeec013a0ce72ef (diff)
parent891196d7325e4c55d92d5ac5cfe7161c4f36c0ce (diff)
downloadgcc-fortran-dev.tar.gz
Merge from trunk (r239915 to r240230)fortran-dev
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/fortran-dev@240290 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/c')
-rw-r--r--gcc/c/ChangeLog82
-rw-r--r--gcc/c/c-array-notation.c4
-rw-r--r--gcc/c/c-decl.c2
-rw-r--r--gcc/c/c-lang.c3
-rw-r--r--gcc/c/c-objc-common.h6
-rw-r--r--gcc/c/c-parser.c146
-rw-r--r--gcc/c/c-tree.h1
-rw-r--r--gcc/c/c-typeck.c184
8 files changed, 334 insertions, 94 deletions
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog
index 3ac6648b45a..4c2fc5dda65 100644
--- a/gcc/c/ChangeLog
+++ b/gcc/c/ChangeLog
@@ -1,3 +1,77 @@
+2016-09-16 Marek Polacek <polacek@redhat.com>
+
+ * c-typeck.c (lvalue_p): Use true and false instead of 1 and 0.
+
+2016-09-14 Marek Polacek <polacek@redhat.com>
+
+ * c-array-notation.c (create_cmp_incr): Use false instead of 0.
+ (fix_array_notation_expr): Likewise.
+ * c-decl.c (finish_decl): Likewise.
+ * c-parser.c (c_parser_postfix_expression_after_primary): Likewise.
+ * c-typeck.c (array_to_pointer_conversion): Use true instead of 1.
+ (function_to_pointer_conversion): Use false instead of 0.
+ (convert_lvalue_to_rvalue): Likewise.
+ (parser_build_unary_op): Likewise.
+ (build_atomic_assign): Likewise.
+ (build_unary_op): Change nonconvert parameter type to bool, use
+ true/false instead of 1/0.
+ (build_binary_op): Use true instead of 1.
+
+2016-09-13 David Malcolm <dmalcolm@redhat.com>
+
+ * c-parser.c (c_parser_declaration_or_fndef): Update for renaming
+ of add_fixit_insert to add_fixit_insert_before.
+
+2016-09-13 Marek Polacek <polacek@redhat.com>
+
+ * c-typeck.c (build_unary_op): Rename FLAG parameter to NOCONVERT. Use
+ it.
+
+2016-09-12 Bernd Edlinger <bernd.edlinger@hotmail.de>
+
+ PR c++/77496
+ * c-parser.c (c_parser_conditional_expression): Pass the rightmost
+ COMPOUND_EXPR to warn_for_omitted_condop.
+
+2016-09-07 David Malcolm <dmalcolm@redhat.com>
+
+ * c-lang.c (LANG_HOOKS_GET_SUBSTRING_LOCATION): Use
+ c_get_substring_location for this new langhook.
+
+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
+ * c-typeck.c (composite_type): Add FALLTHRU comment.
+
2016-08-31 David Malcolm <dmalcolm@redhat.com>
* c-parser.c (c_parser_declaration_or_fndef): Add trailing space
@@ -244,7 +318,7 @@
* c-typeck.c (build_conditional_expr): Return error_mark_node if
c_common_type returns error_mark_node.
-2016-06-19 Martin Sebor <msebor@redhat.com>
+2016-06-19 Martin Sebor <msebor@redhat.com>
PR c/69507
* c-parser.c (c_parser_alignof_expression): Avoid diagnosing
@@ -1993,7 +2067,7 @@
* c-typeck.c (build_array_ref): Pass loc down to
warn_array_subscript_with_type_char.
-2014-12-20 Martin Uecker <uecker@eecs.berkeley.edu>
+2014-12-20 Martin Uecker <uecker@eecs.berkeley.edu>
* c-typeck.c: New behavious for pointers to arrays with qualifiers
(common-pointer-type): For pointers to arrays take qualifiers from
@@ -2315,7 +2389,7 @@
Likewise.
(c_parser_postfix_expression) <case RID_C99_FUNCTION_NAME>: Likewise.
-2014-08-10 Marek Polacek <polacek@redhat.com>
+2014-08-10 Marek Polacek <polacek@redhat.com>
PR c/51849
* c-decl.c (build_array_declarator): Remove check for !flag_isoc99.
@@ -2402,7 +2476,7 @@
function parameter.
2014-07-02 Jan Hubicka <hubicka@ucw.cz>
- Chen Gang <gang.chen.5i5j@gmail.com>
+ Chen Gang <gang.chen.5i5j@gmail.com>
* c-decl.c (duplicate_decls): CLear DECL_STRUCT_FUNCTION before
releasing symbol.
diff --git a/gcc/c/c-array-notation.c b/gcc/c/c-array-notation.c
index c7cf66a2c81..ce609112089 100644
--- a/gcc/c/c-array-notation.c
+++ b/gcc/c/c-array-notation.c
@@ -104,7 +104,7 @@ create_cmp_incr (location_t loc, vec<an_loop_parts> *node, size_t rank,
{
tree var = (*node)[ii].var;
tree length = an_info[0][ii].length;
- (*node)[ii].incr = build_unary_op (loc, POSTINCREMENT_EXPR, var, 0);
+ (*node)[ii].incr = build_unary_op (loc, POSTINCREMENT_EXPR, var, false);
(*node)[ii].cmp = build2 (LT_EXPR, boolean_type_node, var, length);
}
}
@@ -1088,7 +1088,7 @@ fix_array_notation_expr (location_t location, enum tree_code code,
arg = default_function_array_read_conversion (location, arg);
if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR)
- arg.value = build_unary_op (location, code, arg.value, 0);
+ arg.value = build_unary_op (location, code, arg.value, false);
else if (code == PREINCREMENT_EXPR || code == PREDECREMENT_EXPR)
arg = parser_build_unary_op (location, code, arg);
diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c
index 8f49c35237d..d15b8f89b0a 100644
--- a/gcc/c/c-decl.c
+++ b/gcc/c/c-decl.c
@@ -5102,7 +5102,7 @@ finish_decl (tree decl, location_t init_loc, tree init,
vec<tree, va_gc> *v;
/* Build "cleanup(&decl)" for the destructor. */
- cleanup = build_unary_op (input_location, ADDR_EXPR, decl, 0);
+ cleanup = build_unary_op (input_location, ADDR_EXPR, decl, false);
vec_alloc (v, 1);
v->quick_push (cleanup);
cleanup = c_build_function_call_vec (DECL_SOURCE_LOCATION (decl),
diff --git a/gcc/c/c-lang.c b/gcc/c/c-lang.c
index b26be6ad92c..b4096d064ee 100644
--- a/gcc/c/c-lang.c
+++ b/gcc/c/c-lang.c
@@ -43,6 +43,9 @@ enum c_language_kind c_language = clk_c;
#define LANG_HOOKS_RUN_LANG_SELFTESTS selftest::run_c_tests
#endif /* #if CHECKING_P */
+#undef LANG_HOOKS_GET_SUBSTRING_LOCATION
+#define LANG_HOOKS_GET_SUBSTRING_LOCATION c_get_substring_location
+
/* Each front end provides its own lang hook initializer. */
struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
diff --git a/gcc/c/c-objc-common.h b/gcc/c/c-objc-common.h
index ccb4903ee42..14554ace114 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 0581899e307..58424a9e8e5 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -1685,7 +1685,7 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
if (tag_exists_p (RECORD_TYPE, name))
{
/* This is not C++ with its implicit typedef. */
- richloc.add_fixit_insert ("struct ");
+ richloc.add_fixit_insert_before ("struct ");
error_at_rich_loc (&richloc,
"unknown type name %qE;"
" use %<struct%> keyword to refer to the type",
@@ -1693,7 +1693,7 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
}
else if (tag_exists_p (UNION_TYPE, name))
{
- richloc.add_fixit_insert ("union ");
+ richloc.add_fixit_insert_before ("union ");
error_at_rich_loc (&richloc,
"unknown type name %qE;"
" use %<union%> keyword to refer to the type",
@@ -1701,7 +1701,7 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
}
else if (tag_exists_p (ENUMERAL_TYPE, name))
{
- richloc.add_fixit_insert ("enum ");
+ richloc.add_fixit_insert_before ("enum ");
error_at_rich_loc (&richloc,
"unknown type name %qE;"
" use %<enum%> keyword to refer to the type",
@@ -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");
@@ -6429,14 +6425,17 @@ c_parser_conditional_expression (c_parser *parser, struct c_expr *after,
tree eptype = NULL_TREE;
middle_loc = c_parser_peek_token (parser)->location;
- pedwarn (middle_loc, OPT_Wpedantic,
+ pedwarn (middle_loc, OPT_Wpedantic,
"ISO C forbids omitting the middle term of a ?: expression");
- warn_for_omitted_condop (middle_loc, cond.value);
if (TREE_CODE (cond.value) == EXCESS_PRECISION_EXPR)
{
eptype = TREE_TYPE (cond.value);
cond.value = TREE_OPERAND (cond.value, 0);
}
+ tree e = cond.value;
+ while (TREE_CODE (e) == COMPOUND_EXPR)
+ e = TREE_OPERAND (e, 1);
+ warn_for_omitted_condop (middle_loc, e);
/* Make sure first operand is calculated only once. */
exp1.value = c_save_expr (default_conversion (cond.value));
if (eptype)
@@ -8479,8 +8478,8 @@ c_parser_postfix_expression_after_primary (c_parser *parser,
else
{
expr = default_function_array_read_conversion (expr_loc, expr);
- expr.value = build_unary_op (op_loc,
- POSTINCREMENT_EXPR, expr.value, 0);
+ expr.value = build_unary_op (op_loc, POSTINCREMENT_EXPR,
+ expr.value, false);
}
set_c_expr_source_range (&expr, start, finish);
expr.original_code = ERROR_MARK;
@@ -8498,8 +8497,8 @@ c_parser_postfix_expression_after_primary (c_parser *parser,
else
{
expr = default_function_array_read_conversion (expr_loc, expr);
- expr.value = build_unary_op (op_loc,
- POSTDECREMENT_EXPR, expr.value, 0);
+ expr.value = build_unary_op (op_loc, POSTDECREMENT_EXPR,
+ expr.value, false);
}
set_c_expr_source_range (&expr, start, finish);
expr.original_code = ERROR_MARK;
@@ -10718,8 +10717,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 +10737,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 +11264,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 +11309,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 +11354,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 +11399,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 +11444,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 +11489,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 +11595,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 +11718,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 +11858,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 +11875,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 +12197,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 +12284,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 +12388,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 +12432,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 +12486,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 +12551,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 +12594,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 +12632,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 +12950,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 +13001,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 +16909,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 5a8ab6df483..e8060f8b197 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 51940273d69..059ad1fc2e0 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -605,8 +605,8 @@ composite_type (tree t1, tree t2)
t1 = build_function_type (valtype, newargs);
t1 = qualify_type (t1, t2);
- /* ... falls through ... */
}
+ /* FALLTHRU */
default:
return build_type_attribute_variant (t1, attributes);
@@ -1880,7 +1880,7 @@ array_to_pointer_conversion (location_t loc, tree exp)
"is ill-formed in C++");
}
- adr = build_unary_op (loc, ADDR_EXPR, exp, 1);
+ adr = build_unary_op (loc, ADDR_EXPR, exp, true);
return convert (ptrtype, adr);
}
@@ -1897,7 +1897,7 @@ function_to_pointer_conversion (location_t loc, tree exp)
if (TREE_NO_WARNING (orig_exp))
TREE_NO_WARNING (exp) = 1;
- return build_unary_op (loc, ADDR_EXPR, exp, 0);
+ return build_unary_op (loc, ADDR_EXPR, exp, false);
}
/* Mark EXP as read, not just set, for set but not used -Wunused
@@ -2042,7 +2042,7 @@ convert_lvalue_to_rvalue (location_t loc, struct c_expr exp,
vec<tree, va_gc> *params;
tree nonatomic_type, tmp, tmp_addr, fndecl, func_call;
tree expr_type = TREE_TYPE (exp.value);
- tree expr_addr = build_unary_op (loc, ADDR_EXPR, exp.value, 0);
+ tree expr_addr = build_unary_op (loc, ADDR_EXPR, exp.value, false);
tree seq_cst = build_int_cst (integer_type_node, MEMMODEL_SEQ_CST);
gcc_assert (TYPE_ATOMIC (expr_type));
@@ -2055,7 +2055,7 @@ convert_lvalue_to_rvalue (location_t loc, struct c_expr exp,
create the VAL temp variable to hold the RHS. */
nonatomic_type = build_qualified_type (expr_type, TYPE_UNQUALIFIED);
tmp = create_tmp_var_raw (nonatomic_type);
- tmp_addr = build_unary_op (loc, ADDR_EXPR, tmp, 0);
+ tmp_addr = build_unary_op (loc, ADDR_EXPR, tmp, false);
TREE_ADDRESSABLE (tmp) = 1;
TREE_NO_WARNING (tmp) = 1;
@@ -3575,7 +3575,7 @@ parser_build_unary_op (location_t loc, enum tree_code code, struct c_expr arg)
}
else
{
- result.value = build_unary_op (loc, code, arg.value, 0);
+ result.value = build_unary_op (loc, code, arg.value, false);
if (TREE_OVERFLOW_P (result.value) && !TREE_OVERFLOW_P (arg.value))
overflow_warning (loc, result.value);
@@ -3872,7 +3872,7 @@ build_atomic_assign (location_t loc, tree lhs, enum tree_code modifycode,
tree loop_label, loop_decl, done_label, done_decl;
tree lhs_type = TREE_TYPE (lhs);
- tree lhs_addr = build_unary_op (loc, ADDR_EXPR, lhs, 0);
+ tree lhs_addr = build_unary_op (loc, ADDR_EXPR, lhs, false);
tree seq_cst = build_int_cst (integer_type_node, MEMMODEL_SEQ_CST);
tree rhs_type = TREE_TYPE (rhs);
@@ -3909,7 +3909,7 @@ build_atomic_assign (location_t loc, tree lhs, enum tree_code modifycode,
if (modifycode == NOP_EXPR)
{
/* Build __atomic_store (&lhs, &val, SEQ_CST) */
- rhs = build_unary_op (loc, ADDR_EXPR, val, 0);
+ rhs = build_unary_op (loc, ADDR_EXPR, val, false);
fndecl = builtin_decl_explicit (BUILT_IN_ATOMIC_STORE);
params->quick_push (lhs_addr);
params->quick_push (rhs);
@@ -4014,12 +4014,12 @@ build_atomic_assign (location_t loc, tree lhs, enum tree_code modifycode,
cas_loop:
/* Create the variables and labels required for the op= form. */
old = create_tmp_var_raw (nonatomic_lhs_type);
- old_addr = build_unary_op (loc, ADDR_EXPR, old, 0);
+ old_addr = build_unary_op (loc, ADDR_EXPR, old, false);
TREE_ADDRESSABLE (old) = 1;
TREE_NO_WARNING (old) = 1;
newval = create_tmp_var_raw (nonatomic_lhs_type);
- newval_addr = build_unary_op (loc, ADDR_EXPR, newval, 0);
+ newval_addr = build_unary_op (loc, ADDR_EXPR, newval, false);
TREE_ADDRESSABLE (newval) = 1;
TREE_NO_WARNING (newval) = 1;
@@ -4112,17 +4112,17 @@ cas_loop:
/* Construct and perhaps optimize a tree representation
for a unary operation. CODE, a tree_code, specifies the operation
and XARG is the operand.
- For any CODE other than ADDR_EXPR, FLAG nonzero suppresses
- the default promotions (such as from short to int).
- For ADDR_EXPR, the default promotions are not applied; FLAG nonzero
- allows non-lvalues; this is only used to handle conversion of non-lvalue
- arrays to pointers in C99.
+ For any CODE other than ADDR_EXPR, NOCONVERT suppresses the default
+ promotions (such as from short to int).
+ For ADDR_EXPR, the default promotions are not applied; NOCONVERT allows
+ non-lvalues; this is only used to handle conversion of non-lvalue arrays
+ to pointers in C99.
LOCATION is the location of the operator. */
tree
-build_unary_op (location_t location,
- enum tree_code code, tree xarg, int flag)
+build_unary_op (location_t location, enum tree_code code, tree xarg,
+ bool noconvert)
{
/* No default_conversion here. It causes trouble for ADDR_EXPR. */
tree arg = xarg;
@@ -4131,7 +4131,6 @@ build_unary_op (location_t location,
tree val;
tree ret = error_mark_node;
tree eptype = NULL_TREE;
- int noconvert = flag;
const char *invalid_op_diag;
bool int_operands;
@@ -4276,7 +4275,8 @@ build_unary_op (location_t location,
if (TREE_CODE (arg) == C_MAYBE_CONST_EXPR)
{
tree inner = build_unary_op (location, code,
- C_MAYBE_CONST_EXPR_EXPR (arg), flag);
+ C_MAYBE_CONST_EXPR_EXPR (arg),
+ noconvert);
if (inner == error_mark_node)
return error_mark_node;
ret = build2 (C_MAYBE_CONST_EXPR, TREE_TYPE (inner),
@@ -4324,9 +4324,11 @@ build_unary_op (location_t location,
if (!atomic_op)
{
arg = stabilize_reference (arg);
- real = build_unary_op (EXPR_LOCATION (arg), REALPART_EXPR, arg, 1);
- imag = build_unary_op (EXPR_LOCATION (arg), IMAGPART_EXPR, arg, 1);
- real = build_unary_op (EXPR_LOCATION (arg), code, real, 1);
+ real = build_unary_op (EXPR_LOCATION (arg), REALPART_EXPR, arg,
+ true);
+ imag = build_unary_op (EXPR_LOCATION (arg), IMAGPART_EXPR, arg,
+ true);
+ real = build_unary_op (EXPR_LOCATION (arg), code, real, true);
if (real == error_mark_node || imag == error_mark_node)
return error_mark_node;
ret = build2 (COMPLEX_EXPR, TREE_TYPE (arg),
@@ -4486,7 +4488,7 @@ build_unary_op (location_t location,
/* Anything not already handled and not a true memory reference
or a non-lvalue array is an error. */
- if (typecode != FUNCTION_TYPE && !flag
+ if (typecode != FUNCTION_TYPE && !noconvert
&& !lvalue_or_else (location, arg, lv_addressof))
return error_mark_node;
@@ -4495,7 +4497,8 @@ build_unary_op (location_t location,
if (TREE_CODE (arg) == C_MAYBE_CONST_EXPR)
{
tree inner = build_unary_op (location, code,
- C_MAYBE_CONST_EXPR_EXPR (arg), flag);
+ C_MAYBE_CONST_EXPR_EXPR (arg),
+ noconvert);
ret = build2 (C_MAYBE_CONST_EXPR, TREE_TYPE (inner),
C_MAYBE_CONST_EXPR_PRE (arg), inner);
gcc_assert (!C_MAYBE_CONST_EXPR_INT_OPERANDS (arg));
@@ -4628,7 +4631,7 @@ lvalue_p (const_tree ref)
case COMPOUND_LITERAL_EXPR:
case STRING_CST:
- return 1;
+ return true;
case INDIRECT_REF:
case ARRAY_REF:
@@ -4644,7 +4647,7 @@ lvalue_p (const_tree ref)
return TREE_CODE (TREE_TYPE (ref)) == ARRAY_TYPE;
default:
- return 0;
+ return false;
}
}
@@ -11512,9 +11515,9 @@ build_binary_op (location_t location, enum tree_code code,
{
op0 = c_save_expr (op0);
real = build_unary_op (EXPR_LOCATION (orig_op0), REALPART_EXPR,
- op0, 1);
+ op0, true);
imag = build_unary_op (EXPR_LOCATION (orig_op0), IMAGPART_EXPR,
- op0, 1);
+ op0, true);
switch (code)
{
case MULT_EXPR:
@@ -11534,9 +11537,9 @@ build_binary_op (location_t location, enum tree_code code,
{
op1 = c_save_expr (op1);
real = build_unary_op (EXPR_LOCATION (orig_op1), REALPART_EXPR,
- op1, 1);
+ op1, true);
imag = build_unary_op (EXPR_LOCATION (orig_op1), IMAGPART_EXPR,
- op1, 1);
+ op1, true);
switch (code)
{
case MULT_EXPR:
@@ -12072,6 +12075,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 +12119,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 +12707,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 +12782,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 +13003,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 +13158,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 +13250,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 +13311,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 +13371,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 +13720,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