diff options
Diffstat (limited to 'gcc/c')
-rw-r--r-- | gcc/c/ChangeLog | 106 | ||||
-rw-r--r-- | gcc/c/Make-lang.in | 2 | ||||
-rw-r--r-- | gcc/c/c-decl.c | 37 | ||||
-rw-r--r-- | gcc/c/c-fold.c | 1 | ||||
-rw-r--r-- | gcc/c/c-objc-common.h | 5 | ||||
-rw-r--r-- | gcc/c/c-parser.c | 155 | ||||
-rw-r--r-- | gcc/c/c-tree.h | 1 | ||||
-rw-r--r-- | gcc/c/c-typeck.c | 145 | ||||
-rw-r--r-- | gcc/c/gimple-parser.c | 3 |
9 files changed, 377 insertions, 78 deletions
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 878f45b..e80c040 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,109 @@ +2020-08-01 Richard Sandiford <richard.sandiford@arm.com> + + PR c/96377 + * c-typeck.c (process_init_element): Split test for whether to + recurse into a record, union or array into... + (initialize_elementwise_p): ...this new function. Don't recurse + into a vector type if the initialization value is also a vector. + +2020-07-31 Richard Biener <rguenther@suse.de> + + PR debug/96383 + * c-objc-common.h (LANG_HOOKS_FINALIZE_EARLY_DEBUG): + Define to c_common_finalize_early_debug. + +2020-07-22 Tobias Burnus <tobias@codesourcery.com> + + * c-parser.c (c_parser_omp_clause_hint): Require nonnegative hint clause. + (c_parser_omp_critical): Permit hint(0) clause without named critical. + (c_parser_omp_construct): Don't assert if error_mark_node is returned. + +2020-07-21 Sunil K Pandey <skpgkp2@gmail.com> + + PR target/95237 + * c-decl.c (finish_decl): Call target hook + lower_local_decl_alignment to lower local decl alignment. + +2020-07-09 Julian Brown <julian@codesourcery.com> + Thomas Schwinge <thomas@codesourcery.com> + + PR middle-end/95270 + * c-typeck.c (c_finish_omp_clauses): Set OMP_CLAUSE_SIZE (bias) to zero + for standalone attach/detach clauses. + +2020-07-08 Eric Botcazou <ebotcazou@gcc.gnu.org> + + * c-typeck.c (convert_for_assignment): If -Wscalar-storage-order is + set, warn for conversion between pointers that point to incompatible + scalar storage orders. + +2020-07-07 Kaipeng Zhou <zhoukaipeng3@huawei.com> + + * c-parser.c (c_parser_statement_after_labels): Pass correct + parameters to c_parser_do_statement. + +2020-06-16 Jakub Jelinek <jakub@redhat.com> + + * c-parser.c (c_parser_expr_no_commas): Save, clear and restore + c_in_omp_for. + (c_parser_omp_for_loop): Set c_in_omp_for around some calls to avoid + premature c_fully_fold. Defer explicit c_fully_fold calls to after + c_finish_omp_for. + * c-tree.h (c_in_omp_for): Declare. + * c-typeck.c (c_in_omp_for): Define. + (build_modify_expr): Avoid c_fully_fold if c_in_omp_for. + (digest_init): Likewise. + (build_binary_op): Likewise. + +2020-06-16 Jakub Jelinek <jakub@redhat.com> + + * c-parser.c (c_parser_omp_clause_schedule): Reject modifier separated + from kind by comma rather than colon. + +2020-06-05 Mark Wielaard <mark@klomp.org> + + * c-decl.c (implicit_decl_warning): When warned and olddecl is + an undeclared builtin, then add a fixit header hint, if found. + (implicitly_declare): Add OPT_Wbuiltin_declaration_mismatch to + warning_at about implicit builtin declaration type mismatch. + +2020-06-03 Mark Wielaard <mark@klomp.org> + + * c-parser.c (struct c_parser): Add seen_string_literal + bitfield. + (c_parser_consume_token): Reset seen_string_literal. + (c_parser_error_richloc): Add name_hint if seen_string_literal + and next token is a CPP_NAME and we have a missing header + suggestion for the name. + (c_parser_string_literal): Set seen_string_literal. + +2020-06-03 Mark Wielaard <mark@klomp.org> + + * c-parser.c (c_parser_postfix_expression_after_primary): Add + scope with matching_parens after CPP_OPEN_PAREN. + +2020-06-03 Tobias Burnus <tobias@codesourcery.com> + + * c-objc-common.h (LANG_HOOKS_OMP_PREDETERMINED_MAPPING): Redefine. + +2020-05-28 Nicolas Bértolo <nicolasbertolo@gmail.com> + + * Make-lang.in: Remove extra slash. + +2020-05-19 Martin Liska <mliska@suse.cz> + + * c-parser.c: Fix typo. + +2020-05-14 Jakub Jelinek <jakub@redhat.com> + + * c-parser.c (c_parser_omp_target): Set cfun->has_omp_target. + +2020-05-07 Richard Biener <rguenther@suse.de> + + PR middle-end/94703 + * gimple-parser.c (c_parser_parse_ssa_name): Do not set + DECL_GIMPLE_REG_P. + 2020-04-30 Jakub Jelinek <jakub@redhat.com> PR c/94842 diff --git a/gcc/c/Make-lang.in b/gcc/c/Make-lang.in index 8944b9b..7efc7c2 100644 --- a/gcc/c/Make-lang.in +++ b/gcc/c/Make-lang.in @@ -162,7 +162,7 @@ c.install-plugin: installdirs # Install import library. ifeq ($(plugin_implib),yes) $(mkinstalldirs) $(DESTDIR)$(plugin_resourcesdir) - $(INSTALL_DATA) cc1$(exeext).a $(DESTDIR)/$(plugin_resourcesdir)/cc1$(exeext).a + $(INSTALL_DATA) cc1$(exeext).a $(DESTDIR)$(plugin_resourcesdir)/cc1$(exeext).a endif c.uninstall: diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c index b3e05be..5d6b504 100644 --- a/gcc/c/c-decl.c +++ b/gcc/c/c-decl.c @@ -3368,8 +3368,30 @@ implicit_decl_warning (location_t loc, tree id, tree olddecl) warned = warning_at (loc, OPT_Wimplicit_function_declaration, G_("implicit declaration of function %qE"), id); - if (olddecl && warned) - locate_old_decl (olddecl); + if (warned) + { + /* Whether the olddecl is an undeclared builtin function. + locate_old_decl will not generate a diagnostic for those, + so in that case we want to look elsewhere. */ + bool undeclared_builtin = (olddecl + && TREE_CODE (olddecl) == FUNCTION_DECL + && fndecl_built_in_p (olddecl) + && !C_DECL_DECLARED_BUILTIN (olddecl)); + if (undeclared_builtin) + { + const char *header = header_for_builtin_fn (olddecl); + if (header) + { + rich_location richloc (line_table, loc); + maybe_add_include_fixit (&richloc, header, true); + inform (&richloc, + "include %qs or provide a declaration of %qE", + header, id); + } + } + else if (olddecl) + locate_old_decl (olddecl); + } if (!warned) hint.suppress (); @@ -3631,7 +3653,9 @@ implicitly_declare (location_t loc, tree functionid) (TREE_TYPE (decl))); if (!comptypes (newtype, TREE_TYPE (decl))) { - bool warned = warning_at (loc, 0, "incompatible implicit " + bool warned = warning_at (loc, + OPT_Wbuiltin_declaration_mismatch, + "incompatible implicit " "declaration of built-in " "function %qD", decl); /* See if we can hint which header to include. */ @@ -5576,6 +5600,13 @@ finish_decl (tree decl, location_t init_loc, tree init, NULL_TREE, DECL_ATTRIBUTES (decl)); } + /* This is the last point we can lower alignment so give the target the + chance to do so. */ + if (VAR_P (decl) + && !is_global_var (decl) + && !DECL_HARD_REGISTER (decl)) + targetm.lower_local_decl_alignment (decl); + invoke_plugin_callbacks (PLUGIN_FINISH_DECL, decl); } diff --git a/gcc/c/c-fold.c b/gcc/c/c-fold.c index 63becfe..bd21d24 100644 --- a/gcc/c/c-fold.c +++ b/gcc/c/c-fold.c @@ -374,6 +374,7 @@ c_fully_fold_internal (tree expr, bool in_init, bool *maybe_const_operands, ret = fold (expr); if (TREE_OVERFLOW_P (ret) && !TREE_OVERFLOW_P (op0) + && !(BINARY_CLASS_P (op0) && TREE_OVERFLOW_P (TREE_OPERAND (op0, 1))) && !TREE_OVERFLOW_P (op1)) overflow_warning (EXPR_LOC_OR_LOC (expr, input_location), ret, expr); if (code == LSHIFT_EXPR diff --git a/gcc/c/c-objc-common.h b/gcc/c/c-objc-common.h index bfdb279..9257959 100644 --- a/gcc/c/c-objc-common.h +++ b/gcc/c/c-objc-common.h @@ -65,6 +65,8 @@ along with GCC; see the file COPYING3. If not see c_simulate_builtin_function_decl #undef LANG_HOOKS_EMITS_BEGIN_STMT #define LANG_HOOKS_EMITS_BEGIN_STMT true +#undef LANG_HOOKS_FINALIZE_EARLY_DEBUG +#define LANG_HOOKS_FINALIZE_EARLY_DEBUG c_common_finalize_early_debug /* Attribute hooks. */ #undef LANG_HOOKS_COMMON_ATTRIBUTE_TABLE @@ -107,6 +109,9 @@ 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_PREDETERMINED_MAPPING +#define LANG_HOOKS_OMP_PREDETERMINED_MAPPING c_omp_predetermined_mapping + #undef LANG_HOOKS_OMP_CLAUSE_COPY_CTOR #define LANG_HOOKS_OMP_CLAUSE_COPY_CTOR c_omp_clause_copy_ctor diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index ae354e6..7961cbc 100644 --- a/gcc/c/c-parser.c +++ b/gcc/c/c-parser.c @@ -69,11 +69,12 @@ along with GCC; see the file COPYING3. If not see #include "c-family/name-hint.h" #include "tree-iterator.h" #include "memmodel.h" +#include "c-family/known-headers.h" /* We need to walk over decls with incomplete struct/union/enum types after parsing the whole translation unit. In finish_decl(), if the decl is static, has incomplete - struct/union/enum type, it is appeneded to incomplete_record_decls. + struct/union/enum type, it is appended to incomplete_record_decls. In c_parser_translation_unit(), we iterate over incomplete_record_decls and report error if any of the decls are still incomplete. */ @@ -223,6 +224,13 @@ struct GTY(()) c_parser { keywords are valid. */ BOOL_BITFIELD objc_property_attr_context : 1; + /* Whether we have just seen/constructed a string-literal. Set when + returning a string-literal from c_parser_string_literal. Reset + in consume_token. Useful when we get a parse error and see an + unknown token, which could have been a string-literal constant + macro. */ + BOOL_BITFIELD seen_string_literal : 1; + /* Location of the last consumed token. */ location_t last_token_location; }; @@ -853,6 +861,7 @@ c_parser_consume_token (c_parser *parser) } } parser->tokens_avail--; + parser->seen_string_literal = false; } /* Expect the current token to be a #pragma. Consume it and remember @@ -966,6 +975,25 @@ c_parser_error_richloc (c_parser *parser, const char *gmsgid, } } + /* If we were parsing a string-literal and there is an unknown name + token right after, then check to see if that could also have been + a literal string by checking the name against a list of known + standard string literal constants defined in header files. If + there is one, then add that as an hint to the error message. */ + auto_diagnostic_group d; + name_hint h; + if (parser->seen_string_literal && token->type == CPP_NAME) + { + tree name = token->value; + const char *token_name = IDENTIFIER_POINTER (name); + const char *header_hint + = get_c_stdlib_header_for_string_macro_name (token_name); + if (header_hint != NULL) + h = name_hint (NULL, new suggest_missing_header (token->location, + token_name, + header_hint)); + } + c_parse_error (gmsgid, /* Because c_parse_error does not understand CPP_KEYWORD, keywords are treated like @@ -6166,7 +6194,7 @@ c_parser_statement_after_labels (c_parser *parser, bool *if_p, c_parser_while_statement (parser, false, 0, if_p); break; case RID_DO: - c_parser_do_statement (parser, 0, false); + c_parser_do_statement (parser, false, 0); break; case RID_FOR: c_parser_for_statement (parser, false, 0, if_p); @@ -7539,6 +7567,7 @@ c_parser_string_literal (c_parser *parser, bool translate, bool wide_ok) ret.original_code = STRING_CST; ret.original_type = NULL_TREE; set_c_expr_source_range (&ret, get_range_from_loc (line_table, loc)); + parser->seen_string_literal = true; return ret; } @@ -7565,6 +7594,8 @@ c_parser_expr_no_commas (c_parser *parser, struct c_expr *after, struct c_expr lhs, rhs, ret; enum tree_code code; location_t op_location, exp_location; + bool save_in_omp_for = c_in_omp_for; + c_in_omp_for = false; gcc_assert (!after || c_dialect_objc ()); lhs = c_parser_conditional_expression (parser, after, omp_atomic_lhs); op_location = c_parser_peek_token (parser)->location; @@ -7604,6 +7635,7 @@ c_parser_expr_no_commas (c_parser *parser, struct c_expr *after, code = BIT_IOR_EXPR; break; default: + c_in_omp_for = save_in_omp_for; return lhs; } c_parser_consume_token (parser); @@ -7623,6 +7655,7 @@ c_parser_expr_no_commas (c_parser *parser, struct c_expr *after, ret.original_code = ERROR_MARK; } ret.original_type = NULL; + c_in_omp_for = save_in_omp_for; return ret; } @@ -10458,21 +10491,23 @@ c_parser_postfix_expression_after_primary (c_parser *parser, break; case CPP_OPEN_PAREN: /* Function call. */ - c_parser_consume_token (parser); - for (i = 0; i < 3; i++) - { - sizeof_arg[i] = NULL_TREE; - sizeof_arg_loc[i] = UNKNOWN_LOCATION; - } - literal_zero_mask = 0; - if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) - exprlist = NULL; - else - exprlist = c_parser_expr_list (parser, true, false, &origtypes, - sizeof_arg_loc, sizeof_arg, - &arg_loc, &literal_zero_mask); - c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, - "expected %<)%>"); + { + matching_parens parens; + parens.consume_open (parser); + for (i = 0; i < 3; i++) + { + sizeof_arg[i] = NULL_TREE; + sizeof_arg_loc[i] = UNKNOWN_LOCATION; + } + literal_zero_mask = 0; + if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) + exprlist = NULL; + else + exprlist = c_parser_expr_list (parser, true, false, &origtypes, + sizeof_arg_loc, sizeof_arg, + &arg_loc, &literal_zero_mask); + parens.skip_until_found_close (parser); + } orig_expr = expr; mark_exp_read (expr.value); if (warn_sizeof_pointer_memaccess) @@ -13866,16 +13901,15 @@ c_parser_omp_clause_hint (c_parser *parser, tree list) expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true); tree c, t = expr.value; t = c_fully_fold (t, false, NULL); - - parens.skip_until_found_close (parser); - if (!INTEGRAL_TYPE_P (TREE_TYPE (t)) - || TREE_CODE (t) != INTEGER_CST) + || TREE_CODE (t) != INTEGER_CST + || tree_int_cst_sgn (t) == -1) { - c_parser_error (parser, "expected constant integer expression"); + c_parser_error (parser, "expected constant integer expression " + "with valid sync-hint value"); return list; } - + parens.skip_until_found_close (parser); check_no_duplicate_clause (list, OMP_CLAUSE_HINT, "hint"); c = build_omp_clause (hint_loc, OMP_CLAUSE_HINT); @@ -14751,6 +14785,7 @@ c_parser_omp_clause_schedule (c_parser *parser, tree list) c = build_omp_clause (loc, OMP_CLAUSE_SCHEDULE); + location_t comma = UNKNOWN_LOCATION; while (c_parser_next_token_is (parser, CPP_NAME)) { tree kind = c_parser_peek_token (parser)->value; @@ -14763,16 +14798,22 @@ c_parser_omp_clause_schedule (c_parser *parser, tree list) modifiers |= OMP_CLAUSE_SCHEDULE_NONMONOTONIC; else break; + comma = UNKNOWN_LOCATION; c_parser_consume_token (parser); if (nmodifiers++ == 0 && c_parser_next_token_is (parser, CPP_COMMA)) - c_parser_consume_token (parser); + { + comma = c_parser_peek_token (parser)->location; + c_parser_consume_token (parser); + } else { c_parser_require (parser, CPP_COLON, "expected %<:%>"); break; } } + if (comma != UNKNOWN_LOCATION) + error_at (comma, "expected %<:%>"); if ((modifiers & (OMP_CLAUSE_SCHEDULE_MONOTONIC | OMP_CLAUSE_SCHEDULE_NONMONOTONIC)) @@ -17753,18 +17794,9 @@ c_parser_omp_critical (location_t loc, c_parser *parser, bool *if_p) if (c_parser_next_token_is (parser, CPP_COMMA) && c_parser_peek_2nd_token (parser)->type == CPP_NAME) c_parser_consume_token (parser); - - clauses = c_parser_omp_all_clauses (parser, - OMP_CRITICAL_CLAUSE_MASK, - "#pragma omp critical"); } - else - { - if (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL)) - c_parser_error (parser, "expected %<(%> or end of line"); - c_parser_skip_to_pragma_eol (parser); - } - + clauses = c_parser_omp_all_clauses (parser, OMP_CRITICAL_CLAUSE_MASK, + "#pragma omp critical"); stmt = c_parser_omp_structured_block (parser, if_p); return c_finish_omp_critical (loc, stmt, name, clauses); } @@ -18081,8 +18113,10 @@ c_parser_omp_for_loop (location_t loc, c_parser *parser, enum tree_code code, if (i > 0) vec_safe_push (for_block, c_begin_compound_stmt (true)); this_pre_body = push_stmt_list (); + c_in_omp_for = true; c_parser_declaration_or_fndef (parser, true, true, true, true, true, NULL, vNULL); + c_in_omp_for = false; if (this_pre_body) { this_pre_body = pop_stmt_list (this_pre_body); @@ -18120,9 +18154,11 @@ c_parser_omp_for_loop (location_t loc, c_parser *parser, enum tree_code code, init_exp = c_parser_expr_no_commas (parser, NULL); init_exp = default_function_array_read_conversion (init_loc, init_exp); + c_in_omp_for = true; init = build_modify_expr (init_loc, decl, decl_exp.original_type, NOP_EXPR, init_loc, init_exp.value, init_exp.original_type); + c_in_omp_for = false; init = c_process_expr_stmt (init_loc, init); c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>"); @@ -18143,19 +18179,13 @@ c_parser_omp_for_loop (location_t loc, c_parser *parser, enum tree_code code, if (c_parser_next_token_is_not (parser, CPP_SEMICOLON)) { location_t cond_loc = c_parser_peek_token (parser)->location; + c_in_omp_for = true; struct c_expr cond_expr = c_parser_binary_expression (parser, NULL, NULL_TREE); + c_in_omp_for = false; cond = cond_expr.value; cond = c_objc_common_truthvalue_conversion (cond_loc, cond); - if (COMPARISON_CLASS_P (cond)) - { - tree op0 = TREE_OPERAND (cond, 0), op1 = TREE_OPERAND (cond, 1); - op0 = c_fully_fold (op0, false, NULL); - op1 = c_fully_fold (op1, false, NULL); - TREE_OPERAND (cond, 0) = op0; - TREE_OPERAND (cond, 1) = op1; - } switch (cond_expr.original_code) { case GT_EXPR: @@ -18299,8 +18329,10 @@ c_parser_omp_for_loop (location_t loc, c_parser *parser, enum tree_code code, an error from the initialization parsing. */ if (!fail) { + c_in_omp_for = true; stmt = c_finish_omp_for (loc, code, declv, NULL, initv, condv, incrv, body, pre_body, true); + c_in_omp_for = false; /* Check for iterators appearing in lb, b or incr expressions. */ if (stmt && !c_omp_check_loop_iv (stmt, declv, NULL)) @@ -18310,6 +18342,40 @@ c_parser_omp_for_loop (location_t loc, c_parser *parser, enum tree_code code, { add_stmt (stmt); + for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (stmt)); i++) + { + tree init = TREE_VEC_ELT (OMP_FOR_INIT (stmt), i); + gcc_assert (TREE_CODE (init) == MODIFY_EXPR); + tree decl = TREE_OPERAND (init, 0); + tree cond = TREE_VEC_ELT (OMP_FOR_COND (stmt), i); + gcc_assert (COMPARISON_CLASS_P (cond)); + gcc_assert (TREE_OPERAND (cond, 0) == decl); + + tree op0 = TREE_OPERAND (init, 1); + if (!OMP_FOR_NON_RECTANGULAR (stmt) + || TREE_CODE (op0) != TREE_VEC) + TREE_OPERAND (init, 1) = c_fully_fold (op0, false, NULL); + else + { + TREE_VEC_ELT (op0, 1) + = c_fully_fold (TREE_VEC_ELT (op0, 1), false, NULL); + TREE_VEC_ELT (op0, 2) + = c_fully_fold (TREE_VEC_ELT (op0, 2), false, NULL); + } + + tree op1 = TREE_OPERAND (cond, 1); + if (!OMP_FOR_NON_RECTANGULAR (stmt) + || TREE_CODE (op1) != TREE_VEC) + TREE_OPERAND (cond, 1) = c_fully_fold (op1, false, NULL); + else + { + TREE_VEC_ELT (op1, 1) + = c_fully_fold (TREE_VEC_ELT (op1, 1), false, NULL); + TREE_VEC_ELT (op1, 2) + = c_fully_fold (TREE_VEC_ELT (op1, 2), false, NULL); + } + } + if (cclauses != NULL && cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL] != NULL) { @@ -19866,6 +19932,7 @@ check_clauses: } pc = &OMP_CLAUSE_CHAIN (*pc); } + cfun->has_omp_target = true; return true; } @@ -21460,7 +21527,7 @@ c_parser_omp_construct (c_parser *parser, bool *if_p) gcc_unreachable (); } - if (stmt) + if (stmt && stmt != error_mark_node) gcc_assert (EXPR_LOCATION (stmt) != UNKNOWN_LOCATION); } diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h index 9466886..10938cf 100644 --- a/gcc/c/c-tree.h +++ b/gcc/c/c-tree.h @@ -657,6 +657,7 @@ extern alias_set_type c_get_alias_set (tree); extern int in_alignof; extern int in_sizeof; extern int in_typeof; +extern bool c_in_omp_for; extern tree c_last_sizeof_arg; extern location_t c_last_sizeof_loc; diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c index 385bf3a..0d639b60 100644 --- a/gcc/c/c-typeck.c +++ b/gcc/c/c-typeck.c @@ -71,6 +71,9 @@ int in_sizeof; /* The level of nesting inside "typeof". */ int in_typeof; +/* True when parsing OpenMP loop expressions. */ +bool c_in_omp_for; + /* The argument of last parsed sizeof expression, only to be tested if expr.original_code == SIZEOF_EXPR. */ tree c_last_sizeof_arg; @@ -6209,15 +6212,20 @@ build_modify_expr (location_t location, tree lhs, tree lhs_origtype, if (!(is_atomic_op && modifycode != NOP_EXPR)) { tree rhs_semantic_type = NULL_TREE; - if (TREE_CODE (newrhs) == EXCESS_PRECISION_EXPR) + if (!c_in_omp_for) { - rhs_semantic_type = TREE_TYPE (newrhs); - newrhs = TREE_OPERAND (newrhs, 0); + if (TREE_CODE (newrhs) == EXCESS_PRECISION_EXPR) + { + rhs_semantic_type = TREE_TYPE (newrhs); + newrhs = TREE_OPERAND (newrhs, 0); + } + npc = null_pointer_constant_p (newrhs); + newrhs = c_fully_fold (newrhs, false, NULL); + if (rhs_semantic_type) + newrhs = build1 (EXCESS_PRECISION_EXPR, rhs_semantic_type, newrhs); } - npc = null_pointer_constant_p (newrhs); - newrhs = c_fully_fold (newrhs, false, NULL); - if (rhs_semantic_type) - newrhs = build1 (EXCESS_PRECISION_EXPR, rhs_semantic_type, newrhs); + else + npc = null_pointer_constant_p (newrhs); newrhs = convert_for_assignment (location, rhs_loc, lhstype, newrhs, rhs_origtype, ic_assign, npc, NULL_TREE, NULL_TREE, 0); @@ -7143,6 +7151,41 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type, } } + /* See if the pointers point to incompatible scalar storage orders. */ + if (warn_scalar_storage_order + && (AGGREGATE_TYPE_P (ttl) && TYPE_REVERSE_STORAGE_ORDER (ttl)) + != (AGGREGATE_TYPE_P (ttr) && TYPE_REVERSE_STORAGE_ORDER (ttr))) + { + switch (errtype) + { + case ic_argpass: + /* Do not warn for built-in functions, for example memcpy, since we + control how they behave and they can be useful in this area. */ + if (TREE_CODE (rname) != FUNCTION_DECL || !DECL_IS_BUILTIN (rname)) + warning_at (location, OPT_Wscalar_storage_order, + "passing argument %d of %qE from incompatible " + "scalar storage order", parmnum, rname); + break; + case ic_assign: + warning_at (location, OPT_Wscalar_storage_order, + "assignment to %qT from pointer type %qT with " + "incompatible scalar storage order", type, rhstype); + break; + case ic_init: + warning_at (location, OPT_Wscalar_storage_order, + "initialization of %qT from pointer type %qT with " + "incompatible scalar storage order", type, rhstype); + break; + case ic_return: + warning_at (location, OPT_Wscalar_storage_order, + "returning %qT from pointer type with incompatible " + "scalar storage order %qT", rhstype, type); + break; + default: + gcc_unreachable (); + } + } + /* Any non-function converts to a [const][volatile] void * and vice versa; otherwise, targets must be the same. Meanwhile, the lhs target must have all the qualifiers of the rhs. */ @@ -7745,12 +7788,15 @@ digest_init (location_t init_loc, tree type, tree init, tree origtype, STRIP_TYPE_NOPS (inside_init); - if (TREE_CODE (inside_init) == EXCESS_PRECISION_EXPR) + if (!c_in_omp_for) { - semantic_type = TREE_TYPE (inside_init); - inside_init = TREE_OPERAND (inside_init, 0); + if (TREE_CODE (inside_init) == EXCESS_PRECISION_EXPR) + { + semantic_type = TREE_TYPE (inside_init); + inside_init = TREE_OPERAND (inside_init, 0); + } + inside_init = c_fully_fold (inside_init, require_constant, &maybe_const); } - inside_init = c_fully_fold (inside_init, require_constant, &maybe_const); /* Initialization of an array of chars from a string constant optionally enclosed in braces. */ @@ -9910,6 +9956,47 @@ output_pending_init_elements (int all, struct obstack * braced_init_obstack) goto retry; } +/* Expression VALUE coincides with the start of type TYPE in a braced + initializer. Return true if we should treat VALUE as initializing + the first element of TYPE, false if we should treat it as initializing + TYPE as a whole. + + If the initializer is clearly invalid, the question becomes: + which choice gives the best error message? */ + +static bool +initialize_elementwise_p (tree type, tree value) +{ + if (type == error_mark_node || value == error_mark_node) + return false; + + gcc_checking_assert (TYPE_MAIN_VARIANT (type) == type); + + tree value_type = TREE_TYPE (value); + if (value_type == error_mark_node) + return false; + + /* GNU vectors can be initialized elementwise. However, treat any + kind of vector value as initializing the vector type as a whole, + regardless of whether the value is a GNU vector. Such initializers + are valid if and only if they would have been valid in a non-braced + initializer like: + + TYPE foo = VALUE; + + so recursing into the vector type would be at best confusing or at + worst wrong. For example, when -flax-vector-conversions is in effect, + it's possible to initialize a V8HI from a V4SI, even though the vectors + have different element types and different numbers of elements. */ + if (gnu_vector_type_p (type)) + return !VECTOR_TYPE_P (value_type); + + if (AGGREGATE_TYPE_P (type)) + return type != TYPE_MAIN_VARIANT (value_type); + + return false; +} + /* Add one non-braced element to the current constructor level. This adjusts the current position within the constructor's type. This may also start or terminate implicit levels @@ -10089,11 +10176,7 @@ process_init_element (location_t loc, struct c_expr value, bool implicit, /* Otherwise, if we have come to a subaggregate, and we don't have an element of its type, push into it. */ else if (value.value != NULL_TREE - && value.value != error_mark_node - && TYPE_MAIN_VARIANT (TREE_TYPE (value.value)) != fieldtype - && (fieldcode == RECORD_TYPE || fieldcode == ARRAY_TYPE - || fieldcode == UNION_TYPE - || gnu_vector_type_p (fieldtype))) + && initialize_elementwise_p (fieldtype, value.value)) { push_init_level (loc, 1, braced_init_obstack); continue; @@ -10181,11 +10264,7 @@ process_init_element (location_t loc, struct c_expr value, bool implicit, /* Otherwise, if we have come to a subaggregate, and we don't have an element of its type, push into it. */ else if (value.value != NULL_TREE - && value.value != error_mark_node - && TYPE_MAIN_VARIANT (TREE_TYPE (value.value)) != fieldtype - && (fieldcode == RECORD_TYPE || fieldcode == ARRAY_TYPE - || fieldcode == UNION_TYPE - || gnu_vector_type_p (fieldtype))) + && initialize_elementwise_p (fieldtype, value.value)) { push_init_level (loc, 1, braced_init_obstack); continue; @@ -10224,11 +10303,7 @@ process_init_element (location_t loc, struct c_expr value, bool implicit, /* Otherwise, if we have come to a subaggregate, and we don't have an element of its type, push into it. */ else if (value.value != NULL_TREE - && value.value != error_mark_node - && TYPE_MAIN_VARIANT (TREE_TYPE (value.value)) != elttype - && (eltcode == RECORD_TYPE || eltcode == ARRAY_TYPE - || eltcode == UNION_TYPE - || gnu_vector_type_p (elttype))) + && initialize_elementwise_p (elttype, value.value)) { push_init_level (loc, 1, braced_init_obstack); continue; @@ -12475,7 +12550,7 @@ build_binary_op (location_t location, enum tree_code code, converted = 1; resultcode = xresultcode; - if (c_inhibit_evaluation_warnings == 0) + if (c_inhibit_evaluation_warnings == 0 && !c_in_omp_for) { bool op0_maybe_const = true; bool op1_maybe_const = true; @@ -14533,6 +14608,15 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort) } if (c_oacc_check_attachments (c)) remove = true; + if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP + && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH + || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DETACH)) + /* In this case, we have a single array element which is a + pointer, and we already set OMP_CLAUSE_SIZE in + handle_omp_array_sections above. For attach/detach clauses, + reset the OMP_CLAUSE_SIZE (representing a bias) to zero + here. */ + OMP_CLAUSE_SIZE (c) = size_zero_node; break; } if (t == error_mark_node) @@ -14546,6 +14630,13 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort) remove = true; break; } + if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP + && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH + || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DETACH)) + /* For attach/detach clauses, set OMP_CLAUSE_SIZE (representing a + bias) to zero here, so it is not set erroneously to the pointer + size later on in gimplify.c. */ + OMP_CLAUSE_SIZE (c) = size_zero_node; if (TREE_CODE (t) == COMPONENT_REF && OMP_CLAUSE_CODE (c) != OMP_CLAUSE__CACHE_) { diff --git a/gcc/c/gimple-parser.c b/gcc/c/gimple-parser.c index 4e8ff5b..577d8b5 100644 --- a/gcc/c/gimple-parser.c +++ b/gcc/c/gimple-parser.c @@ -1272,9 +1272,6 @@ c_parser_parse_ssa_name (gimple_parser &parser, error ("invalid base %qE for SSA name", parent); return error_mark_node; } - if (VECTOR_TYPE_P (TREE_TYPE (parent)) - || TREE_CODE (TREE_TYPE (parent)) == COMPLEX_TYPE) - DECL_GIMPLE_REG_P (parent) = 1; name = make_ssa_name_fn (cfun, parent, gimple_build_nop (), version); } |