aboutsummaryrefslogtreecommitdiff
path: root/gcc/c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/c')
-rw-r--r--gcc/c/ChangeLog106
-rw-r--r--gcc/c/Make-lang.in2
-rw-r--r--gcc/c/c-decl.c37
-rw-r--r--gcc/c/c-fold.c1
-rw-r--r--gcc/c/c-objc-common.h5
-rw-r--r--gcc/c/c-parser.c155
-rw-r--r--gcc/c/c-tree.h1
-rw-r--r--gcc/c/c-typeck.c145
-rw-r--r--gcc/c/gimple-parser.c3
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);
}