aboutsummaryrefslogtreecommitdiff
path: root/gcc/c
diff options
context:
space:
mode:
authorAldy Hernandez <aldyh@redhat.com>2020-06-17 07:50:57 -0400
committerAldy Hernandez <aldyh@redhat.com>2020-06-17 07:50:57 -0400
commitb9e67f2840ce0d8859d96e7f8df8fe9584af5eba (patch)
treeed3b7284ff15c802583f6409b9c71b3739642d15 /gcc/c
parent1957047ed1c94bf17cf993a2b1866965f493ba87 (diff)
parent56638b9b1853666f575928f8baf17f70e4ed3517 (diff)
downloadgcc-b9e67f2840ce0d8859d96e7f8df8fe9584af5eba.zip
gcc-b9e67f2840ce0d8859d96e7f8df8fe9584af5eba.tar.gz
gcc-b9e67f2840ce0d8859d96e7f8df8fe9584af5eba.tar.bz2
Merge from trunk at:
commit 56638b9b1853666f575928f8baf17f70e4ed3517 Author: GCC Administrator <gccadmin@gcc.gnu.org> Date: Wed Jun 17 00:16:36 2020 +0000 Daily bump.
Diffstat (limited to 'gcc/c')
-rw-r--r--gcc/c/ChangeLog225
-rw-r--r--gcc/c/Make-lang.in2
-rw-r--r--gcc/c/c-decl.c254
-rw-r--r--gcc/c/c-fold.c10
-rw-r--r--gcc/c/c-objc-common.h3
-rw-r--r--gcc/c/c-parser.c233
-rw-r--r--gcc/c/c-tree.h16
-rw-r--r--gcc/c/c-typeck.c99
-rw-r--r--gcc/c/gimple-parser.c12
9 files changed, 677 insertions, 177 deletions
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog
index a4b1980..7d85d5a 100644
--- a/gcc/c/ChangeLog
+++ b/gcc/c/ChangeLog
@@ -1,3 +1,228 @@
+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
+ * c-decl.c (set_labels_context_r): In addition to context-less
+ LABEL_DECLs adjust also LABEL_DECLs with context equal to
+ parent function if any.
+ (store_parm_decls): Adjust comment.
+
+2020-04-19 Jakub Jelinek <jakub@redhat.com>
+
+ PR objc/94637
+ * c-parser.c (c_parser_objc_selector_arg): Handle CPP_SCOPE like
+ two CPP_COLON tokens.
+
+2020-04-17 Jakub Jelinek <jakub@redhat.com>
+
+ PR other/94629
+ * c-parser.c (c_parser_oacc_routine): Remove redundant assignment
+ to data.clauses.
+
+2020-04-15 Jakub Jelinek <jakub@redhat.com>
+
+ PR c/94593
+ * c-parser.c (c_parser_pragma) <case PRAGMA_OMP_REQUIRES>: Reject
+ requires directive when not at file scope.
+
+2020-04-08 Tobias Burnus <tobias@codesourcery.com>
+
+ PR middle-end/94120
+ * c-decl.c (c_check_in_current_scope): New function.
+ * c-tree.h (c_check_in_current_scope): Declare it.
+ * c-parser.c (c_parser_oacc_declare): Add check that variables
+ are declared in the same scope as the directive. Fix handling
+ of namespace vars.
+
+2020-04-07 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/94512
+ * c-parser.c (c_parser_omp_parallel): Set OMP_PARALLEL_COMBINED
+ if c_parser_omp_master succeeded.
+
+2020-03-23 Jakub Jelinek <jakub@redhat.com>
+
+ PR gcov-profile/94029
+ PR c/94239
+ * c-parser.c (c_parser_declaration_or_fndef): Initialize endloc to
+ the function_start_locus location. Don't do that afterwards for the
+ __GIMPLE body parsing.
+
+2020-03-19 Jakub Jelinek <jakub@redhat.com>
+
+ PR gcov-profile/94029
+ * c-tree.h (finish_function): Add location_t argument defaulted to
+ input_location.
+ * c-parser.c (c_parser_compound_statement): Add endlocp argument and
+ set it to the locus of closing } if non-NULL.
+ (c_parser_compound_statement_nostart): Return locus of closing }.
+ (c_parser_parse_rtl_body): Likewise.
+ (c_parser_declaration_or_fndef): Propagate locus of closing } to
+ finish_function.
+ * c-decl.c (finish_function): Add end_loc argument, use it instead of
+ input_location to set function_end_locus.
+
+2020-03-17 Jakub Jelinek <jakub@redhat.com>
+
+ PR c/94172
+ * c-tree.h (C_TYPE_INCOMPLETE_VARS): Define to TYPE_LANG_SLOT_1
+ instead of TYPE_VFIELD, and support it on {RECORD,UNION,ENUMERAL}_TYPE.
+ (TYPE_ACTUAL_ARG_TYPES): Check that it is only used on FUNCTION_TYPEs.
+ * c-decl.c (pushdecl): Push C_TYPE_INCOMPLETE_VARS also to
+ ENUMERAL_TYPEs.
+ (finish_incomplete_vars): New function, moved from finish_struct. Use
+ relayout_decl instead of layout_decl.
+ (finish_struct): Remove obsolete comment about C_TYPE_INCOMPLETE_VARS
+ being TYPE_VFIELD. Use finish_incomplete_vars.
+ (finish_enum): Clear C_TYPE_INCOMPLETE_VARS. Call
+ finish_incomplete_vars.
+ * c-typeck.c (c_build_qualified_type): Clear C_TYPE_INCOMPLETE_VARS
+ also on ENUMERAL_TYPEs.
+
+2020-03-16 Jakub Jelinek <jakub@redhat.com>
+
+ PR c/94179
+ * c-fold.c (c_fully_fold_internal): Handle MEM_REF.
+
+2020-03-13 Martin Sebor <msebor@redhat.com>
+
+ PR c/94040
+ * c-decl.c (builtin_structptr_type_count): New constant.
+ (match_builtin_function_types): Reject decls that are incompatible
+ in types pointed to by pointers.
+ (diagnose_mismatched_decls): Adjust comments.
+
+2020-03-05 Joseph Myers <joseph@codesourcery.com>
+
+ PR c/93577
+ * c-typeck.c (pop_init_level): Do not diagnose initializers as
+ empty when initialized type is error_mark_node.
+ (set_designator, process_init_element): Ignore initializers for
+ elements of a variable-size type or of error_mark_node.
+
+2020-03-01 Martin Sebor <msebor@redhat.com>
+
+ PR middle-end/93926
+ * c-decl.c (types_close_enough_to_match): New function.
+ (match_builtin_function_types):
+ (diagnose_mismatched_decls): Add missing inform call to a warning.
+
+2020-03-01 Martin Sebor <msebor@redhat.com>
+
+ PR c/93812
+ * c-typeck.c (build_functype_attribute_variant): New function.
+ (composite_type): Call it.
+
+2020-02-25 Jakub Jelinek <jakub@redhat.com>
+
+ PR other/93912
+ * gimple-parser.c (c_parser_gimple_parse_bb_spec_edge_probability):
+ Rename last argument from probablity to probability.
+
+2020-02-13 Jakub Jelinek <jakub@redhat.com>
+
+ PR c/93576
+ * c-decl.c (grokdeclarator): If this_size_varies, only push size into
+ *expr if it has side effects.
+
+2020-01-30 Jeff Law <law@redhat.com>
+
+ PR c/88660
+ * c-parser.c (c_parser_switch_statement): Make sure to request
+ marking the switch expr as used.
+
+2020-01-22 Joseph Myers <joseph@codesourcery.com>
+
+ PR c/93348
+ * c-typeck.c (build_c_cast): Call remove_c_maybe_const_expr on
+ argument with integer operands.
+
+2020-01-16 Kerem Kat <keremkat@gmail.com>
+
+ PR c/92833
+ * c-parser.c (c_parser_consume_token): Fix peeked token stack pop
+ to support 4 available tokens.
+
+2020-01-15 Joseph Myers <joseph@codesourcery.com>
+
+ PR c/93072
+ * c-decl.c (pushdecl): Use TREE_PUBLIC, not DECL_EXTERNAL, to
+ determine whether to set DECL_CONTEXT.
+
+2020-01-13 Joseph Myers <joseph@codesourcery.com>
+
+ PR c/93241
+ * c-typeck.c (build_c_cast): Check for expressions with integer
+ operands that can occur in an unevaluated part of an integer
+ constant expression and call note_integer_operands as needed.
+
+2019-01-08 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/93199
+ * gimple-parser.c (c_parser_parse_gimple_body): Remove __PHI IFN
+ permanently.
+
2020-01-01 Jakub Jelinek <jakub@redhat.com>
Update copyright years.
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 fa834d9..81bd2ee 100644
--- a/gcc/c/c-decl.c
+++ b/gcc/c/c-decl.c
@@ -1641,13 +1641,29 @@ c_bind (location_t loc, tree decl, bool is_global)
}
-/* Stores the first FILE*, const struct tm* etc. argument type (whatever it
- is) seen in a declaration of a file I/O etc. built-in. Subsequent
- declarations of such built-ins are expected to refer to it rather than to
- fileptr_type_node etc. which is just void* (or to any other type).
+/* Stores the first FILE*, const struct tm* etc. argument type (whatever
+ it is) seen in a declaration of a file I/O etc. built-in, corresponding
+ to the builtin_structptr_types array. Subsequent declarations of such
+ built-ins are expected to refer to it rather than to fileptr_type_node,
+ etc. which is just void* (or to any other type).
Used only by match_builtin_function_types. */
-static GTY(()) tree last_structptr_types[6];
+static const unsigned builtin_structptr_type_count
+ = sizeof builtin_structptr_types / sizeof builtin_structptr_types[0];
+
+static GTY(()) tree last_structptr_types[builtin_structptr_type_count];
+
+/* Returns true if types T1 and T2 representing return types or types
+ of function arguments are close enough to be considered interchangeable
+ in redeclarations of built-in functions. */
+
+static bool
+types_close_enough_to_match (tree t1, tree t2)
+{
+ return (TYPE_MODE (t1) == TYPE_MODE (t2)
+ && POINTER_TYPE_P (t1) == POINTER_TYPE_P (t2)
+ && FUNCTION_POINTER_TYPE_P (t1) == FUNCTION_POINTER_TYPE_P (t2));
+}
/* Subroutine of compare_decls. Allow harmless mismatches in return
and argument types provided that the type modes match. Set *STRICT
@@ -1659,16 +1675,19 @@ static tree
match_builtin_function_types (tree newtype, tree oldtype,
tree *strict, unsigned *argno)
{
- /* Accept the return type of the new declaration if same modes. */
- tree oldrettype = TREE_TYPE (oldtype);
- tree newrettype = TREE_TYPE (newtype);
-
*argno = 0;
*strict = NULL_TREE;
- if (TYPE_MODE (oldrettype) != TYPE_MODE (newrettype))
+ /* Accept the return type of the new declaration if it has the same
+ mode and if they're both pointers or if neither is. */
+ tree oldrettype = TREE_TYPE (oldtype);
+ tree newrettype = TREE_TYPE (newtype);
+
+ if (!types_close_enough_to_match (oldrettype, newrettype))
return NULL_TREE;
+ /* Check that the return types are compatible but don't fail if they
+ are not (e.g., int vs long in ILP32) and just let the caller know. */
if (!comptypes (TYPE_MAIN_VARIANT (oldrettype),
TYPE_MAIN_VARIANT (newrettype)))
*strict = oldrettype;
@@ -1677,10 +1696,13 @@ match_builtin_function_types (tree newtype, tree oldtype,
tree newargs = TYPE_ARG_TYPES (newtype);
tree tryargs = newargs;
- gcc_checking_assert ((sizeof (last_structptr_types)
- / sizeof (last_structptr_types[0]))
- == (sizeof (builtin_structptr_types)
- / sizeof (builtin_structptr_types[0])));
+ const unsigned nlst
+ = sizeof last_structptr_types / sizeof last_structptr_types[0];
+ const unsigned nbst
+ = sizeof builtin_structptr_types / sizeof builtin_structptr_types[0];
+
+ gcc_checking_assert (nlst == nbst);
+
for (unsigned i = 1; oldargs || newargs; ++i)
{
if (!oldargs
@@ -1692,22 +1714,15 @@ match_builtin_function_types (tree newtype, tree oldtype,
tree oldtype = TYPE_MAIN_VARIANT (TREE_VALUE (oldargs));
tree newtype = TYPE_MAIN_VARIANT (TREE_VALUE (newargs));
- /* Fail for types with incompatible modes/sizes. */
- if (TYPE_MODE (TREE_VALUE (oldargs))
- != TYPE_MODE (TREE_VALUE (newargs)))
+ if (!types_close_enough_to_match (oldtype, newtype))
return NULL_TREE;
- /* Fail for function and object pointer mismatches. */
- if ((FUNCTION_POINTER_TYPE_P (oldtype)
- != FUNCTION_POINTER_TYPE_P (newtype))
- || POINTER_TYPE_P (oldtype) != POINTER_TYPE_P (newtype))
- return NULL_TREE;
-
- unsigned j = (sizeof (builtin_structptr_types)
- / sizeof (builtin_structptr_types[0]));
+ unsigned j = nbst;
if (POINTER_TYPE_P (oldtype))
- for (j = 0; j < (sizeof (builtin_structptr_types)
- / sizeof (builtin_structptr_types[0])); ++j)
+ /* Iterate over well-known struct types like FILE (whose types
+ aren't known to us) and compare the pointer to each to
+ the pointer argument. */
+ for (j = 0; j < nbst; ++j)
{
if (TREE_VALUE (oldargs) != builtin_structptr_types[j].node)
continue;
@@ -1727,13 +1742,26 @@ match_builtin_function_types (tree newtype, tree oldtype,
last_structptr_types[j] = newtype;
break;
}
- if (j == (sizeof (builtin_structptr_types)
- / sizeof (builtin_structptr_types[0]))
- && !*strict
- && !comptypes (oldtype, newtype))
+
+ if (j == nbst && !comptypes (oldtype, newtype))
{
- *argno = i;
- *strict = oldtype;
+ if (POINTER_TYPE_P (oldtype))
+ {
+ /* For incompatible pointers, only reject differences in
+ the unqualified variants of the referenced types but
+ consider differences in qualifiers as benign (report
+ those to caller via *STRICT below). */
+ tree oldref = TYPE_MAIN_VARIANT (TREE_TYPE (oldtype));
+ tree newref = TYPE_MAIN_VARIANT (TREE_TYPE (newtype));
+ if (!comptypes (oldref, newref))
+ return NULL_TREE;
+ }
+
+ if (!*strict)
+ {
+ *argno = i;
+ *strict = oldtype;
+ }
}
oldargs = TREE_CHAIN (oldargs);
@@ -1957,11 +1985,9 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
&& !C_DECL_DECLARED_BUILTIN (olddecl))
{
/* Accept "harmless" mismatches in function types such
- as missing qualifiers or pointer vs same size integer
- mismatches. This is for the ffs and fprintf builtins.
- However, with -Wextra in effect, diagnose return and
- argument types that are incompatible according to
- language rules. */
+ as missing qualifiers or int vs long when they're the same
+ size. However, diagnose return and argument types that are
+ incompatible according to language rules. */
tree mismatch_expect;
unsigned mismatch_argno;
@@ -1996,19 +2022,26 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
if (mismatch_expect && extra_warnings)
{
- /* If types match only loosely, print a warning but accept
- the redeclaration. */
location_t newloc = DECL_SOURCE_LOCATION (newdecl);
+ bool warned = false;
if (mismatch_argno)
- warning_at (newloc, OPT_Wbuiltin_declaration_mismatch,
- "mismatch in argument %u type of built-in "
- "function %qD; expected %qT",
- mismatch_argno, newdecl, mismatch_expect);
+ warned = warning_at (newloc, OPT_Wbuiltin_declaration_mismatch,
+ "mismatch in argument %u type of built-in "
+ "function %qD; expected %qT",
+ mismatch_argno, newdecl, mismatch_expect);
else
- warning_at (newloc, OPT_Wbuiltin_declaration_mismatch,
- "mismatch in return type of built-in "
- "function %qD; expected %qT",
- newdecl, mismatch_expect);
+ warned = warning_at (newloc, OPT_Wbuiltin_declaration_mismatch,
+ "mismatch in return type of built-in "
+ "function %qD; expected %qT",
+ newdecl, mismatch_expect);
+ const char *header = header_for_builtin_fn (olddecl);
+ if (warned && header)
+ {
+ rich_location richloc (line_table, newloc);
+ maybe_add_include_fixit (&richloc, header, true);
+ inform (&richloc,
+ "%qD is declared in header %qs", olddecl, header);
+ }
}
}
else if (TREE_CODE (olddecl) == FUNCTION_DECL
@@ -3048,7 +3081,7 @@ pushdecl (tree x)
unless they have initializers (which generate code). */
if (current_function_decl
&& (!VAR_OR_FUNCTION_DECL_P (x)
- || DECL_INITIAL (x) || !DECL_EXTERNAL (x)))
+ || DECL_INITIAL (x) || !TREE_PUBLIC (x)))
DECL_CONTEXT (x) = current_function_decl;
/* Anonymous decls are just inserted in the scope. */
@@ -3279,7 +3312,8 @@ pushdecl (tree x)
element = TREE_TYPE (element);
element = TYPE_MAIN_VARIANT (element);
- if (RECORD_OR_UNION_TYPE_P (element)
+ if ((RECORD_OR_UNION_TYPE_P (element)
+ || TREE_CODE (element) == ENUMERAL_TYPE)
&& (TREE_CODE (x) != TYPE_DECL
|| TREE_CODE (TREE_TYPE (x)) == ARRAY_TYPE)
&& !COMPLETE_TYPE_P (element))
@@ -3334,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 ();
@@ -3597,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. */
@@ -6382,6 +6440,7 @@ grokdeclarator (const struct c_declarator *declarator,
error_at (loc,
"size of unnamed array has non-integer type");
size = integer_one_node;
+ size_int_const = true;
}
/* This can happen with enum forward declaration. */
else if (!COMPLETE_TYPE_P (TREE_TYPE (size)))
@@ -6393,6 +6452,7 @@ grokdeclarator (const struct c_declarator *declarator,
error_at (loc, "size of unnamed array has incomplete "
"type");
size = integer_one_node;
+ size_int_const = true;
}
size = c_fully_fold (size, false, &size_maybe_const);
@@ -6417,6 +6477,7 @@ grokdeclarator (const struct c_declarator *declarator,
else
error_at (loc, "size of unnamed array is negative");
size = integer_one_node;
+ size_int_const = true;
}
/* Handle a size folded to an integer constant but
not an integer constant expression. */
@@ -6512,11 +6573,14 @@ grokdeclarator (const struct c_declarator *declarator,
}
if (this_size_varies)
{
- if (*expr)
- *expr = build2 (COMPOUND_EXPR, TREE_TYPE (size),
- *expr, size);
- else
- *expr = size;
+ if (TREE_SIDE_EFFECTS (size))
+ {
+ if (*expr)
+ *expr = build2 (COMPOUND_EXPR, TREE_TYPE (size),
+ *expr, size);
+ else
+ *expr = size;
+ }
*expr_const_operands &= size_maybe_const;
}
}
@@ -8318,6 +8382,26 @@ field_decl_cmp (const void *x_p, const void *y_p)
return 1;
}
+/* If this structure or union completes the type of any previous
+ variable declaration, lay it out and output its rtl. */
+static void
+finish_incomplete_vars (tree incomplete_vars, bool toplevel)
+{
+ for (tree x = incomplete_vars; x; x = TREE_CHAIN (x))
+ {
+ tree decl = TREE_VALUE (x);
+ if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
+ layout_array_type (TREE_TYPE (decl));
+ if (TREE_CODE (decl) != TYPE_DECL)
+ {
+ relayout_decl (decl);
+ if (c_dialect_objc ())
+ objc_check_decl (decl);
+ rest_of_decl_compilation (decl, toplevel, 0);
+ }
+ }
+}
+
/* Fill in the fields of a RECORD_TYPE or UNION_TYPE node, T.
LOC is the location of the RECORD_TYPE or UNION_TYPE's definition.
FIELDLIST is a chain of FIELD_DECL nodes for the fields.
@@ -8576,13 +8660,6 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes,
warning_at (loc, 0, "union cannot be made transparent");
}
- /* Note: C_TYPE_INCOMPLETE_VARS overloads TYPE_VFIELD which is used
- in dwarf2out via rest_of_decl_compilation below and means
- something totally different. Since we will be clearing
- C_TYPE_INCOMPLETE_VARS shortly after we iterate through them,
- clear it ahead of time and avoid problems in dwarf2out. Ideally,
- C_TYPE_INCOMPLETE_VARS should use some language specific
- node. */
tree incomplete_vars = C_TYPE_INCOMPLETE_VARS (TYPE_MAIN_VARIANT (t));
for (x = TYPE_MAIN_VARIANT (t); x; x = TYPE_NEXT_VARIANT (x))
{
@@ -8603,21 +8680,7 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes,
/* Finish debugging output for this type. */
rest_of_type_compilation (t, toplevel);
- /* If this structure or union completes the type of any previous
- variable declaration, lay it out and output its rtl. */
- for (x = incomplete_vars; x; x = TREE_CHAIN (x))
- {
- tree decl = TREE_VALUE (x);
- if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
- layout_array_type (TREE_TYPE (decl));
- if (TREE_CODE (decl) != TYPE_DECL)
- {
- layout_decl (decl, 0);
- if (c_dialect_objc ())
- objc_check_decl (decl);
- rest_of_decl_compilation (decl, toplevel, 0);
- }
- }
+ finish_incomplete_vars (incomplete_vars, toplevel);
/* If we're inside a function proper, i.e. not file-scope and not still
parsing parameters, then arrange for the size of a variable sized type
@@ -8896,8 +8959,10 @@ finish_enum (tree enumtype, tree values, tree attributes)
TYPE_LANG_SPECIFIC (enumtype) = lt;
/* Fix up all variant types of this enum type. */
+ tree incomplete_vars = C_TYPE_INCOMPLETE_VARS (TYPE_MAIN_VARIANT (enumtype));
for (tem = TYPE_MAIN_VARIANT (enumtype); tem; tem = TYPE_NEXT_VARIANT (tem))
{
+ C_TYPE_INCOMPLETE_VARS (tem) = NULL_TREE;
if (tem == enumtype)
continue;
TYPE_VALUES (tem) = TYPE_VALUES (enumtype);
@@ -8916,6 +8981,8 @@ finish_enum (tree enumtype, tree values, tree attributes)
/* Finish debugging output for this type. */
rest_of_type_compilation (enumtype, toplevel);
+ finish_incomplete_vars (incomplete_vars, toplevel);
+
/* If this enum is defined inside a struct, add it to
struct_types. */
if (warn_cxx_compat
@@ -9679,15 +9746,18 @@ store_parm_decls_from (struct c_arg_info *arg_info)
store_parm_decls ();
}
-/* Called by walk_tree to look for and update context-less labels. */
+/* Called by walk_tree to look for and update context-less labels
+ or labels with context in the parent function. */
static tree
set_labels_context_r (tree *tp, int *walk_subtrees, void *data)
{
+ tree ctx = static_cast<tree>(data);
if (TREE_CODE (*tp) == LABEL_EXPR
- && DECL_CONTEXT (LABEL_EXPR_LABEL (*tp)) == NULL_TREE)
+ && (DECL_CONTEXT (LABEL_EXPR_LABEL (*tp)) == NULL_TREE
+ || DECL_CONTEXT (LABEL_EXPR_LABEL (*tp)) == DECL_CONTEXT (ctx)))
{
- DECL_CONTEXT (LABEL_EXPR_LABEL (*tp)) = static_cast<tree>(data);
+ DECL_CONTEXT (LABEL_EXPR_LABEL (*tp)) = ctx;
*walk_subtrees = 0;
}
@@ -9757,7 +9827,11 @@ store_parm_decls (void)
gotos, labels, etc. Because at that time the function decl
for F has not been created yet, those labels do not have any
function context. But we have the fndecl now, so update the
- labels accordingly. gimplify_expr would crash otherwise. */
+ labels accordingly. gimplify_expr would crash otherwise.
+ Or with nested functions the labels could be created with parent
+ function's context, while when the statement is emitted at the
+ start of the nested function, it needs the nested function's
+ context. */
walk_tree_without_duplicates (&arg_info->pending_sizes,
set_labels_context_r, fndecl);
add_stmt (arg_info->pending_sizes);
@@ -9811,7 +9885,7 @@ temp_pop_parm_decls (void)
This is called after parsing the body of the function definition. */
void
-finish_function (void)
+finish_function (location_t end_loc)
{
tree fndecl = current_function_decl;
@@ -9907,7 +9981,7 @@ finish_function (void)
/* Store the end of the function, so that we get good line number
info for the epilogue. */
- cfun->function_end_locus = input_location;
+ cfun->function_end_locus = end_loc;
/* Finalize the ELF visibility for the function. */
c_determine_visibility (fndecl);
@@ -11998,4 +12072,12 @@ c_check_omp_declare_reduction_r (tree *tp, int *, void *data)
return NULL_TREE;
}
+
+bool
+c_check_in_current_scope (tree decl)
+{
+ struct c_binding *b = I_SYMBOL_BINDING (DECL_NAME (decl));
+ return b != NULL && B_IN_CURRENT_SCOPE (b);
+}
+
#include "gt-c-c-decl.h"
diff --git a/gcc/c/c-fold.c b/gcc/c/c-fold.c
index fde2d55..bd21d24 100644
--- a/gcc/c/c-fold.c
+++ b/gcc/c/c-fold.c
@@ -346,6 +346,7 @@ c_fully_fold_internal (tree expr, bool in_init, bool *maybe_const_operands,
case UNGT_EXPR:
case UNGE_EXPR:
case UNEQ_EXPR:
+ case MEM_REF:
/* Binary operations evaluating both arguments (increment and
decrement are binary internally in GCC). */
orig_op0 = op0 = TREE_OPERAND (expr, 0);
@@ -373,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
@@ -435,6 +437,14 @@ c_fully_fold_internal (tree expr, bool in_init, bool *maybe_const_operands,
|| TREE_CODE (TREE_TYPE (orig_op0)) == FIXED_POINT_TYPE)
&& TREE_CODE (TREE_TYPE (orig_op1)) == INTEGER_TYPE)
warn_for_div_by_zero (loc, op1);
+ if (code == MEM_REF
+ && ret != expr
+ && TREE_CODE (ret) == MEM_REF)
+ {
+ TREE_READONLY (ret) = TREE_READONLY (expr);
+ TREE_SIDE_EFFECTS (ret) = TREE_SIDE_EFFECTS (expr);
+ TREE_THIS_VOLATILE (ret) = TREE_THIS_VOLATILE (expr);
+ }
goto out;
case ADDR_EXPR:
diff --git a/gcc/c/c-objc-common.h b/gcc/c/c-objc-common.h
index bfdb279..5471fc7 100644
--- a/gcc/c/c-objc-common.h
+++ b/gcc/c/c-objc-common.h
@@ -107,6 +107,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 ea06069..7bf91ef 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;
};
@@ -846,9 +854,14 @@ c_parser_consume_token (c_parser *parser)
{
parser->tokens[0] = parser->tokens[1];
if (parser->tokens_avail >= 3)
- parser->tokens[1] = parser->tokens[2];
+ {
+ parser->tokens[1] = parser->tokens[2];
+ if (parser->tokens_avail >= 4)
+ parser->tokens[2] = parser->tokens[3];
+ }
}
parser->tokens_avail--;
+ parser->seen_string_literal = false;
}
/* Expect the current token to be a #pragma. Consume it and remember
@@ -962,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
@@ -1483,8 +1515,8 @@ static struct c_expr c_parser_braced_init (c_parser *, tree, bool,
static void c_parser_initelt (c_parser *, struct obstack *);
static void c_parser_initval (c_parser *, struct c_expr *,
struct obstack *);
-static tree c_parser_compound_statement (c_parser *);
-static void c_parser_compound_statement_nostart (c_parser *);
+static tree c_parser_compound_statement (c_parser *, location_t * = NULL);
+static location_t c_parser_compound_statement_nostart (c_parser *);
static void c_parser_label (c_parser *);
static void c_parser_statement (c_parser *, bool *, location_t * = NULL);
static void c_parser_statement_after_labels (c_parser *, bool *,
@@ -1579,8 +1611,7 @@ static void c_parser_objc_at_synthesize_declaration (c_parser *);
static void c_parser_objc_at_dynamic_declaration (c_parser *);
static bool c_parser_objc_diagnose_bad_element_prefix
(c_parser *, struct c_declspecs *);
-
-static void c_parser_parse_rtl_body (c_parser *parser, char *start_with_pass);
+static location_t c_parser_parse_rtl_body (c_parser *, char *);
/* Parse a translation unit (C90 6.7, C99 6.9, C11 6.9).
@@ -2466,14 +2497,16 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
omp_declare_simd_clauses);
if (oacc_routine_data)
c_finish_oacc_routine (oacc_routine_data, current_function_decl, true);
+ location_t startloc = c_parser_peek_token (parser)->location;
DECL_STRUCT_FUNCTION (current_function_decl)->function_start_locus
- = c_parser_peek_token (parser)->location;
+ = startloc;
+ location_t endloc = startloc;
/* If the definition was marked with __RTL, use the RTL parser now,
consuming the function body. */
if (specs->declspec_il == cdil_rtl)
{
- c_parser_parse_rtl_body (parser, specs->gimple_or_rtl_pass);
+ endloc = c_parser_parse_rtl_body (parser, specs->gimple_or_rtl_pass);
/* Normally, store_parm_decls sets next_is_function_body,
anticipating a function body. We need a push_scope/pop_scope
@@ -2482,7 +2515,7 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
push_scope ();
pop_scope ();
- finish_function ();
+ finish_function (endloc);
return;
}
/* If the definition was marked with __GIMPLE then parse the
@@ -2497,7 +2530,7 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
in_late_binary_op = saved;
}
else
- fnbody = c_parser_compound_statement (parser);
+ fnbody = c_parser_compound_statement (parser, &endloc);
tree fndecl = current_function_decl;
if (nested)
{
@@ -2508,7 +2541,7 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
by initializer_constant_valid_p. See gcc.dg/nested-fn-2.c. */
DECL_STATIC_CHAIN (decl) = 1;
add_stmt (fnbody);
- finish_function ();
+ finish_function (endloc);
c_pop_function_context ();
add_stmt (build_stmt (DECL_SOURCE_LOCATION (decl), DECL_EXPR, decl));
}
@@ -2516,7 +2549,7 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
{
if (fnbody)
add_stmt (fnbody);
- finish_function ();
+ finish_function (endloc);
}
/* Get rid of the empty stmt list for GIMPLE/RTL. */
if (specs->declspec_il != cdil_none)
@@ -5595,7 +5628,7 @@ c_parser_initval (c_parser *parser, struct c_expr *after,
cancellation-point-directive */
static tree
-c_parser_compound_statement (c_parser *parser)
+c_parser_compound_statement (c_parser *parser, location_t *endlocp)
{
tree stmt;
location_t brace_loc;
@@ -5609,7 +5642,9 @@ c_parser_compound_statement (c_parser *parser)
return error_mark_node;
}
stmt = c_begin_compound_stmt (true);
- c_parser_compound_statement_nostart (parser);
+ location_t end_loc = c_parser_compound_statement_nostart (parser);
+ if (endlocp)
+ *endlocp = end_loc;
return c_end_compound_stmt (brace_loc, stmt, true);
}
@@ -5618,7 +5653,7 @@ c_parser_compound_statement (c_parser *parser)
used for parsing both compound statements and statement expressions
(which follow different paths to handling the opening). */
-static void
+static location_t
c_parser_compound_statement_nostart (c_parser *parser)
{
bool last_stmt = false;
@@ -5627,9 +5662,10 @@ c_parser_compound_statement_nostart (c_parser *parser)
location_t label_loc = UNKNOWN_LOCATION; /* Quiet warning. */
if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
{
- add_debug_begin_stmt (c_parser_peek_token (parser)->location);
+ location_t endloc = c_parser_peek_token (parser)->location;
+ add_debug_begin_stmt (endloc);
c_parser_consume_token (parser);
- return;
+ return endloc;
}
mark_valid_location_for_stdc_pragma (true);
if (c_parser_next_token_is_keyword (parser, RID_LABEL))
@@ -5670,8 +5706,9 @@ c_parser_compound_statement_nostart (c_parser *parser)
{
mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
c_parser_error (parser, "expected declaration or statement");
+ location_t endloc = c_parser_peek_token (parser)->location;
c_parser_consume_token (parser);
- return;
+ return endloc;
}
while (c_parser_next_token_is_not (parser, CPP_CLOSE_BRACE))
{
@@ -5769,7 +5806,7 @@ c_parser_compound_statement_nostart (c_parser *parser)
{
mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
c_parser_error (parser, "expected declaration or statement");
- return;
+ return c_parser_peek_token (parser)->location;
}
else if (c_parser_next_token_is_keyword (parser, RID_ELSE))
{
@@ -5777,7 +5814,7 @@ c_parser_compound_statement_nostart (c_parser *parser)
{
mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
error_at (loc, "expected %<}%> before %<else%>");
- return;
+ return c_parser_peek_token (parser)->location;
}
else
{
@@ -5800,9 +5837,11 @@ c_parser_compound_statement_nostart (c_parser *parser)
}
if (last_label)
error_at (label_loc, "label at end of compound statement");
+ location_t endloc = c_parser_peek_token (parser)->location;
c_parser_consume_token (parser);
/* Restore the value we started with. */
mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
+ return endloc;
}
/* Parse all consecutive labels, possibly preceded by standard
@@ -6603,7 +6642,7 @@ c_parser_switch_statement (c_parser *parser, bool *if_p)
&& c_token_starts_typename (c_parser_peek_2nd_token (parser)))
explicit_cast_p = true;
ce = c_parser_expression (parser);
- ce = convert_lvalue_to_rvalue (switch_cond_loc, ce, true, false);
+ ce = convert_lvalue_to_rvalue (switch_cond_loc, ce, true, true);
expr = ce.value;
/* ??? expr has no valid location? */
parens.skip_until_found_close (parser);
@@ -7528,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;
}
@@ -7554,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;
@@ -7593,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);
@@ -7612,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;
}
@@ -10447,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)
@@ -11771,15 +11817,28 @@ c_parser_objc_selector_arg (c_parser *parser)
{
tree sel = c_parser_objc_selector (parser);
tree list = NULL_TREE;
- if (sel && c_parser_next_token_is_not (parser, CPP_COLON))
+ if (sel
+ && c_parser_next_token_is_not (parser, CPP_COLON)
+ && c_parser_next_token_is_not (parser, CPP_SCOPE))
return sel;
while (true)
{
- if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
- return list;
- list = chainon (list, build_tree_list (sel, NULL_TREE));
+ if (c_parser_next_token_is (parser, CPP_SCOPE))
+ {
+ c_parser_consume_token (parser);
+ list = chainon (list, build_tree_list (sel, NULL_TREE));
+ list = chainon (list, build_tree_list (NULL_TREE, NULL_TREE));
+ }
+ else
+ {
+ if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
+ return list;
+ list = chainon (list, build_tree_list (sel, NULL_TREE));
+ }
sel = c_parser_objc_selector (parser);
- if (!sel && c_parser_next_token_is_not (parser, CPP_COLON))
+ if (!sel
+ && c_parser_next_token_is_not (parser, CPP_COLON)
+ && c_parser_next_token_is_not (parser, CPP_SCOPE))
break;
}
return list;
@@ -12391,6 +12450,13 @@ c_parser_pragma (c_parser *parser, enum pragma_context context, bool *if_p)
return false;
case PRAGMA_OMP_REQUIRES:
+ if (context != pragma_external)
+ {
+ error_at (c_parser_peek_token (parser)->location,
+ "%<#pragma omp requires%> may only be used at file scope");
+ c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
+ return false;
+ }
c_parser_omp_requires (parser);
return false;
@@ -14720,6 +14786,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;
@@ -14732,16 +14799,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))
@@ -16569,6 +16642,15 @@ c_parser_oacc_declare (c_parser *parser)
break;
}
+ if (!c_check_in_current_scope (decl))
+ {
+ error_at (loc,
+ "%qD must be a variable declared in the same scope as "
+ "%<#pragma acc declare%>", decl);
+ error = true;
+ continue;
+ }
+
if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (decl))
|| lookup_attribute ("omp declare target link",
DECL_ATTRIBUTES (decl)))
@@ -16701,7 +16783,9 @@ c_parser_oacc_enter_exit_data (c_parser *parser, bool enter)
*/
#define OACC_HOST_DATA_CLAUSE_MASK \
- ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_USE_DEVICE) )
+ ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_USE_DEVICE) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT) )
static tree
c_parser_oacc_host_data (location_t loc, c_parser *parser, bool *if_p)
@@ -16910,7 +16994,6 @@ c_parser_oacc_routine (c_parser *parser, enum pragma_context context)
oacc_routine_data data;
data.error_seen = false;
data.fndecl_seen = false;
- data.clauses = NULL_TREE;
data.loc = c_parser_peek_token (parser)->location;
c_parser_consume_pragma (parser);
@@ -18040,8 +18123,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);
@@ -18079,9 +18164,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 %<;%>");
@@ -18102,19 +18189,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:
@@ -18258,8 +18339,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))
@@ -18269,6 +18352,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)
{
@@ -18864,9 +18981,9 @@ c_parser_omp_parallel (location_t loc, c_parser *parser,
stmt = c_finish_omp_parallel (loc,
cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
block);
- OMP_PARALLEL_COMBINED (stmt) = 1;
if (ret == NULL)
return ret;
+ OMP_PARALLEL_COMBINED (stmt) = 1;
return stmt;
}
else if (strcmp (p, "loop") == 0)
@@ -19825,6 +19942,7 @@ check_clauses:
}
pc = &OMP_CLAUSE_CHAIN (*pc);
}
+ cfun->has_omp_target = true;
return true;
}
@@ -21719,13 +21837,13 @@ c_parse_file (void)
Take ownership of START_WITH_PASS, if non-NULL. */
-void
+location_t
c_parser_parse_rtl_body (c_parser *parser, char *start_with_pass)
{
if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
{
free (start_with_pass);
- return;
+ return c_parser_peek_token (parser)->location;
}
location_t start_loc = c_parser_peek_token (parser)->location;
@@ -21747,7 +21865,7 @@ c_parser_parse_rtl_body (c_parser *parser, char *start_with_pass)
case CPP_EOF:
error_at (start_loc, "no closing brace");
free (start_with_pass);
- return;
+ return c_parser_peek_token (parser)->location;
default:
break;
}
@@ -21765,12 +21883,13 @@ c_parser_parse_rtl_body (c_parser *parser, char *start_with_pass)
if (!read_rtl_function_body_from_file_range (start_loc, end_loc))
{
free (start_with_pass);
- return;
+ return end_loc;
}
/* Run the backend on the cfun created above, transferring ownership of
START_WITH_PASS. */
run_rtl_passes (start_with_pass);
+ return end_loc;
}
#include "gt-c-c-parser.h"
diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h
index 7122992..10938cf 100644
--- a/gcc/c/c-tree.h
+++ b/gcc/c/c-tree.h
@@ -38,9 +38,12 @@ along with GCC; see the file COPYING3. If not see
nonzero if the definition of the type has already started. */
#define C_TYPE_BEING_DEFINED(TYPE) TYPE_LANG_FLAG_0 (TYPE)
-/* In an incomplete RECORD_TYPE or UNION_TYPE, a list of variable
- declarations whose type would be completed by completing that type. */
-#define C_TYPE_INCOMPLETE_VARS(TYPE) TYPE_VFIELD (TYPE)
+/* In an incomplete RECORD_TYPE, UNION_TYPE or ENUMERAL_TYPE, a list of
+ variable declarations whose type would be completed by completing
+ that type. */
+#define C_TYPE_INCOMPLETE_VARS(TYPE) \
+ TYPE_LANG_SLOT_1 (TREE_CHECK4 (TYPE, RECORD_TYPE, UNION_TYPE, \
+ QUAL_UNION_TYPE, ENUMERAL_TYPE))
/* In an IDENTIFIER_NODE, nonzero if this identifier is actually a
keyword. C_RID_CODE (node) is then the RID_* value of the keyword. */
@@ -108,7 +111,8 @@ along with GCC; see the file COPYING3. If not see
/* For FUNCTION_TYPE, a hidden list of types of arguments. The same as
TYPE_ARG_TYPES for functions with prototypes, but created for functions
without prototypes. */
-#define TYPE_ACTUAL_ARG_TYPES(NODE) TYPE_LANG_SLOT_1 (NODE)
+#define TYPE_ACTUAL_ARG_TYPES(NODE) \
+ TYPE_LANG_SLOT_1 (FUNCTION_TYPE_CHECK (NODE))
/* For a CONSTRUCTOR, whether some initializer contains a
subexpression meaning it is not a constant expression. */
@@ -576,7 +580,7 @@ extern bool c_check_switch_jump_warnings (struct c_spot_bindings *,
location_t, location_t);
extern void finish_decl (tree, location_t, tree, tree, tree);
extern tree finish_enum (tree, tree, tree);
-extern void finish_function (void);
+extern void finish_function (location_t = input_location);
extern tree finish_struct (location_t, tree, tree, tree,
class c_struct_parse_info *);
extern tree c_simulate_enum_decl (location_t, const char *,
@@ -653,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;
@@ -789,6 +794,7 @@ extern tree c_omp_reduction_id (enum tree_code, tree);
extern tree c_omp_reduction_decl (tree);
extern tree c_omp_reduction_lookup (tree, tree);
extern tree c_check_omp_declare_reduction_r (tree *, int *, void *);
+extern bool c_check_in_current_scope (tree);
extern void c_pushtag (location_t, tree, tree);
extern void c_bind (location_t, tree, bool);
extern bool tag_exists_p (enum tree_code, tree);
diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index c746f23..3be3690c 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;
@@ -353,7 +356,28 @@ c_vla_type_p (const_tree t)
return true;
return false;
}
-
+
+/* If NTYPE is a type of a non-variadic function with a prototype
+ and OTYPE is a type of a function without a prototype and ATTRS
+ contains attribute format, diagnosess and removes it from ATTRS.
+ Returns the result of build_type_attribute_variant of NTYPE and
+ the (possibly) modified ATTRS. */
+
+static tree
+build_functype_attribute_variant (tree ntype, tree otype, tree attrs)
+{
+ if (!prototype_p (otype)
+ && prototype_p (ntype)
+ && lookup_attribute ("format", attrs))
+ {
+ warning_at (input_location, OPT_Wattributes,
+ "%qs attribute cannot be applied to a function that "
+ "does not take variable arguments", "format");
+ attrs = remove_attribute ("format", attrs);
+ }
+ return build_type_attribute_variant (ntype, attrs);
+
+}
/* Return the composite type of two compatible types.
We assume that comptypes has already been done and returned
@@ -504,9 +528,9 @@ composite_type (tree t1, tree t2)
/* Save space: see if the result is identical to one of the args. */
if (valtype == TREE_TYPE (t1) && !TYPE_ARG_TYPES (t2))
- return build_type_attribute_variant (t1, attributes);
+ return build_functype_attribute_variant (t1, t2, attributes);
if (valtype == TREE_TYPE (t2) && !TYPE_ARG_TYPES (t1))
- return build_type_attribute_variant (t2, attributes);
+ return build_functype_attribute_variant (t2, t1, attributes);
/* Simple way if one arg fails to specify argument types. */
if (TYPE_ARG_TYPES (t1) == NULL_TREE)
@@ -5709,10 +5733,14 @@ build_c_cast (location_t loc, tree type, tree expr)
{
tree value;
+ bool int_operands = EXPR_INT_CONST_OPERANDS (expr);
+
if (TREE_CODE (expr) == EXCESS_PRECISION_EXPR)
expr = TREE_OPERAND (expr, 0);
value = expr;
+ if (int_operands)
+ value = remove_c_maybe_const_expr (value);
if (type == error_mark_node || expr == error_mark_node)
return error_mark_node;
@@ -5943,6 +5971,14 @@ build_c_cast (location_t loc, tree type, tree expr)
|| TREE_CODE (expr) == COMPLEX_CST)))
value = build1 (NOP_EXPR, type, value);
+ /* If the expression has integer operands and so can occur in an
+ unevaluated part of an integer constant expression, ensure the
+ return value reflects this. */
+ if (int_operands
+ && INTEGRAL_TYPE_P (type)
+ && !EXPR_INT_CONST_OPERANDS (value))
+ value = note_integer_operands (value);
+
protected_set_expr_location (value, loc);
return value;
}
@@ -6176,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);
@@ -7712,12 +7753,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. */
@@ -8726,7 +8770,7 @@ pop_init_level (location_t loc, int implicit,
the element, after verifying there is just one. */
if (vec_safe_is_empty (constructor_elements))
{
- if (!constructor_erroneous)
+ if (!constructor_erroneous && constructor_type != error_mark_node)
error_init (loc, "empty scalar initializer");
ret.value = error_mark_node;
}
@@ -8803,8 +8847,8 @@ set_designator (location_t loc, bool array,
enum tree_code subcode;
/* Don't die if an entire brace-pair level is superfluous
- in the containing level. */
- if (constructor_type == NULL_TREE)
+ in the containing level, or for an erroneous type. */
+ if (constructor_type == NULL_TREE || constructor_type == error_mark_node)
return true;
/* If there were errors in this designator list already, bail out
@@ -8812,6 +8856,12 @@ set_designator (location_t loc, bool array,
if (designator_erroneous)
return true;
+ /* Likewise for an initializer for a variable-size type. Those are
+ diagnosed in digest_init. */
+ if (COMPLETE_TYPE_P (constructor_type)
+ && TREE_CODE (TYPE_SIZE (constructor_type)) != INTEGER_CST)
+ return true;
+
if (!designator_depth)
{
gcc_assert (!constructor_range_stack);
@@ -9922,8 +9972,14 @@ process_init_element (location_t loc, struct c_expr value, bool implicit,
}
/* Ignore elements of a brace group if it is entirely superfluous
- and has already been diagnosed. */
- if (constructor_type == NULL_TREE)
+ and has already been diagnosed, or if the type is erroneous. */
+ if (constructor_type == NULL_TREE || constructor_type == error_mark_node)
+ return;
+
+ /* Ignore elements of an initializer for a variable-size type.
+ Those are diagnosed in digest_init. */
+ if (COMPLETE_TYPE_P (constructor_type)
+ && !poly_int_tree_p (TYPE_SIZE (constructor_type)))
return;
if (!implicit && warn_designated_init && !was_designated
@@ -12430,7 +12486,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;
@@ -15162,7 +15218,8 @@ c_build_qualified_type (tree type, int type_quals, tree orig_qual_type,
: build_qualified_type (type, type_quals));
/* A variant type does not inherit the list of incomplete vars from the
type main variant. */
- if (RECORD_OR_UNION_TYPE_P (var_type)
+ if ((RECORD_OR_UNION_TYPE_P (var_type)
+ || TREE_CODE (var_type) == ENUMERAL_TYPE)
&& TYPE_MAIN_VARIANT (var_type) != var_type)
C_TYPE_INCOMPLETE_VARS (var_type) = 0;
return var_type;
diff --git a/gcc/c/gimple-parser.c b/gcc/c/gimple-parser.c
index 7e4cd39..577d8b5 100644
--- a/gcc/c/gimple-parser.c
+++ b/gcc/c/gimple-parser.c
@@ -149,12 +149,13 @@ static bool
c_parser_gimple_parse_bb_spec_edge_probability (tree val,
gimple_parser &parser,
int *index,
- profile_probability *probablity)
+ profile_probability
+ *probability)
{
bool return_p = c_parser_gimple_parse_bb_spec (val, index);
if (return_p)
{
- *probablity = profile_probability::uninitialized ();
+ *probability = profile_probability::uninitialized ();
/* Parse frequency if provided. */
if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
{
@@ -188,7 +189,7 @@ c_parser_gimple_parse_bb_spec_edge_probability (tree val,
}
unsigned int value = TREE_INT_CST_LOW (f);
- *probablity = profile_probability (value, quality);
+ *probability = profile_probability (value, quality);
c_parser_consume_token (parser);
if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
@@ -327,7 +328,7 @@ c_parser_parse_gimple_body (c_parser *cparser, char *gimple_pass,
add_phi_arg (phi, gimple_call_arg (stmt, i + 1), e,
UNKNOWN_LOCATION);
}
- gsi_remove (&gsi, false);
+ gsi_remove (&gsi, true);
}
/* Fill SSA name gaps, putting them on the freelist. */
for (unsigned i = 1; i < num_ssa_names; ++i)
@@ -1271,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);
}