diff options
author | Aldy Hernandez <aldyh@redhat.com> | 2020-06-17 07:50:57 -0400 |
---|---|---|
committer | Aldy Hernandez <aldyh@redhat.com> | 2020-06-17 07:50:57 -0400 |
commit | b9e67f2840ce0d8859d96e7f8df8fe9584af5eba (patch) | |
tree | ed3b7284ff15c802583f6409b9c71b3739642d15 /gcc/c | |
parent | 1957047ed1c94bf17cf993a2b1866965f493ba87 (diff) | |
parent | 56638b9b1853666f575928f8baf17f70e4ed3517 (diff) | |
download | gcc-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/ChangeLog | 225 | ||||
-rw-r--r-- | gcc/c/Make-lang.in | 2 | ||||
-rw-r--r-- | gcc/c/c-decl.c | 254 | ||||
-rw-r--r-- | gcc/c/c-fold.c | 10 | ||||
-rw-r--r-- | gcc/c/c-objc-common.h | 3 | ||||
-rw-r--r-- | gcc/c/c-parser.c | 233 | ||||
-rw-r--r-- | gcc/c/c-tree.h | 16 | ||||
-rw-r--r-- | gcc/c/c-typeck.c | 99 | ||||
-rw-r--r-- | gcc/c/gimple-parser.c | 12 |
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); } |