diff options
Diffstat (limited to 'gcc/c')
-rw-r--r-- | gcc/c/ChangeLog | 82 | ||||
-rw-r--r-- | gcc/c/c-array-notation.c | 4 | ||||
-rw-r--r-- | gcc/c/c-decl.c | 2 | ||||
-rw-r--r-- | gcc/c/c-lang.c | 3 | ||||
-rw-r--r-- | gcc/c/c-objc-common.h | 6 | ||||
-rw-r--r-- | gcc/c/c-parser.c | 146 | ||||
-rw-r--r-- | gcc/c/c-tree.h | 1 | ||||
-rw-r--r-- | gcc/c/c-typeck.c | 184 |
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 |