From 0a9d711df36b42b6494b73a90c7ebf050e904493 Mon Sep 17 00:00:00 2001 From: Sunil K Pandey Date: Fri, 17 Jul 2020 19:42:09 -0700 Subject: Add TARGET_LOWER_LOCAL_DECL_ALIGNMENT [PR95237] Default for this hook is NOP. For x86, in 32 bit mode, this hook sets alignment of long long on stack to 32 bits if preferred stack boundary is 32 bits. - This patch prevents lowering of alignment from following macros. LOCAL_ALIGNMENT STACK_SLOT_ALIGNMENT LOCAL_DECL_ALIGNMENT - This patch fixes gcc.target/i386/pr69454-2.c gcc.target/i386/stackalign/longlong-1.c - Regression test on x86-64, no new fail introduced. Tested on x86-64. gcc/c/ChangeLog: PR target/95237 * c-decl.c (finish_decl): Call target hook lower_local_decl_alignment to lower local decl alignment. gcc/ChangeLog: PR target/95237 * config/i386/i386-protos.h (ix86_local_alignment): Add another function parameter may_lower alignment. Default is false. * config/i386/i386.c (ix86_lower_local_decl_alignment): New function. (ix86_local_alignment): Amend ix86_local_alignment to accept another parameter may_lower. If may_lower is true, new align may be lower than incoming alignment. If may_lower is false, new align will be greater or equal to incoming alignment. (TARGET_LOWER_LOCAL_DECL_ALIGNMENT): Define. * doc/tm.texi: Regenerate. * doc/tm.texi.in (TARGET_LOWER_LOCAL_DECL_ALIGNMENT): New hook. * target.def (lower_local_decl_alignment): New hook. gcc/cp/ChangeLog: PR target/95237 * decl.c (cp_finish_decl): Call target hook lower_local_decl_alignment to lower local decl alignment. gcc/testsuite/ChangeLog: PR target/95237 * c-c++-common/pr95237-1.c: New test. * c-c++-common/pr95237-2.c: New test. * c-c++-common/pr95237-3.c: New test. * c-c++-common/pr95237-4.c: New test. * c-c++-common/pr95237-5.c: New test. * c-c++-common/pr95237-6.c: New test. * c-c++-common/pr95237-7.c: New test. * c-c++-common/pr95237-8.c: New test. * c-c++-common/pr95237-9.c: New test. --- gcc/c/c-decl.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'gcc/c') diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c index 81bd2ee..5d6b504 100644 --- a/gcc/c/c-decl.c +++ b/gcc/c/c-decl.c @@ -5600,6 +5600,13 @@ finish_decl (tree decl, location_t init_loc, tree init, NULL_TREE, DECL_ATTRIBUTES (decl)); } + /* This is the last point we can lower alignment so give the target the + chance to do so. */ + if (VAR_P (decl) + && !is_global_var (decl) + && !DECL_HARD_REGISTER (decl)) + targetm.lower_local_decl_alignment (decl); + invoke_plugin_callbacks (PLUGIN_FINISH_DECL, decl); } -- cgit v1.1 From 3043006104023797c8193700aace6bf254139bc4 Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Wed, 22 Jul 2020 00:16:27 +0000 Subject: Daily bump. --- gcc/c/ChangeLog | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'gcc/c') diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 8e179a3..9478dcd 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,9 @@ +2020-07-21 Sunil K Pandey + + PR target/95237 + * c-decl.c (finish_decl): Call target hook + lower_local_decl_alignment to lower local decl alignment. + 2020-07-09 Julian Brown Thomas Schwinge -- cgit v1.1 From c7c24828cfa4983ebc6744be3f913d0da6ff7163 Mon Sep 17 00:00:00 2001 From: Tobias Burnus Date: Tue, 21 Jul 2020 18:29:53 +0200 Subject: OpenMP: Fixes for omp critical + hint gcc/c-family/ChangeLog: * c-omp.c (c_finish_omp_critical): Check for no name but nonzero hint provided. gcc/c/ChangeLog: * c-parser.c (c_parser_omp_clause_hint): Require nonnegative hint clause. (c_parser_omp_critical): Permit hint(0) clause without named critical. (c_parser_omp_construct): Don't assert if error_mark_node is returned. gcc/cp/ChangeLog: * parser.c (cp_parser_omp_clause_hint): Require nonnegative hint. (cp_parser_omp_critical): Permit hint(0) clause without named critical. * pt.c (tsubst_expr): Re-check the latter for templates. gcc/fortran/ChangeLog: * openmp.c (gfc_match_omp_critical): Fix handling hints; permit hint clause without named critical. (resolve_omp_clauses): Require nonnegative constant integer for the hint clause. (gfc_resolve_omp_directive): Check for no name but nonzero value for hint clause. * parse.c (parse_omp_structured_block): Fix same-name check for critical. * trans-openmp.c (gfc_trans_omp_critical): Handle hint clause properly. libgomp/ChangeLog: * omp_lib.f90.in: Add omp_sync_hint_* and omp_sync_hint_kind. * omp_lib.h.in: Likewise. gcc/testsuite/ChangeLog: * g++.dg/gomp/critical-3.C: Add nameless critical with hint testcase. * c-c++-common/gomp/critical-hint-1.c: New test. * c-c++-common/gomp/critical-hint-2.c: New test. * gfortran.dg/gomp/critical-hint-1.f90: New test. * gfortran.dg/gomp/critical-hint-2.f90: New test. --- gcc/c/c-parser.c | 26 ++++++++------------------ 1 file changed, 8 insertions(+), 18 deletions(-) (limited to 'gcc/c') diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index 275b8a3..7961cbc 100644 --- a/gcc/c/c-parser.c +++ b/gcc/c/c-parser.c @@ -13901,16 +13901,15 @@ c_parser_omp_clause_hint (c_parser *parser, tree list) expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true); tree c, t = expr.value; t = c_fully_fold (t, false, NULL); - - parens.skip_until_found_close (parser); - if (!INTEGRAL_TYPE_P (TREE_TYPE (t)) - || TREE_CODE (t) != INTEGER_CST) + || TREE_CODE (t) != INTEGER_CST + || tree_int_cst_sgn (t) == -1) { - c_parser_error (parser, "expected constant integer expression"); + c_parser_error (parser, "expected constant integer expression " + "with valid sync-hint value"); return list; } - + parens.skip_until_found_close (parser); check_no_duplicate_clause (list, OMP_CLAUSE_HINT, "hint"); c = build_omp_clause (hint_loc, OMP_CLAUSE_HINT); @@ -17795,18 +17794,9 @@ c_parser_omp_critical (location_t loc, c_parser *parser, bool *if_p) if (c_parser_next_token_is (parser, CPP_COMMA) && c_parser_peek_2nd_token (parser)->type == CPP_NAME) c_parser_consume_token (parser); - - clauses = c_parser_omp_all_clauses (parser, - OMP_CRITICAL_CLAUSE_MASK, - "#pragma omp critical"); } - else - { - if (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL)) - c_parser_error (parser, "expected %<(%> or end of line"); - c_parser_skip_to_pragma_eol (parser); - } - + clauses = c_parser_omp_all_clauses (parser, OMP_CRITICAL_CLAUSE_MASK, + "#pragma omp critical"); stmt = c_parser_omp_structured_block (parser, if_p); return c_finish_omp_critical (loc, stmt, name, clauses); } @@ -21537,7 +21527,7 @@ c_parser_omp_construct (c_parser *parser, bool *if_p) gcc_unreachable (); } - if (stmt) + if (stmt && stmt != error_mark_node) gcc_assert (EXPR_LOCATION (stmt) != UNKNOWN_LOCATION); } -- cgit v1.1 From 3ea9abca71f7bbdf70c97b4cc73f86faf24b0dc0 Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Thu, 23 Jul 2020 00:16:28 +0000 Subject: Daily bump. --- gcc/c/ChangeLog | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'gcc/c') diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 9478dcd..dea0429 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,9 @@ +2020-07-22 Tobias Burnus + + * c-parser.c (c_parser_omp_clause_hint): Require nonnegative hint clause. + (c_parser_omp_critical): Permit hint(0) clause without named critical. + (c_parser_omp_construct): Don't assert if error_mark_node is returned. + 2020-07-21 Sunil K Pandey PR target/95237 -- cgit v1.1 From c6ef9d8d3f11221df1ea6358b8d4e79e42f074fb Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Thu, 30 Jul 2020 11:46:43 +0200 Subject: debug/96383 - emit debug info for used external functions This makes sure to emit full declaration DIEs including formal parameters for used external functions. This helps debugging when debug information of the external entity is not available and also helps external tools cross-checking ABI compatibility which was the bug reporters use case. For cc1 this affects debug information size as follows: VM SIZE FILE SIZE ++++++++++++++ GROWING ++++++++++++++ [ = ] 0 .debug_info +1.63Mi +1.3% [ = ] 0 .debug_str +263Ki +3.4% [ = ] 0 .debug_abbrev +101Ki +4.9% [ = ] 0 .debug_line +5.71Ki +0.0% +44% +16 [Unmapped] +48 +1.2% -------------- SHRINKING -------------- [ = ] 0 .debug_loc -213 -0.0% -0.0% -48 .text -48 -0.0% [ = ] 0 .debug_ranges -16 -0.0% -0.0% -32 TOTAL +1.99Mi +0.6% and DWARF compression via DWZ can only shave off minor bits here. Previously we emitted no DIEs for external functions at all unless they were referenced via DW_TAG_GNU_call_site which for some GCC revs caused a regular DIE to appear and since GCC 4.9 only a stub without formal parameters. This means at -O0 we did not emit any DIE for external functions but with optimization we emitted stubs. 2020-07-30 Richard Biener PR debug/96383 * langhooks-def.h (lhd_finalize_early_debug): Declare. (LANG_HOOKS_FINALIZE_EARLY_DEBUG): Define. (LANG_HOOKS_INITIALIZER): Amend. * langhooks.c: Include cgraph.h and debug.h. (lhd_finalize_early_debug): Default implementation from former code in finalize_compilation_unit. * langhooks.h (lang_hooks::finalize_early_debug): Add. * cgraphunit.c (symbol_table::finalize_compilation_unit): Call the finalize_early_debug langhook. gcc/c-family/ * c-common.h (c_common_finalize_early_debug): Declare. * c-common.c: Include debug.h. (c_common_finalize_early_debug): finalize_early_debug langhook implementation generating debug for extern declarations. gcc/c/ * c-objc-common.h (LANG_HOOKS_FINALIZE_EARLY_DEBUG): Define to c_common_finalize_early_debug. gcc/cp/ * cp-objcp-common.h (LANG_HOOKS_FINALIZE_EARLY_DEBUG): Define to c_common_finalize_early_debug. gcc/testsuite/ * gcc.dg/debug/dwarf2/pr96383-1.c: New testcase. * gcc.dg/debug/dwarf2/pr96383-2.c: Likewise. libstdc++-v3/ * testsuite/20_util/assume_aligned/3.cc: Use -g0. --- gcc/c/c-objc-common.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'gcc/c') diff --git a/gcc/c/c-objc-common.h b/gcc/c/c-objc-common.h index 5471fc7..9257959 100644 --- a/gcc/c/c-objc-common.h +++ b/gcc/c/c-objc-common.h @@ -65,6 +65,8 @@ along with GCC; see the file COPYING3. If not see c_simulate_builtin_function_decl #undef LANG_HOOKS_EMITS_BEGIN_STMT #define LANG_HOOKS_EMITS_BEGIN_STMT true +#undef LANG_HOOKS_FINALIZE_EARLY_DEBUG +#define LANG_HOOKS_FINALIZE_EARLY_DEBUG c_common_finalize_early_debug /* Attribute hooks. */ #undef LANG_HOOKS_COMMON_ATTRIBUTE_TABLE -- cgit v1.1 From 48cc2e468cca54ae930e64be01f3b183df2198fb Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Sat, 1 Aug 2020 00:16:25 +0000 Subject: Daily bump. --- gcc/c/ChangeLog | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'gcc/c') diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index dea0429..18eeb1b 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,9 @@ +2020-07-31 Richard Biener + + PR debug/96383 + * c-objc-common.h (LANG_HOOKS_FINALIZE_EARLY_DEBUG): + Define to c_common_finalize_early_debug. + 2020-07-22 Tobias Burnus * c-parser.c (c_parser_omp_clause_hint): Require nonnegative hint clause. -- cgit v1.1 From 7d599ad27b9bcf5165f87710f1abc64bbabd06ae Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Sat, 1 Aug 2020 12:41:28 +0100 Subject: c: Fix bogus vector initialisation error [PR96377] One of the problems in this PR was that if we had: vector_type1 array[] = { vector_value1 }; process_init_element would only treat vector_value1 as initialising a vector_type1 if they had the same TYPE_MAIN_VARIANT. This has several problems: (1) It gives confusing error messages if the vector types are incompatible. (Tested by gcc.dg/pr96377-1.c.) (2) It means that we reject code that should be valid with -flax-vector-conversions. (Tested by gcc.dg/pr96377-2.c.) (3) On arm and aarch64 targets, it means that we reject some initializers that mix Advanced SIMD and standard GNU vectors. These vectors have traditionally had different TYPE_MAIN_VARIANTs because they have different mangling schemes. (Tested by gcc.dg/pr96377-[3-6].c.) (4) It means that we reject SVE initializers that should be valid. (Tested by gcc.target/aarch64/sve/gnu_vectors_[34].c.) (5) After r11-1741-g:31427b974ed7b7dd54e2 we reject: arm_neon_type1 array[] = { k ^ arm_neon_value1 }; because applying the binary operator to arm_neon_value1 strips the "Advanced SIMD type" attributes that were added in that patch. Stripping the attributes is problematic for other reasons though, so that still needs to be fixed separately. g++.target/aarch64/sve/gnu_vectors_[34].C already pass. gcc/c/ PR c/96377 * c-typeck.c (process_init_element): Split test for whether to recurse into a record, union or array into... (initialize_elementwise_p): ...this new function. Don't recurse into a vector type if the initialization value is also a vector. gcc/testsuite/ PR c/96377 * gcc.dg/pr96377-1.c: New test. * gcc.dg/pr96377-2.c: Likewise. * gcc.dg/pr96377-3.c: Likewise. * gcc.dg/pr96377-4.c: Likewise. * gcc.dg/pr96377-5.c: Likewise. * gcc.dg/pr96377-6.c: Likewise. * gcc.target/aarch64/pr96377-1.c: Likewise. * gcc.target/aarch64/sve/acle/general-c/gnu_vectors_3.c: Likewise. * gcc.target/aarch64/sve/acle/general-c/gnu_vectors_4.c: Likewise. * g++.target/aarch64/sve/acle/general-c++/gnu_vectors_3.C: Likewise. * g++.target/aarch64/sve/acle/general-c++/gnu_vectors_4.C: Likewise. --- gcc/c/c-typeck.c | 59 ++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 44 insertions(+), 15 deletions(-) (limited to 'gcc/c') diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c index fb5c288..0d639b60 100644 --- a/gcc/c/c-typeck.c +++ b/gcc/c/c-typeck.c @@ -9956,6 +9956,47 @@ output_pending_init_elements (int all, struct obstack * braced_init_obstack) goto retry; } +/* Expression VALUE coincides with the start of type TYPE in a braced + initializer. Return true if we should treat VALUE as initializing + the first element of TYPE, false if we should treat it as initializing + TYPE as a whole. + + If the initializer is clearly invalid, the question becomes: + which choice gives the best error message? */ + +static bool +initialize_elementwise_p (tree type, tree value) +{ + if (type == error_mark_node || value == error_mark_node) + return false; + + gcc_checking_assert (TYPE_MAIN_VARIANT (type) == type); + + tree value_type = TREE_TYPE (value); + if (value_type == error_mark_node) + return false; + + /* GNU vectors can be initialized elementwise. However, treat any + kind of vector value as initializing the vector type as a whole, + regardless of whether the value is a GNU vector. Such initializers + are valid if and only if they would have been valid in a non-braced + initializer like: + + TYPE foo = VALUE; + + so recursing into the vector type would be at best confusing or at + worst wrong. For example, when -flax-vector-conversions is in effect, + it's possible to initialize a V8HI from a V4SI, even though the vectors + have different element types and different numbers of elements. */ + if (gnu_vector_type_p (type)) + return !VECTOR_TYPE_P (value_type); + + if (AGGREGATE_TYPE_P (type)) + return type != TYPE_MAIN_VARIANT (value_type); + + return false; +} + /* Add one non-braced element to the current constructor level. This adjusts the current position within the constructor's type. This may also start or terminate implicit levels @@ -10135,11 +10176,7 @@ process_init_element (location_t loc, struct c_expr value, bool implicit, /* Otherwise, if we have come to a subaggregate, and we don't have an element of its type, push into it. */ else if (value.value != NULL_TREE - && value.value != error_mark_node - && TYPE_MAIN_VARIANT (TREE_TYPE (value.value)) != fieldtype - && (fieldcode == RECORD_TYPE || fieldcode == ARRAY_TYPE - || fieldcode == UNION_TYPE - || gnu_vector_type_p (fieldtype))) + && initialize_elementwise_p (fieldtype, value.value)) { push_init_level (loc, 1, braced_init_obstack); continue; @@ -10227,11 +10264,7 @@ process_init_element (location_t loc, struct c_expr value, bool implicit, /* Otherwise, if we have come to a subaggregate, and we don't have an element of its type, push into it. */ else if (value.value != NULL_TREE - && value.value != error_mark_node - && TYPE_MAIN_VARIANT (TREE_TYPE (value.value)) != fieldtype - && (fieldcode == RECORD_TYPE || fieldcode == ARRAY_TYPE - || fieldcode == UNION_TYPE - || gnu_vector_type_p (fieldtype))) + && initialize_elementwise_p (fieldtype, value.value)) { push_init_level (loc, 1, braced_init_obstack); continue; @@ -10270,11 +10303,7 @@ process_init_element (location_t loc, struct c_expr value, bool implicit, /* Otherwise, if we have come to a subaggregate, and we don't have an element of its type, push into it. */ else if (value.value != NULL_TREE - && value.value != error_mark_node - && TYPE_MAIN_VARIANT (TREE_TYPE (value.value)) != elttype - && (eltcode == RECORD_TYPE || eltcode == ARRAY_TYPE - || eltcode == UNION_TYPE - || gnu_vector_type_p (elttype))) + && initialize_elementwise_p (elttype, value.value)) { push_init_level (loc, 1, braced_init_obstack); continue; -- cgit v1.1 From 4967ca2f8b2e13324258786a90c46f62abce2b7d Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Sun, 2 Aug 2020 00:16:21 +0000 Subject: Daily bump. --- gcc/c/ChangeLog | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'gcc/c') diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 18eeb1b..e80c040 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,11 @@ +2020-08-01 Richard Sandiford + + PR c/96377 + * c-typeck.c (process_init_element): Split test for whether to + recurse into a record, union or array into... + (initialize_elementwise_p): ...this new function. Don't recurse + into a vector type if the initialization value is also a vector. + 2020-07-31 Richard Biener PR debug/96383 -- cgit v1.1 From 6d42cbe5ad7a7b46437f2576c9920e44dc14b386 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Tue, 18 Aug 2020 07:51:58 +0200 Subject: c: Fix -Wunused-but-set-* warning with _Generic [PR96571] The following testcase shows various problems with -Wunused-but-set* warnings and _Generic construct. I think it is best to treat the selector and the ignored expressions as (potentially) read, because when they are parsed, the vars in there are already marked as TREE_USED. 2020-08-18 Jakub Jelinek PR c/96571 * c-parser.c (c_parser_generic_selection): Change match_found from bool to int, holding index of the match. Call mark_exp_read on the selector expression and on expressions other than the selected one. * gcc.dg/Wunused-var-4.c: New test. --- gcc/c/c-parser.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) (limited to 'gcc/c') diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index 7961cbc..a8bc301 100644 --- a/gcc/c/c-parser.c +++ b/gcc/c/c-parser.c @@ -8686,7 +8686,7 @@ c_parser_generic_selection (c_parser *parser) struct c_expr selector, error_expr; tree selector_type; struct c_generic_association matched_assoc; - bool match_found = false; + int match_found = -1; location_t generic_loc, selector_loc; error_expr.original_code = ERROR_MARK; @@ -8721,6 +8721,7 @@ c_parser_generic_selection (c_parser *parser) c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); return selector; } + mark_exp_read (selector.value); selector_type = TREE_TYPE (selector.value); /* In ISO C terms, rvalues (including the controlling expression of _Generic) do not have qualified types. */ @@ -8820,18 +8821,18 @@ c_parser_generic_selection (c_parser *parser) if (assoc.type == NULL_TREE) { - if (!match_found) + if (match_found < 0) { matched_assoc = assoc; - match_found = true; + match_found = associations.length (); } } else if (comptypes (assoc.type, selector_type)) { - if (!match_found || matched_assoc.type == NULL_TREE) + if (match_found < 0 || matched_assoc.type == NULL_TREE) { matched_assoc = assoc; - match_found = true; + match_found = associations.length (); } else { @@ -8849,13 +8850,19 @@ c_parser_generic_selection (c_parser *parser) c_parser_consume_token (parser); } + unsigned int ix; + struct c_generic_association *iter; + FOR_EACH_VEC_ELT (associations, ix, iter) + if (ix != (unsigned) match_found) + mark_exp_read (iter->expression.value); + if (!parens.require_close (parser)) { c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); return error_expr; } - if (!match_found) + if (match_found < 0) { error_at (selector_loc, "%<_Generic%> selector of type %qT is not " "compatible with any association", -- cgit v1.1 From 5c265693bfa8e5f205e81c0452d54800334c32a9 Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Wed, 19 Aug 2020 00:16:23 +0000 Subject: Daily bump. --- gcc/c/ChangeLog | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'gcc/c') diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index e80c040..7839b9b 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,10 @@ +2020-08-18 Jakub Jelinek + + PR c/96571 + * c-parser.c (c_parser_generic_selection): Change match_found from bool + to int, holding index of the match. Call mark_exp_read on the selector + expression and on expressions other than the selected one. + 2020-08-01 Richard Sandiford PR c/96377 -- cgit v1.1 From 3d5ed337cb354c2f85a9caf60377bad887b18d53 Mon Sep 17 00:00:00 2001 From: Tobias Burnus Date: Tue, 25 Aug 2020 17:46:13 +0200 Subject: OpenMP: Improve map-clause error message for array function parameter (PR96678) gcc/c/ChangeLog: PR c/96678 * c-typeck.c (handle_omp_array_sections_1): Talk about array function parameter in the error message. gcc/cp/ChangeLog: PR c/96678 * semantics.c (handle_omp_array_sections_1): Talk about array function parameter in the error message. gcc/testsuite/ChangeLog: PR c/96678 * c-c++-common/gomp/map-4.c: New test. * c-c++-common/gomp/depend-1.c: Update dg-error. * c-c++-common/gomp/map-1.c: Likewise. * c-c++-common/gomp/reduction-1.c: Likewise. * g++.dg/gomp/depend-1.C: Likewise. * g++.dg/gomp/depend-2.C: Likewise. --- gcc/c/c-typeck.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'gcc/c') diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c index 0d639b60..e158d23 100644 --- a/gcc/c/c-typeck.c +++ b/gcc/c/c-typeck.c @@ -13298,8 +13298,13 @@ handle_omp_array_sections_1 (tree c, tree t, vec &types, { if (length == NULL_TREE) { - error_at (OMP_CLAUSE_LOCATION (c), - "for pointer type length expression must be specified"); + if (C_ARRAY_PARAMETER (ret)) + error_at (OMP_CLAUSE_LOCATION (c), + "for array function parameter length expression " + "must be specified"); + else + error_at (OMP_CLAUSE_LOCATION (c), + "for pointer type length expression must be specified"); return error_mark_node; } if (length != NULL_TREE -- cgit v1.1 From db0f6efe7a049744b735d8bc69b205a417236c33 Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Wed, 26 Aug 2020 00:16:32 +0000 Subject: Daily bump. --- gcc/c/ChangeLog | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'gcc/c') diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 7839b9b..b04b6fd 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,9 @@ +2020-08-25 Tobias Burnus + + PR c/96678 + * c-typeck.c (handle_omp_array_sections_1): Talk about + array function parameter in the error message. + 2020-08-18 Jakub Jelinek PR c/96571 -- cgit v1.1 From cb3874dcf82bc80c2552ef62f57cf08c28fc686a Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Mon, 10 Aug 2020 11:11:05 +0200 Subject: vec: add exact argument for various grow functions. gcc/ada/ChangeLog: * gcc-interface/trans.c (gigi): Set exact argument of a vector growth function to true. (Attribute_to_gnu): Likewise. gcc/ChangeLog: * alias.c (init_alias_analysis): Set exact argument of a vector growth function to true. * calls.c (internal_arg_pointer_based_exp_scan): Likewise. * cfgbuild.c (find_many_sub_basic_blocks): Likewise. * cfgexpand.c (expand_asm_stmt): Likewise. * cfgrtl.c (rtl_create_basic_block): Likewise. * combine.c (combine_split_insns): Likewise. (combine_instructions): Likewise. * config/aarch64/aarch64-sve-builtins.cc (function_expander::add_output_operand): Likewise. (function_expander::add_input_operand): Likewise. (function_expander::add_integer_operand): Likewise. (function_expander::add_address_operand): Likewise. (function_expander::add_fixed_operand): Likewise. * df-core.c (df_worklist_dataflow_doublequeue): Likewise. * dwarf2cfi.c (update_row_reg_save): Likewise. * early-remat.c (early_remat::init_block_info): Likewise. (early_remat::finalize_candidate_indices): Likewise. * except.c (sjlj_build_landing_pads): Likewise. * final.c (compute_alignments): Likewise. (grow_label_align): Likewise. * function.c (temp_slots_at_level): Likewise. * fwprop.c (build_single_def_use_links): Likewise. (update_uses): Likewise. * gcc.c (insert_wrapper): Likewise. * genautomata.c (create_state_ainsn_table): Likewise. (add_vect): Likewise. (output_dead_lock_vect): Likewise. * genmatch.c (capture_info::capture_info): Likewise. (parser::finish_match_operand): Likewise. * genrecog.c (optimize_subroutine_group): Likewise. (merge_pattern_info::merge_pattern_info): Likewise. (merge_into_decision): Likewise. (print_subroutine_start): Likewise. (main): Likewise. * gimple-loop-versioning.cc (loop_versioning::loop_versioning): Likewise. * gimple.c (gimple_set_bb): Likewise. * graphite-isl-ast-to-gimple.c (translate_isl_ast_node_user): Likewise. * haifa-sched.c (sched_extend_luids): Likewise. (extend_h_i_d): Likewise. * insn-addr.h (insn_addresses_new): Likewise. * ipa-cp.c (gather_context_independent_values): Likewise. (find_more_contexts_for_caller_subset): Likewise. * ipa-devirt.c (final_warning_record::grow_type_warnings): Likewise. (ipa_odr_read_section): Likewise. * ipa-fnsummary.c (evaluate_properties_for_edge): Likewise. (ipa_fn_summary_t::duplicate): Likewise. (analyze_function_body): Likewise. (ipa_merge_fn_summary_after_inlining): Likewise. (read_ipa_call_summary): Likewise. * ipa-icf.c (sem_function::bb_dict_test): Likewise. * ipa-prop.c (ipa_alloc_node_params): Likewise. (parm_bb_aa_status_for_bb): Likewise. (ipa_compute_jump_functions_for_edge): Likewise. (ipa_analyze_node): Likewise. (update_jump_functions_after_inlining): Likewise. (ipa_read_edge_info): Likewise. (read_ipcp_transformation_info): Likewise. (ipcp_transform_function): Likewise. * ipa-reference.c (ipa_reference_write_optimization_summary): Likewise. * ipa-split.c (execute_split_functions): Likewise. * ira.c (find_moveable_pseudos): Likewise. * lower-subreg.c (decompose_multiword_subregs): Likewise. * lto-streamer-in.c (input_eh_regions): Likewise. (input_cfg): Likewise. (input_struct_function_base): Likewise. (input_function): Likewise. * modulo-sched.c (set_node_sched_params): Likewise. (extend_node_sched_params): Likewise. (schedule_reg_moves): Likewise. * omp-general.c (omp_construct_simd_compare): Likewise. * passes.c (pass_manager::create_pass_tab): Likewise. (enable_disable_pass): Likewise. * predict.c (determine_unlikely_bbs): Likewise. * profile.c (compute_branch_probabilities): Likewise. * read-rtl-function.c (function_reader::parse_block): Likewise. * read-rtl.c (rtx_reader::read_rtx_code): Likewise. * reg-stack.c (stack_regs_mentioned): Likewise. * regrename.c (regrename_init): Likewise. * rtlanal.c (T>::add_single_to_queue): Likewise. * sched-deps.c (init_deps_data_vector): Likewise. * sel-sched-ir.c (sel_extend_global_bb_info): Likewise. (extend_region_bb_info): Likewise. (extend_insn_data): Likewise. * symtab.c (symtab_node::create_reference): Likewise. * tracer.c (tail_duplicate): Likewise. * trans-mem.c (tm_region_init): Likewise. (get_bb_regions_instrumented): Likewise. * tree-cfg.c (init_empty_tree_cfg_for_function): Likewise. (build_gimple_cfg): Likewise. (create_bb): Likewise. (move_block_to_fn): Likewise. * tree-complex.c (tree_lower_complex): Likewise. * tree-if-conv.c (predicate_rhs_code): Likewise. * tree-inline.c (copy_bb): Likewise. * tree-into-ssa.c (get_ssa_name_ann): Likewise. (mark_phi_for_rewrite): Likewise. * tree-object-size.c (compute_builtin_object_size): Likewise. (init_object_sizes): Likewise. * tree-predcom.c (initialize_root_vars_store_elim_1): Likewise. (initialize_root_vars_store_elim_2): Likewise. (prepare_initializers_chain_store_elim): Likewise. * tree-ssa-address.c (addr_for_mem_ref): Likewise. (multiplier_allowed_in_address_p): Likewise. * tree-ssa-coalesce.c (ssa_conflicts_new): Likewise. * tree-ssa-forwprop.c (simplify_vector_constructor): Likewise. * tree-ssa-loop-ivopts.c (addr_offset_valid_p): Likewise. (get_address_cost_ainc): Likewise. * tree-ssa-loop-niter.c (discover_iteration_bound_by_body_walk): Likewise. * tree-ssa-pre.c (add_to_value): Likewise. (phi_translate_1): Likewise. (do_pre_regular_insertion): Likewise. (do_pre_partial_partial_insertion): Likewise. (init_pre): Likewise. * tree-ssa-propagate.c (ssa_prop_init): Likewise. (update_call_from_tree): Likewise. * tree-ssa-reassoc.c (optimize_range_tests_cmp_bitwise): Likewise. * tree-ssa-sccvn.c (vn_reference_lookup_3): Likewise. (vn_reference_lookup_pieces): Likewise. (eliminate_dom_walker::eliminate_push_avail): Likewise. * tree-ssa-strlen.c (set_strinfo): Likewise. (get_stridx_plus_constant): Likewise. (zero_length_string): Likewise. (find_equal_ptrs): Likewise. (printf_strlen_execute): Likewise. * tree-ssa-threadedge.c (set_ssa_name_value): Likewise. * tree-ssanames.c (make_ssa_name_fn): Likewise. * tree-streamer-in.c (streamer_read_tree_bitfields): Likewise. * tree-vect-loop.c (vect_record_loop_mask): Likewise. (vect_get_loop_mask): Likewise. (vect_record_loop_len): Likewise. (vect_get_loop_len): Likewise. * tree-vect-patterns.c (vect_recog_mask_conversion_pattern): Likewise. * tree-vect-slp.c (vect_slp_convert_to_external): Likewise. (vect_bb_slp_scalar_cost): Likewise. (vect_bb_vectorization_profitable_p): Likewise. (vectorizable_slp_permutation): Likewise. * tree-vect-stmts.c (vectorizable_call): Likewise. (vectorizable_simd_clone_call): Likewise. (scan_store_can_perm_p): Likewise. (vectorizable_store): Likewise. * expr.c: Likewise. * vec.c (test_safe_grow_cleared): Likewise. * vec.h (vec_safe_grow): Likewise. (vec_safe_grow_cleared): Likewise. (vl_ptr>::safe_grow): Likewise. (vl_ptr>::safe_grow_cleared): Likewise. * config/c6x/c6x.c (insn_set_clock): Likewise. gcc/c/ChangeLog: * gimple-parser.c (c_parser_gimple_compound_statement): Set exact argument of a vector growth function to true. gcc/cp/ChangeLog: * class.c (build_vtbl_initializer): Set exact argument of a vector growth function to true. * constraint.cc (get_mapped_args): Likewise. * decl.c (cp_maybe_mangle_decomp): Likewise. (cp_finish_decomp): Likewise. * parser.c (cp_parser_omp_for_loop): Likewise. * pt.c (canonical_type_parameter): Likewise. * rtti.c (get_pseudo_ti_init): Likewise. gcc/fortran/ChangeLog: * trans-openmp.c (gfc_trans_omp_do): Set exact argument of a vector growth function to true. gcc/lto/ChangeLog: * lto-common.c (lto_file_finalize): Set exact argument of a vector growth function to true. --- gcc/c/gimple-parser.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'gcc/c') diff --git a/gcc/c/gimple-parser.c b/gcc/c/gimple-parser.c index 577d8b5..5c0ed82 100644 --- a/gcc/c/gimple-parser.c +++ b/gcc/c/gimple-parser.c @@ -590,7 +590,7 @@ c_parser_gimple_compound_statement (gimple_parser &parser, gimple_seq *seq) : ENTRY_BLOCK_PTR_FOR_FN (cfun))); if (basic_block_info_for_fn (cfun)->length () <= (size_t)index) vec_safe_grow_cleared (basic_block_info_for_fn (cfun), - index + 1); + index + 1, true); SET_BASIC_BLOCK_FOR_FN (cfun, index, bb); if (last_basic_block_for_fn (cfun) <= index) last_basic_block_for_fn (cfun) = index + 1; @@ -617,7 +617,7 @@ c_parser_gimple_compound_statement (gimple_parser &parser, gimple_seq *seq) loop->num = is_loop_header_of; loop->header = bb; vec_safe_grow_cleared (loops_for_fn (cfun)->larray, - is_loop_header_of + 1); + is_loop_header_of + 1, true); (*loops_for_fn (cfun)->larray)[is_loop_header_of] = loop; flow_loop_tree_node_add (loops_for_fn (cfun)->tree_root, loop); -- cgit v1.1 From 8b394f011a8d4fd578914b057f26e572f8767b99 Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Fri, 28 Aug 2020 00:16:24 +0000 Subject: Daily bump. --- gcc/c/ChangeLog | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'gcc/c') diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index b04b6fd..91a278e 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,8 @@ +2020-08-27 Martin Liska + + * gimple-parser.c (c_parser_gimple_compound_statement): Set exact argument of a vector + growth function to true. + 2020-08-25 Tobias Burnus PR c/96678 -- cgit v1.1 From ba6373a39782139789f0eeba7c0e607ec6dfb477 Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Fri, 28 Aug 2020 08:26:32 -0600 Subject: PR c/96596 - ICE in match_builtin_function_types on a declaration of a built-in with invalid array argument gcc/c/ChangeLog: PR c/96596 * c-decl.c (match_builtin_function_types): Avoid dealing with erroneous argument type. gcc/testsuite/ChangeLog: PR c/96596 * gcc.dg/Wbuiltin-declaration-mismatch-16.c: New test. --- gcc/c/c-decl.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'gcc/c') diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c index 5d6b504..190c00b 100644 --- a/gcc/c/c-decl.c +++ b/gcc/c/c-decl.c @@ -1712,7 +1712,10 @@ match_builtin_function_types (tree newtype, tree oldtype, return NULL_TREE; tree oldtype = TYPE_MAIN_VARIANT (TREE_VALUE (oldargs)); - tree newtype = TYPE_MAIN_VARIANT (TREE_VALUE (newargs)); + tree newtype = TREE_VALUE (newargs); + if (newtype == error_mark_node) + return NULL_TREE; + newtype = TYPE_MAIN_VARIANT (newtype); if (!types_close_enough_to_match (oldtype, newtype)) return NULL_TREE; -- cgit v1.1 From 8f7ea26ae325f796c4873089acdfd2b1f1d2520f Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Sat, 29 Aug 2020 00:16:21 +0000 Subject: Daily bump. --- gcc/c/ChangeLog | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'gcc/c') diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 91a278e..da8ad54 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,9 @@ +2020-08-28 Martin Sebor + + PR c/96596 + * c-decl.c (match_builtin_function_types): Avoid dealing with erroneous + argument type. + 2020-08-27 Martin Liska * gimple-parser.c (c_parser_gimple_compound_statement): Set exact argument of a vector -- cgit v1.1 From a37b0cccf4965f13006d2928f57a71e46e341cf8 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Tue, 1 Sep 2020 09:17:58 +0200 Subject: openmp: Check for PARM_DECL before using C_ARRAY_PARAMETER or DECL_ARRAY_PARAMETER_P [PR96867] The C++ macro performs a PARM_DECL_CHECK, so will ICE if not tested on a PARM_DECL, C_ARRAY_PARAMETER doesn't, but probably should, otherwise it is testing e.g. C_DECL_VARIABLE_SIZE on VAR_DECLs. 2020-09-01 Jakub Jelinek PR c++/96867 * c-typeck.c (handle_omp_array_sections_1): Test C_ARRAY_PARAMETER only on PARM_DECLs. * semantics.c (handle_omp_array_sections_1): Test DECL_ARRAY_PARAMETER_P only on PARM_DECLs. * c-c++-common/gomp/pr96867.c: New test. --- gcc/c/c-typeck.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/c') diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c index e158d23..bb27099 100644 --- a/gcc/c/c-typeck.c +++ b/gcc/c/c-typeck.c @@ -13298,7 +13298,7 @@ handle_omp_array_sections_1 (tree c, tree t, vec &types, { if (length == NULL_TREE) { - if (C_ARRAY_PARAMETER (ret)) + if (TREE_CODE (ret) == PARM_DECL && C_ARRAY_PARAMETER (ret)) error_at (OMP_CLAUSE_LOCATION (c), "for array function parameter length expression " "must be specified"); -- cgit v1.1 From e1a4a8a03f700744c59e5b5e562fee0c33859c2c Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Wed, 2 Sep 2020 00:16:25 +0000 Subject: Daily bump. --- gcc/c/ChangeLog | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'gcc/c') diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index da8ad54..01d1c6b 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,9 @@ +2020-09-01 Jakub Jelinek + + PR c++/96867 + * c-typeck.c (handle_omp_array_sections_1): Test C_ARRAY_PARAMETER + only on PARM_DECLs. + 2020-08-28 Martin Sebor PR c/96596 -- cgit v1.1 From a82c4c4cef047ad420cf8460052d303e5dafb460 Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Fri, 11 Sep 2020 10:12:28 +0200 Subject: Adjust email address --- gcc/c/ChangeLog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/c') diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 01d1c6b..eb68b12 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -61,7 +61,7 @@ * c-typeck.c (c_finish_omp_clauses): Set OMP_CLAUSE_SIZE (bias) to zero for standalone attach/detach clauses. -2020-07-08 Eric Botcazou +2020-07-08 Eric Botcazou * c-typeck.c (convert_for_assignment): If -Wscalar-storage-order is set, warn for conversion between pointers that point to incompatible -- cgit v1.1 From 3696a50beeb73f4ded8a584e76ee16f0bde109b9 Mon Sep 17 00:00:00 2001 From: Sandra Loosemore Date: Sat, 19 Sep 2020 07:32:35 -0700 Subject: Change C front end to emit structured loop and switch tree nodes. 2020-08-12 Sandra Loosemore gcc/c * c-decl.c (c_break_label, c_cont_label): Delete, and replace with... (in_statement): New. (start_function): Adjust for above change. (c_push_function_context, c_pop_function_context): Likewise. * c-lang.h (struct language_function): Likewise. * c-objc-common.h (LANG_HOOKS_BLOCK_MAY_FALLTHRU): Define. * c-parser.c (objc_foreach_break_label, objc_foreach_continue_label): New. (c_parser_statement_after_labels): Adjust calls to c_finish_bc_stmt. (c_parser_switch_statement): Adjust break/switch context handling and calls to renamed functions. (c_parser_while_statement): Adjust break/switch context handling and build a WHILE_STMT. (c_parser_do_statement): Ditto, with DO_STMT respectively. (c_parser_for_statement): Ditto, with FOR_STMT respectively. (c_parser_omp_for_loop): Adjust break/switch context handling. * c-tree.h (c_break_label, c_cont_label): Delete. (IN_SWITCH_STMT, IN_ITERATION_STMT): Define. (IN_OMP_BLOCK, IN_OMP_FOR, IN_OBJC_FOREACH): Define. (in_statement, switch_statement_break_seen_p): Declare. (c_start_case, c_finish_case): Renamed to... (c_start_switch, c_finish_switch). (c_finish_bc_stmt): Adjust arguments. * c-typeck.c (build_function_call_vec): Don't try to print statements with %qE format. (struct c_switch): Rename switch_expr field to switch_stmt. Add break_stmt_seen_p field. (c_start_case): Rename to c_start_switch. Build a SWITCH_STMT instead of a SWITCH_EXPR. Update for changes to struct c_switch. (do_case): Update for changes to struct c_switch. (c_finish_case): Rename to c_finish_switch. Update for changes to struct c_switch and change of representation from SWITCH_EXPR to SWITCH_STMT. (c_finish_loop): Delete. (c_finish_bc_stmt): Update to reflect changes to break/continue state representation. Build a BREAK_STMT or CONTINUE_STMT instead of a GOTO_EXPR except for objc foreach loops. gcc/objc * objc-act.c (objc_start_method_definition): Update to reflect changes to break/continue state bookkeeping in C front end. gcc/testsuite/ * gcc.dg/gomp/block-7.c: Update expected error message wording. --- gcc/c/c-decl.c | 18 ++-- gcc/c/c-lang.h | 3 +- gcc/c/c-objc-common.h | 2 + gcc/c/c-parser.c | 125 +++++++++++++-------------- gcc/c/c-tree.h | 21 +++-- gcc/c/c-typeck.c | 227 ++++++++++++++++---------------------------------- 6 files changed, 156 insertions(+), 240 deletions(-) (limited to 'gcc/c') diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c index 190c00b..8204db2 100644 --- a/gcc/c/c-decl.c +++ b/gcc/c/c-decl.c @@ -112,9 +112,9 @@ struct obstack parser_obstack; static GTY(()) struct stmt_tree_s c_stmt_tree; -/* State saving variables. */ -tree c_break_label; -tree c_cont_label; +/* Zero if we are not in an iteration or switch statement, otherwise + a bitmask. See bitmask definitions in c-tree.h. */ +unsigned char in_statement; /* A list of decls to be made automatically visible in each file scope. */ static GTY(()) tree visible_builtins; @@ -9163,10 +9163,8 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator, warn_about_return_type = 0; c_switch_stack = NULL; - /* Indicate no valid break/continue context by setting these variables - to some non-null, non-label value. We'll notice and emit the proper - error message in c_finish_bc_stmt. */ - c_break_label = c_cont_label = size_zero_node; + /* Indicate no valid break/continue context. */ + in_statement = 0; decl1 = grokdeclarator (declarator, declspecs, FUNCDEF, true, NULL, &attributes, NULL, NULL, DEPRECATED_NORMAL); @@ -10167,8 +10165,7 @@ c_push_function_context (void) p->base.x_stmt_tree = c_stmt_tree; c_stmt_tree.x_cur_stmt_list = vec_safe_copy (c_stmt_tree.x_cur_stmt_list); - p->x_break_label = c_break_label; - p->x_cont_label = c_cont_label; + p->x_in_statement = in_statement; p->x_switch_stack = c_switch_stack; p->arg_info = current_function_arg_info; p->returns_value = current_function_returns_value; @@ -10207,8 +10204,7 @@ c_pop_function_context (void) c_stmt_tree = p->base.x_stmt_tree; p->base.x_stmt_tree.x_cur_stmt_list = NULL; - c_break_label = p->x_break_label; - c_cont_label = p->x_cont_label; + in_statement = p->x_in_statement; c_switch_stack = p->x_switch_stack; current_function_arg_info = p->arg_info; current_function_returns_value = p->returns_value; diff --git a/gcc/c/c-lang.h b/gcc/c/c-lang.h index 6d377cd..7e9a276 100644 --- a/gcc/c/c-lang.h +++ b/gcc/c/c-lang.h @@ -51,8 +51,7 @@ struct GTY(()) lang_decl { struct GTY(()) language_function { struct c_language_function base; - tree x_break_label; - tree x_cont_label; + unsigned char x_in_statement; struct c_switch * GTY((skip)) x_switch_stack; struct c_arg_info * GTY((skip)) arg_info; int returns_value; diff --git a/gcc/c/c-objc-common.h b/gcc/c/c-objc-common.h index 9257959..76f9db7 100644 --- a/gcc/c/c-objc-common.h +++ b/gcc/c/c-objc-common.h @@ -56,6 +56,8 @@ along with GCC; see the file COPYING3. If not see #define LANG_HOOKS_TYPES_COMPATIBLE_P c_types_compatible_p #undef LANG_HOOKS_MISSING_NORETURN_OK_P #define LANG_HOOKS_MISSING_NORETURN_OK_P c_missing_noreturn_ok_p +#undef LANG_HOOKS_BLOCK_MAY_FALLTHRU +#define LANG_HOOKS_BLOCK_MAY_FALLTHRU c_block_may_fallthru #undef LANG_HOOKS_BUILTIN_FUNCTION #define LANG_HOOKS_BUILTIN_FUNCTION c_builtin_function #undef LANG_HOOKS_BUILTIN_FUNCTION_EXT_SCOPE diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index a8bc301..2e6775a 100644 --- a/gcc/c/c-parser.c +++ b/gcc/c/c-parser.c @@ -1479,6 +1479,9 @@ struct oacc_routine_data { location_t loc; }; +/* Used for parsing objc foreach statements. */ +static tree objc_foreach_break_label, objc_foreach_continue_label; + static bool c_parser_nth_token_starts_std_attributes (c_parser *, unsigned int); static tree c_parser_std_attribute_specifier_sequence (c_parser *); @@ -6221,11 +6224,11 @@ c_parser_statement_after_labels (c_parser *parser, bool *if_p, goto expect_semicolon; case RID_CONTINUE: c_parser_consume_token (parser); - stmt = c_finish_bc_stmt (loc, &c_cont_label, false); + stmt = c_finish_bc_stmt (loc, objc_foreach_continue_label, false); goto expect_semicolon; case RID_BREAK: c_parser_consume_token (parser); - stmt = c_finish_bc_stmt (loc, &c_break_label, true); + stmt = c_finish_bc_stmt (loc, objc_foreach_break_label, true); goto expect_semicolon; case RID_RETURN: c_parser_consume_token (parser); @@ -6627,7 +6630,8 @@ static void c_parser_switch_statement (c_parser *parser, bool *if_p) { struct c_expr ce; - tree block, expr, body, save_break; + tree block, expr, body; + unsigned char save_in_statement; location_t switch_loc = c_parser_peek_token (parser)->location; location_t switch_cond_loc; gcc_assert (c_parser_next_token_is_keyword (parser, RID_SWITCH)); @@ -6653,9 +6657,9 @@ c_parser_switch_statement (c_parser *parser, bool *if_p) expr = error_mark_node; ce.original_type = error_mark_node; } - c_start_case (switch_loc, switch_cond_loc, expr, explicit_cast_p); - save_break = c_break_label; - c_break_label = NULL_TREE; + c_start_switch (switch_loc, switch_cond_loc, expr, explicit_cast_p); + save_in_statement = in_statement; + in_statement |= IN_SWITCH_STMT; location_t loc_after_labels; bool open_brace_p = c_parser_peek_token (parser)->type == CPP_OPEN_BRACE; body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels); @@ -6663,16 +6667,8 @@ c_parser_switch_statement (c_parser *parser, bool *if_p) if (!open_brace_p && c_parser_peek_token (parser)->type != CPP_SEMICOLON) warn_for_multistatement_macros (loc_after_labels, next_loc, switch_loc, RID_SWITCH); - if (c_break_label) - { - location_t here = c_parser_peek_token (parser)->location; - tree t = build1 (LABEL_EXPR, void_type_node, c_break_label); - SET_EXPR_LOCATION (t, here); - SWITCH_BREAK_LABEL_P (c_break_label) = 1; - append_to_statement_list_force (t, &body); - } - c_finish_case (body, ce.original_type); - c_break_label = save_break; + c_finish_switch (body, ce.original_type); + in_statement = save_in_statement; add_stmt (c_end_compound_stmt (switch_loc, block, flag_isoc99)); c_parser_maybe_reclassify_token (parser); } @@ -6690,7 +6686,8 @@ static void c_parser_while_statement (c_parser *parser, bool ivdep, unsigned short unroll, bool *if_p) { - tree block, cond, body, save_break, save_cont; + tree block, cond, body; + unsigned char save_in_statement; location_t loc; gcc_assert (c_parser_next_token_is_keyword (parser, RID_WHILE)); token_indent_info while_tinfo @@ -6709,10 +6706,8 @@ c_parser_while_statement (c_parser *parser, bool ivdep, unsigned short unroll, build_int_cst (integer_type_node, annot_expr_unroll_kind), build_int_cst (integer_type_node, unroll)); - save_break = c_break_label; - c_break_label = NULL_TREE; - save_cont = c_cont_label; - c_cont_label = NULL_TREE; + save_in_statement = in_statement; + in_statement = IN_ITERATION_STMT; token_indent_info body_tinfo = get_token_indent_info (c_parser_peek_token (parser)); @@ -6720,8 +6715,7 @@ c_parser_while_statement (c_parser *parser, bool ivdep, unsigned short unroll, location_t loc_after_labels; bool open_brace = c_parser_next_token_is (parser, CPP_OPEN_BRACE); body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels); - c_finish_loop (loc, loc, cond, UNKNOWN_LOCATION, NULL, body, - c_break_label, c_cont_label, true); + add_stmt (build_stmt (loc, WHILE_STMT, cond, body)); add_stmt (c_end_compound_stmt (loc, block, flag_isoc99)); c_parser_maybe_reclassify_token (parser); @@ -6733,8 +6727,7 @@ c_parser_while_statement (c_parser *parser, bool ivdep, unsigned short unroll, warn_for_multistatement_macros (loc_after_labels, next_tinfo.location, while_tinfo.location, RID_WHILE); - c_break_label = save_break; - c_cont_label = save_cont; + in_statement = save_in_statement; } /* Parse a do statement (C90 6.6.5, C99 6.8.5, C11 6.8.5). @@ -6746,7 +6739,8 @@ c_parser_while_statement (c_parser *parser, bool ivdep, unsigned short unroll, static void c_parser_do_statement (c_parser *parser, bool ivdep, unsigned short unroll) { - tree block, cond, body, save_break, save_cont, new_break, new_cont; + tree block, cond, body; + unsigned char save_in_statement; location_t loc; gcc_assert (c_parser_next_token_is_keyword (parser, RID_DO)); c_parser_consume_token (parser); @@ -6756,17 +6750,11 @@ c_parser_do_statement (c_parser *parser, bool ivdep, unsigned short unroll) "suggest braces around empty body in % statement"); block = c_begin_compound_stmt (flag_isoc99); loc = c_parser_peek_token (parser)->location; - save_break = c_break_label; - c_break_label = NULL_TREE; - save_cont = c_cont_label; - c_cont_label = NULL_TREE; + save_in_statement = in_statement; + in_statement = IN_ITERATION_STMT; body = c_parser_c99_block_statement (parser, NULL); c_parser_require_keyword (parser, RID_WHILE, "expected %"); - new_break = c_break_label; - c_break_label = save_break; - new_cont = c_cont_label; - c_cont_label = save_cont; - location_t cond_loc = c_parser_peek_token (parser)->location; + in_statement = save_in_statement; cond = c_parser_paren_condition (parser); if (ivdep && cond != error_mark_node) cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond, @@ -6780,8 +6768,8 @@ c_parser_do_statement (c_parser *parser, bool ivdep, unsigned short unroll) build_int_cst (integer_type_node, unroll)); if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>")) c_parser_skip_to_end_of_block_or_statement (parser); - c_finish_loop (loc, cond_loc, cond, UNKNOWN_LOCATION, NULL, body, - new_break, new_cont, false); + + add_stmt (build_stmt (loc, DO_STMT, cond, body)); add_stmt (c_end_compound_stmt (loc, block, flag_isoc99)); } @@ -6848,15 +6836,15 @@ static void c_parser_for_statement (c_parser *parser, bool ivdep, unsigned short unroll, bool *if_p) { - tree block, cond, incr, save_break, save_cont, body; + tree block, cond, incr, body; + unsigned char save_in_statement; + tree save_objc_foreach_break_label, save_objc_foreach_continue_label; /* The following are only used when parsing an ObjC foreach statement. */ tree object_expression; /* Silence the bogus uninitialized warning. */ tree collection_expression = NULL; location_t loc = c_parser_peek_token (parser)->location; location_t for_loc = loc; - location_t cond_loc = UNKNOWN_LOCATION; - location_t incr_loc = UNKNOWN_LOCATION; bool is_foreach_statement = false; gcc_assert (c_parser_next_token_is_keyword (parser, RID_FOR)); token_indent_info for_tinfo @@ -6966,7 +6954,6 @@ c_parser_for_statement (c_parser *parser, bool ivdep, unsigned short unroll, gcc_assert (!parser->objc_could_be_foreach_context); if (!is_foreach_statement) { - cond_loc = c_parser_peek_token (parser)->location; if (c_parser_next_token_is (parser, CPP_SEMICOLON)) { if (ivdep) @@ -7007,7 +6994,7 @@ c_parser_for_statement (c_parser *parser, bool ivdep, unsigned short unroll, /* Parse the increment expression (the third expression in a for-statement). In the case of a foreach-statement, this is the expression that follows the 'in'. */ - loc = incr_loc = c_parser_peek_token (parser)->location; + loc = c_parser_peek_token (parser)->location; if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) { if (is_foreach_statement) @@ -7033,10 +7020,17 @@ c_parser_for_statement (c_parser *parser, bool ivdep, unsigned short unroll, } parens.skip_until_found_close (parser); } - save_break = c_break_label; - c_break_label = NULL_TREE; - save_cont = c_cont_label; - c_cont_label = NULL_TREE; + save_in_statement = in_statement; + if (is_foreach_statement) + { + in_statement = IN_OBJC_FOREACH; + save_objc_foreach_break_label = objc_foreach_break_label; + save_objc_foreach_continue_label = objc_foreach_continue_label; + objc_foreach_break_label = create_artificial_label (loc); + objc_foreach_continue_label = create_artificial_label (loc); + } + else + in_statement = IN_ITERATION_STMT; token_indent_info body_tinfo = get_token_indent_info (c_parser_peek_token (parser)); @@ -7047,11 +7041,12 @@ c_parser_for_statement (c_parser *parser, bool ivdep, unsigned short unroll, if (is_foreach_statement) objc_finish_foreach_loop (for_loc, object_expression, - collection_expression, body, c_break_label, - c_cont_label); + collection_expression, body, + objc_foreach_break_label, + objc_foreach_continue_label); else - c_finish_loop (for_loc, cond_loc, cond, incr_loc, incr, body, - c_break_label, c_cont_label, true); + add_stmt (build_stmt (for_loc, FOR_STMT, NULL_TREE, cond, incr, + body, NULL_TREE)); add_stmt (c_end_compound_stmt (for_loc, block, flag_isoc99 || c_dialect_objc ())); c_parser_maybe_reclassify_token (parser); @@ -7064,8 +7059,12 @@ c_parser_for_statement (c_parser *parser, bool ivdep, unsigned short unroll, warn_for_multistatement_macros (loc_after_labels, next_tinfo.location, for_tinfo.location, RID_FOR); - c_break_label = save_break; - c_cont_label = save_cont; + in_statement = save_in_statement; + if (is_foreach_statement) + { + objc_foreach_break_label = save_objc_foreach_break_label; + objc_foreach_continue_label = save_objc_foreach_continue_label; + } } /* Parse an asm statement, a GNU extension. This is a full-blown asm @@ -18038,7 +18037,8 @@ static tree c_parser_omp_for_loop (location_t loc, c_parser *parser, enum tree_code code, tree clauses, tree *cclauses, bool *if_p) { - tree decl, cond, incr, save_break, save_cont, body, init, stmt, cl; + tree decl, cond, incr, body, init, stmt, cl; + unsigned char save_in_statement; tree declv, condv, incrv, initv, ret = NULL_TREE; tree pre_body = NULL_TREE, this_pre_body; tree ordered_cl = NULL_TREE; @@ -18106,6 +18106,11 @@ c_parser_omp_for_loop (location_t loc, c_parser *parser, enum tree_code code, for_loc = c_parser_peek_token (parser)->location; c_parser_consume_token (parser); + /* Forbid break/continue in the loop initializer, condition, and + increment expressions. */ + save_in_statement = in_statement; + in_statement = IN_OMP_BLOCK; + for (i = 0; i < count; i++) { int bracecount = 0; @@ -18279,10 +18284,7 @@ c_parser_omp_for_loop (location_t loc, c_parser *parser, enum tree_code code, if (nbraces) if_p = NULL; - save_break = c_break_label; - c_break_label = size_one_node; - save_cont = c_cont_label; - c_cont_label = NULL_TREE; + in_statement = IN_OMP_FOR; body = push_stmt_list (); if (inscan) @@ -18296,16 +18298,9 @@ c_parser_omp_for_loop (location_t loc, c_parser *parser, enum tree_code code, } else add_stmt (c_parser_c99_block_statement (parser, if_p)); - if (c_cont_label) - { - tree t = build1 (LABEL_EXPR, void_type_node, c_cont_label); - SET_EXPR_LOCATION (t, loc); - add_stmt (t); - } body = pop_stmt_list (body); - c_break_label = save_break; - c_cont_label = save_cont; + in_statement = save_in_statement; while (nbraces) { diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h index 10938cf..7e51859 100644 --- a/gcc/c/c-tree.h +++ b/gcc/c/c-tree.h @@ -547,8 +547,19 @@ extern void gen_aux_info_record (tree, int, int, int); struct c_spot_bindings; class c_struct_parse_info; extern struct obstack parser_obstack; -extern tree c_break_label; -extern tree c_cont_label; +/* Set to IN_ITERATION_STMT if parsing an iteration-statement, + to IN_OMP_BLOCK if parsing OpenMP structured block and + IN_OMP_FOR if parsing OpenMP loop. If parsing a switch statement, + this is bitwise ORed with IN_SWITCH_STMT, unless parsing an + iteration-statement, OpenMP block or loop within that switch. */ +#define IN_SWITCH_STMT 1 +#define IN_ITERATION_STMT 2 +#define IN_OMP_BLOCK 4 +#define IN_OMP_FOR 8 +#define IN_OBJC_FOREACH 16 +extern unsigned char in_statement; + +extern bool switch_statement_break_seen_p; extern bool global_bindings_p (void); extern tree pushdecl (tree); @@ -714,8 +725,8 @@ extern void process_init_element (location_t, struct c_expr, bool, extern tree build_compound_literal (location_t, tree, tree, bool, unsigned int); extern void check_compound_literal_type (location_t, struct c_type_name *); -extern tree c_start_case (location_t, location_t, tree, bool); -extern void c_finish_case (tree, tree); +extern tree c_start_switch (location_t, location_t, tree, bool); +extern void c_finish_switch (tree, tree); extern tree build_asm_expr (location_t, tree, tree, tree, tree, tree, bool, bool); extern tree build_asm_stmt (bool, tree); @@ -730,7 +741,7 @@ extern tree c_finish_stmt_expr (location_t, tree); extern tree c_process_expr_stmt (location_t, tree); extern tree c_finish_expr_stmt (location_t, tree); extern tree c_finish_return (location_t, tree, tree); -extern tree c_finish_bc_stmt (location_t, tree *, bool); +extern tree c_finish_bc_stmt (location_t, tree, bool); extern tree c_finish_goto_label (location_t, tree); extern tree c_finish_goto_ptr (location_t, tree); extern tree c_expr_to_decl (tree, bool *, bool *); diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c index bb27099..dd3e309 100644 --- a/gcc/c/c-typeck.c +++ b/gcc/c/c-typeck.c @@ -3076,7 +3076,7 @@ build_function_call_vec (location_t loc, vec arg_loc, if (!(TREE_CODE (fntype) == POINTER_TYPE && TREE_CODE (TREE_TYPE (fntype)) == FUNCTION_TYPE)) { - if (!flag_diagnostics_show_caret) + if (!flag_diagnostics_show_caret && !STATEMENT_CLASS_P (function)) error_at (loc, "called object %qE is not a function or function pointer", function); @@ -10808,8 +10808,8 @@ c_finish_return (location_t loc, tree retval, tree origtype) } struct c_switch { - /* The SWITCH_EXPR being built. */ - tree switch_expr; + /* The SWITCH_STMT being built. */ + tree switch_stmt; /* The original type of the testing expression, i.e. before the default conversion is applied. */ @@ -10826,6 +10826,9 @@ struct c_switch { warnings crossing decls when branching to a case label. */ struct c_spot_bindings *bindings; + /* Whether the switch includes any break statements. */ + bool break_stmt_seen_p; + /* The next node on the stack. */ struct c_switch *next; @@ -10843,14 +10846,14 @@ struct c_switch { struct c_switch *c_switch_stack; /* Start a C switch statement, testing expression EXP. Return the new - SWITCH_EXPR. SWITCH_LOC is the location of the `switch'. + SWITCH_STMT. SWITCH_LOC is the location of the `switch'. SWITCH_COND_LOC is the location of the switch's condition. EXPLICIT_CAST_P is true if the expression EXP has an explicit cast. */ tree -c_start_case (location_t switch_loc, - location_t switch_cond_loc, - tree exp, bool explicit_cast_p) +c_start_switch (location_t switch_loc, + location_t switch_cond_loc, + tree exp, bool explicit_cast_p) { tree orig_type = error_mark_node; bool bool_cond_p = false; @@ -10900,18 +10903,19 @@ c_start_case (location_t switch_loc, } } - /* Add this new SWITCH_EXPR to the stack. */ + /* Add this new SWITCH_STMT to the stack. */ cs = XNEW (struct c_switch); - cs->switch_expr = build2 (SWITCH_EXPR, orig_type, exp, NULL_TREE); - SET_EXPR_LOCATION (cs->switch_expr, switch_loc); + cs->switch_stmt = build_stmt (switch_loc, SWITCH_STMT, exp, + NULL_TREE, orig_type, NULL_TREE); cs->orig_type = orig_type; cs->cases = splay_tree_new (case_compare, NULL, NULL); cs->bindings = c_get_switch_bindings (); + cs->break_stmt_seen_p = false; cs->bool_cond_p = bool_cond_p; cs->next = c_switch_stack; c_switch_stack = cs; - return add_stmt (cs->switch_expr); + return add_stmt (cs->switch_stmt); } /* Process a case label at location LOC. */ @@ -10947,12 +10951,12 @@ do_case (location_t loc, tree low_value, tree high_value) } if (c_check_switch_jump_warnings (c_switch_stack->bindings, - EXPR_LOCATION (c_switch_stack->switch_expr), + EXPR_LOCATION (c_switch_stack->switch_stmt), loc)) return NULL_TREE; label = c_add_case_label (loc, c_switch_stack->cases, - SWITCH_COND (c_switch_stack->switch_expr), + SWITCH_STMT_COND (c_switch_stack->switch_stmt), low_value, high_value); if (label == error_mark_node) label = NULL_TREE; @@ -10963,20 +10967,22 @@ do_case (location_t loc, tree low_value, tree high_value) controlling expression of the switch, or NULL_TREE. */ void -c_finish_case (tree body, tree type) +c_finish_switch (tree body, tree type) { struct c_switch *cs = c_switch_stack; location_t switch_location; - SWITCH_BODY (cs->switch_expr) = body; + SWITCH_STMT_BODY (cs->switch_stmt) = body; /* Emit warnings as needed. */ - switch_location = EXPR_LOCATION (cs->switch_expr); + switch_location = EXPR_LOCATION (cs->switch_stmt); c_do_switch_warnings (cs->cases, switch_location, - type ? type : TREE_TYPE (cs->switch_expr), - SWITCH_COND (cs->switch_expr), cs->bool_cond_p); - if (c_switch_covers_all_cases_p (cs->cases, TREE_TYPE (cs->switch_expr))) - SWITCH_ALL_CASES_P (cs->switch_expr) = 1; + type ? type : SWITCH_STMT_TYPE (cs->switch_stmt), + SWITCH_STMT_COND (cs->switch_stmt), cs->bool_cond_p); + if (c_switch_covers_all_cases_p (cs->cases, + SWITCH_STMT_TYPE (cs->switch_stmt))) + SWITCH_STMT_ALL_CASES_P (cs->switch_stmt) = 1; + SWITCH_STMT_NO_BREAK_P (cs->switch_stmt) = !cs->break_stmt_seen_p; /* Pop the stack. */ c_switch_stack = cs->next; @@ -11000,110 +11006,9 @@ c_finish_if_stmt (location_t if_locus, tree cond, tree then_block, add_stmt (stmt); } -/* Emit a general-purpose loop construct. START_LOCUS is the location of - the beginning of the loop. COND is the loop condition. COND_IS_FIRST - is false for DO loops. INCR is the FOR increment expression. BODY is - the statement controlled by the loop. BLAB is the break label. CLAB is - the continue label. Everything is allowed to be NULL. - COND_LOCUS is the location of the loop condition, INCR_LOCUS is the - location of the FOR increment expression. */ - -void -c_finish_loop (location_t start_locus, location_t cond_locus, tree cond, - location_t incr_locus, tree incr, tree body, tree blab, - tree clab, bool cond_is_first) -{ - tree entry = NULL, exit = NULL, t; - - /* If the condition is zero don't generate a loop construct. */ - if (cond && integer_zerop (cond)) - { - if (cond_is_first) - { - t = build_and_jump (&blab); - SET_EXPR_LOCATION (t, start_locus); - add_stmt (t); - } - } - else - { - tree top = build1 (LABEL_EXPR, void_type_node, NULL_TREE); - - /* If we have an exit condition, then we build an IF with gotos either - out of the loop, or to the top of it. If there's no exit condition, - then we just build a jump back to the top. */ - exit = build_and_jump (&LABEL_EXPR_LABEL (top)); - - if (cond && !integer_nonzerop (cond)) - { - /* Canonicalize the loop condition to the end. This means - generating a branch to the loop condition. Reuse the - continue label, if possible. */ - if (cond_is_first) - { - if (incr || !clab) - { - entry = build1 (LABEL_EXPR, void_type_node, NULL_TREE); - t = build_and_jump (&LABEL_EXPR_LABEL (entry)); - } - else - t = build1 (GOTO_EXPR, void_type_node, clab); - SET_EXPR_LOCATION (t, start_locus); - add_stmt (t); - } - - t = build_and_jump (&blab); - exit = fold_build3_loc (cond_is_first ? start_locus : input_location, - COND_EXPR, void_type_node, cond, exit, t); - } - else - { - /* For the backward-goto's location of an unconditional loop - use the beginning of the body, or, if there is none, the - top of the loop. */ - location_t loc = EXPR_LOCATION (expr_first (body)); - if (loc == UNKNOWN_LOCATION) - loc = start_locus; - SET_EXPR_LOCATION (exit, loc); - } - - add_stmt (top); - } - - if (body) - add_stmt (body); - if (clab) - add_stmt (build1 (LABEL_EXPR, void_type_node, clab)); - if (incr) - { - if (MAY_HAVE_DEBUG_MARKER_STMTS && incr_locus != UNKNOWN_LOCATION) - { - t = build0 (DEBUG_BEGIN_STMT, void_type_node); - SET_EXPR_LOCATION (t, incr_locus); - add_stmt (t); - } - add_stmt (incr); - } - if (entry) - add_stmt (entry); - if (MAY_HAVE_DEBUG_MARKER_STMTS && cond_locus != UNKNOWN_LOCATION) - { - t = build0 (DEBUG_BEGIN_STMT, void_type_node); - SET_EXPR_LOCATION (t, cond_locus); - add_stmt (t); - } - if (exit) - add_stmt (exit); - if (blab) - add_stmt (build1 (LABEL_EXPR, void_type_node, blab)); -} - tree -c_finish_bc_stmt (location_t loc, tree *label_p, bool is_break) +c_finish_bc_stmt (location_t loc, tree label, bool is_break) { - bool skip; - tree label = *label_p; - /* In switch statements break is sometimes stylistically used after a return statement. This can lead to spurious warnings about control reaching the end of a non-void function when it is @@ -11111,47 +11016,55 @@ c_finish_bc_stmt (location_t loc, tree *label_p, bool is_break) language specific tree nodes; this works because block_may_fallthru returns true when given something it does not understand. */ - skip = !block_may_fallthru (cur_stmt_list); + bool skip = !block_may_fallthru (cur_stmt_list); - if (!label) - { - if (!skip) - *label_p = label = create_artificial_label (loc); - } - else if (TREE_CODE (label) == LABEL_DECL) - ; - else switch (TREE_INT_CST_LOW (label)) - { - case 0: - if (is_break) + if (is_break) + switch (in_statement) + { + case 0: error_at (loc, "break statement not within loop or switch"); - else + return NULL_TREE; + case IN_OMP_BLOCK: + error_at (loc, "invalid exit from OpenMP structured block"); + return NULL_TREE; + case IN_OMP_FOR: + error_at (loc, "break statement used with OpenMP for loop"); + return NULL_TREE; + case IN_ITERATION_STMT: + case IN_OBJC_FOREACH: + break; + default: + gcc_assert (in_statement & IN_SWITCH_STMT); + c_switch_stack->break_stmt_seen_p = true; + break; + } + else + switch (in_statement & ~IN_SWITCH_STMT) + { + case 0: error_at (loc, "continue statement not within a loop"); - return NULL_TREE; - - case 1: - gcc_assert (is_break); - error_at (loc, "break statement used with OpenMP for loop"); - return NULL_TREE; - - case 2: - if (is_break) - error ("break statement within %<#pragma simd%> loop body"); - else - error ("continue statement within %<#pragma simd%> loop body"); - return NULL_TREE; - - default: - gcc_unreachable (); - } + return NULL_TREE; + case IN_OMP_BLOCK: + error_at (loc, "invalid exit from OpenMP structured block"); + return NULL_TREE; + case IN_ITERATION_STMT: + case IN_OMP_FOR: + case IN_OBJC_FOREACH: + break; + default: + gcc_unreachable (); + } if (skip) return NULL_TREE; - - if (!is_break) - add_stmt (build_predict_expr (PRED_CONTINUE, NOT_TAKEN)); - - return add_stmt (build1 (GOTO_EXPR, void_type_node, label)); + else if (in_statement & IN_OBJC_FOREACH) + { + /* The foreach expander produces low-level code using gotos instead + of a structured loop construct. */ + gcc_assert (label); + return add_stmt (build_stmt (loc, GOTO_EXPR, label)); + } + return add_stmt (build_stmt (loc, (is_break ? BREAK_STMT : CONTINUE_STMT))); } /* A helper routine for c_process_expr_stmt and c_finish_stmt_expr. */ -- cgit v1.1 From 6450f07388f9fe575a489c9309c36012b17b88b0 Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Sat, 19 Sep 2020 17:21:52 -0600 Subject: Infrastructure & C front end changes for array parameter checking (PR c/50584). gcc/ChangeLog: PR c/50584 * attribs.c (decl_attributes): Also pass decl along with type attributes to handlers. (init_attr_rdwr_indices): Change second argument to attribute chain. Handle internal attribute representation in addition to external. (get_parm_access): New function. (attr_access::to_internal_string): Define new member function. (attr_access::to_external_string): Define new member function. (attr_access::vla_bounds): Define new member function. * attribs.h (struct attr_access): Declare new members. (attr_access::from_mode_char): Define new member function. (get_parm_access): Declare new function. * calls.c (initialize_argument_information): Pass function type attributes to init_attr_rdwr_indices. * doc/invoke.texi (-Warray-parameter, -Wvla-parameter): Document. * tree-pretty-print.c (dump_generic_node): Correct handling of qualifiers. * tree-ssa-uninit.c (maybe_warn_pass_by_reference): Same. * tree.h (access_mode): Add new enumerator. gcc/c-family/ChangeLog: PR c/50584 * c-attribs.c (c_common_attribute_table): Add "arg spec" attribute. (handle_argspec_attribute): New function. (get_argument, get_argument_type): New functions. (append_access_attrs): Add overload. Handle internal attribute representation in addition to external. (handle_access_attribute): Handle internal attribute representation in addition to external. (build_attr_access_from_parms): New function. gcc/c-family/ChangeLog: PR c/50584 * c-common.h (warn_parm_array_mismatch): Declare new function. (has_attribute): Move declaration of an existing function. (build_attr_access_from_parms): Declare new function. * c-warn.c (parm_array_as_string): Define new function. (plus_one): Define new function. (warn_parm_ptrarray_mismatch): Define new function. (warn_parm_array_mismatch): Define new function. (vla_bound_parm_decl): New function. * c.opt (-Warray-parameter, -Wvla-parameter): New options. * c-pretty-print.c (pp_c_type_qualifier_list): Don't print array type qualifiers here... (c_pretty_printer::direct_abstract_declarator): ...but instead print them in brackets here. Also print [static]. Strip extraneous expressions from VLA bounds. gcc/c/ChangeLog: PR c/50584 * c-decl.c (lookup_last_decl): Define new function. (c_decl_attributes): Call it. (start_decl): Add argument and use it. (finish_decl): Call build_attr_access_from_parms and decl_attributes. (get_parm_array_spec): Define new function. (push_parm_decl): Call get_parm_array_spec. (start_function): Call warn_parm_array_mismatch. Build attribute access and add it to current function. * c-parser.c (c_parser_declaration_or_fndef): Diagnose mismatches in forms of array parameters. * c-tree.h (start_decl): Add argument. gcc/testsuite/ChangeLog: PR c/50584 * gcc.dg/attr-access-read-write-2.c: Adjust text of expected message. * c-c++-common/Warray-bounds-6.c: Correct C++ declaration, adjust text of expected diagnostics. * gcc.dg/Wbuiltin-declaration-mismatch-9.c: Prune expected warning. * gcc.dg/Warray-parameter-2.c: New test. * gcc.dg/Warray-parameter-3.c: New test. * gcc.dg/Warray-parameter-4.c: New test. * gcc.dg/Warray-parameter-5.c: New test. * gcc.dg/Warray-parameter.c: New test. * gcc.dg/Wvla-parameter-2.c: New test. * gcc.dg/Wvla-parameter-3.c: New test. * gcc.dg/Wvla-parameter.c: New test. --- gcc/c/c-decl.c | 223 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- gcc/c/c-parser.c | 27 ++++--- gcc/c/c-tree.h | 2 +- 3 files changed, 232 insertions(+), 20 deletions(-) (limited to 'gcc/c') diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c index 8204db2..81b9adb 100644 --- a/gcc/c/c-decl.c +++ b/gcc/c/c-decl.c @@ -25,6 +25,7 @@ along with GCC; see the file COPYING3. If not see line numbers. For example, the CONST_DECLs for enum values. */ #include "config.h" +#define INCLUDE_STRING #define INCLUDE_UNIQUE_PTR #include "system.h" #include "coretypes.h" @@ -58,6 +59,8 @@ along with GCC; see the file COPYING3. If not see #include "c-family/known-headers.h" #include "c-family/c-spellcheck.h" +#include "tree-pretty-print.h" + /* In grokdeclarator, distinguish syntactic contexts of declarators. */ enum decl_context { NORMAL, /* Ordinary declaration */ @@ -4970,6 +4973,17 @@ groktypename (struct c_type_name *type_name, tree *expr, return type; } +/* Looks up the most recent pushed declaration corresponding to DECL. */ + +static tree +lookup_last_decl (tree decl) +{ + tree last_decl = lookup_name (DECL_NAME (decl)); + if (!last_decl) + last_decl = lookup_name_in_scope (DECL_NAME (decl), external_scope); + return last_decl; +} + /* Wrapper for decl_attributes that adds some implicit attributes to VAR_DECLs or FUNCTION_DECLs. */ @@ -4998,10 +5012,7 @@ c_decl_attributes (tree *node, tree attributes, int flags) so far so that attributes on the current declaration that's about to be pushed that conflict with the former can be detected, diagnosed, and rejected as appropriate. */ - tree last_decl = lookup_name (DECL_NAME (*node)); - if (!last_decl) - last_decl = lookup_name_in_scope (DECL_NAME (*node), external_scope); - + tree last_decl = lookup_last_decl (*node); return decl_attributes (node, attributes, flags, last_decl); } @@ -5011,6 +5022,8 @@ c_decl_attributes (tree *node, tree attributes, int flags) have been parsed, before parsing the initializer if any. Here we create the ..._DECL node, fill in its type, and put it on the list of decls for the current context. + When nonnull, set *LASTLOC to the location of the prior declaration + of the same entity if one exists. The ..._DECL node is returned as the value. Exception: for arrays where the length is not specified, @@ -5023,7 +5036,7 @@ c_decl_attributes (tree *node, tree attributes, int flags) tree start_decl (struct c_declarator *declarator, struct c_declspecs *declspecs, - bool initialized, tree attributes) + bool initialized, tree attributes, location_t *lastloc /* = NULL */) { tree decl; tree tem; @@ -5041,6 +5054,10 @@ start_decl (struct c_declarator *declarator, struct c_declspecs *declspecs, if (!decl || decl == error_mark_node) return NULL_TREE; + if (tree lastdecl = lastloc ? lookup_last_decl (decl) : NULL_TREE) + if (lastdecl != error_mark_node) + *lastloc = DECL_SOURCE_LOCATION (lastdecl); + if (expr) add_stmt (fold_convert (void_type_node, expr)); @@ -5478,6 +5495,14 @@ finish_decl (tree decl, location_t init_loc, tree init, if (asmspec && VAR_P (decl) && C_DECL_REGISTER (decl)) DECL_HARD_REGISTER (decl) = 1; rest_of_decl_compilation (decl, true, 0); + + if (TREE_CODE (decl) == FUNCTION_DECL) + { + tree parms = DECL_ARGUMENTS (decl); + const bool builtin = fndecl_built_in_p (decl); + if (tree access = build_attr_access_from_parms (parms, !builtin)) + decl_attributes (&decl, access, 0); + } } else { @@ -5630,6 +5655,175 @@ grokparm (const struct c_parm *parm, tree *expr) return decl; } +/* Return attribute "arg spec" corresponding to an array/VLA parameter + described by PARM, concatenated onto attributes ATTRS. + The spec consists of one dollar symbol for each specified variable + bound, one asterisk for each unspecified variable bound, followed + by at most one specification of the most significant bound of + an ordinary array parameter. For ordinary arrays the specification + is either the constant bound itself, or the space character for + an array with an unspecified bound (the [] form). Finally, a chain + of specified variable bounds is appended to the spec, starting with + the most significant bound. For example, the PARM T a[2][m][3][n] + will produce __attribute__((arg spec ("[$$2]", m, n)). + For T a typedef for an array with variable bounds, the bounds are + included in the specification in the expected order. + No "arg spec" is created for parameters of pointer types, making + a distinction between T(*)[N] (or, equivalently, T[][N]) and + the T[M][N] form, all of which have the same type and are represented + the same, but only the last of which gets an "arg spec" describing + the most significant bound M. */ + +static tree +get_parm_array_spec (const struct c_parm *parm, tree attrs) +{ + /* The attribute specification string, minor bound first. */ + std::string spec; + + /* A list of VLA variable bounds, major first, or null if unspecified + or not a VLA. */ + tree vbchain = NULL_TREE; + /* True for a pointer parameter. */ + bool pointer = false; + /* True for an ordinary array with an unpecified bound. */ + bool nobound = false; + + /* Create a string representation for the bounds of the array/VLA. */ + for (c_declarator *pd = parm->declarator, *next; pd; pd = next) + { + next = pd->declarator; + while (next && next->kind == cdk_attrs) + next = next->declarator; + + /* Remember if a pointer has been seen to avoid storing the constant + bound. */ + if (pd->kind == cdk_pointer) + pointer = true; + + if ((pd->kind == cdk_pointer || pd->kind == cdk_function) + && (!next || next->kind == cdk_id)) + { + /* Do nothing for the common case of a pointer. The fact that + the parameter is one can be deduced from the absence of + an arg spec for it. */ + return attrs; + } + + if (pd->kind == cdk_id) + { + if (pointer + || !parm->specs->type + || TREE_CODE (parm->specs->type) != ARRAY_TYPE + || !TYPE_DOMAIN (parm->specs->type) + || !TYPE_MAX_VALUE (TYPE_DOMAIN (parm->specs->type))) + continue; + + tree max = TYPE_MAX_VALUE (TYPE_DOMAIN (parm->specs->type)); + if (!vbchain + && TREE_CODE (max) == INTEGER_CST) + { + /* Extract the upper bound from a parameter of an array type + unless the parameter is an ordinary array of unspecified + bound in which case a next iteration of the loop will + exit. */ + if (spec.empty () || spec.end ()[-1] != ' ') + { + if (!tree_fits_shwi_p (max)) + continue; + + /* The upper bound is the value of the largest valid + index. */ + HOST_WIDE_INT n = tree_to_shwi (max) + 1; + char buf[40]; + sprintf (buf, "%lu", (unsigned long)n); + spec += buf; + } + continue; + } + + /* For a VLA typedef, create a list of its variable bounds and + append it in the expected order to VBCHAIN. */ + tree tpbnds = NULL_TREE; + for (tree type = parm->specs->type; TREE_CODE (type) == ARRAY_TYPE; + type = TREE_TYPE (type)) + { + tree nelts = array_type_nelts (type); + if (TREE_CODE (nelts) != INTEGER_CST) + { + /* Each variable VLA bound is represented by the dollar + sign. */ + spec += "$"; + tpbnds = tree_cons (NULL_TREE, nelts, tpbnds); + } + } + tpbnds = nreverse (tpbnds); + vbchain = chainon (vbchain, tpbnds); + continue; + } + + if (pd->kind != cdk_array) + continue; + + if (pd->u.array.vla_unspec_p) + { + /* Each unspecified bound is represented by a star. There + can be any number of these in a declaration (but none in + a definition). */ + spec += '*'; + continue; + } + + tree nelts = pd->u.array.dimen; + if (!nelts) + { + /* Ordinary array of unspecified size. There can be at most + one for the most significant bound. Exit on the next + iteration which determines whether or not PARM is declared + as a pointer or an array. */ + nobound = true; + continue; + } + + if (TREE_CODE (nelts) == INTEGER_CST) + { + /* Skip all constant bounds except the most significant one. + The interior ones are included in the array type. */ + if (next && (next->kind == cdk_array || next->kind == cdk_pointer)) + continue; + + if (!tree_fits_uhwi_p (nelts)) + /* Bail completely on invalid bounds. */ + return attrs; + + char buf[40]; + const char *code = pd->u.array.static_p ? "s" : ""; + unsigned HOST_WIDE_INT n = tree_to_uhwi (nelts); + sprintf (buf, "%s%llu", code, (unsigned long long)n); + spec += buf; + break; + } + + /* Each variable VLA bound is represented by a dollar sign. */ + spec += "$"; + vbchain = tree_cons (NULL_TREE, nelts, vbchain); + } + + if (spec.empty () && !nobound) + return attrs; + + spec.insert (0, "["); + if (nobound) + /* Ordinary array of unspecified bound is represented by a space. + It must be last in the spec. */ + spec += ' '; + spec += ']'; + + tree acsstr = build_string (spec.length () + 1, spec.c_str ()); + tree args = tree_cons (NULL_TREE, acsstr, vbchain); + tree name = get_identifier ("arg spec"); + return tree_cons (name, args, attrs); +} + /* Given a parsed parameter declaration, decode it into a PARM_DECL and push that on the current scope. EXPR is a pointer to an expression that needs to be evaluated for the side effects of array @@ -5639,12 +5833,12 @@ void push_parm_decl (const struct c_parm *parm, tree *expr) { tree attrs = parm->attrs; - tree decl; - - decl = grokdeclarator (parm->declarator, parm->specs, PARM, false, NULL, - &attrs, expr, NULL, DEPRECATED_NORMAL); + tree decl = grokdeclarator (parm->declarator, parm->specs, PARM, false, NULL, + &attrs, expr, NULL, DEPRECATED_NORMAL); if (decl && DECL_P (decl)) DECL_SOURCE_LOCATION (decl) = parm->loc; + + attrs = get_parm_array_spec (parm, attrs); decl_attributes (&decl, attrs, 0); decl = pushdecl (decl); @@ -9228,6 +9422,7 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator, old_decl = lookup_name_in_scope (DECL_NAME (decl1), current_scope); if (old_decl && TREE_CODE (old_decl) != FUNCTION_DECL) old_decl = NULL_TREE; + current_function_prototype_locus = UNKNOWN_LOCATION; current_function_prototype_built_in = false; current_function_prototype_arg_types = NULL_TREE; @@ -9358,12 +9553,22 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator, "%qD is normally a non-static function", decl1); } + tree parms = current_function_arg_info->parms; + if (old_decl) + { + location_t origloc = DECL_SOURCE_LOCATION (old_decl); + warn_parm_array_mismatch (origloc, old_decl, parms); + } + /* Record the decl so that the function name is defined. If we already have a decl for this name, and it is a FUNCTION_DECL, use the old decl. */ current_function_decl = pushdecl (decl1); + if (tree access = build_attr_access_from_parms (parms, false)) + decl_attributes (¤t_function_decl, access, 0, old_decl); + push_scope (); declare_parm_level (); diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index 2e6775a..7d58356 100644 --- a/gcc/c/c-parser.c +++ b/gcc/c/c-parser.c @@ -68,6 +68,7 @@ along with GCC; see the file COPYING3. If not see #include "intl.h" #include "c-family/name-hint.h" #include "tree-iterator.h" +#include "tree-pretty-print.h" #include "memmodel.h" #include "c-family/known-headers.h" @@ -2299,13 +2300,11 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok, c_parser_skip_to_end_of_block_or_statement (parser); return; } - tree d = start_decl (declarator, specs, false, - chainon (postfix_attrs, - all_prefix_attrs)); - if (d - && TREE_CODE (d) == FUNCTION_DECL - && DECL_ARGUMENTS (d) == NULL_TREE - && DECL_INITIAL (d) == NULL_TREE) + + location_t lastloc = UNKNOWN_LOCATION; + tree attrs = chainon (postfix_attrs, all_prefix_attrs); + tree d = start_decl (declarator, specs, false, attrs, &lastloc); + if (d && TREE_CODE (d) == FUNCTION_DECL) { /* Find the innermost declarator that is neither cdk_id nor cdk_attrs. */ @@ -2334,10 +2333,18 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok, gcc_unreachable (); } - /* If it exists and is cdk_function, use its parameters. */ + /* If it exists and is cdk_function declaration whose + arguments have not been set yet, use its arguments. */ if (last_non_id_attrs && last_non_id_attrs->kind == cdk_function) - DECL_ARGUMENTS (d) = last_non_id_attrs->u.arg_info->parms; + { + tree parms = last_non_id_attrs->u.arg_info->parms; + if (DECL_ARGUMENTS (d) == NULL_TREE + && DECL_INITIAL (d) == NULL_TREE) + DECL_ARGUMENTS (d) = parms; + + warn_parm_array_mismatch (lastloc, d, parms); + } } if (omp_declare_simd_clauses.exists ()) { @@ -2366,7 +2373,7 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok, if (d) finish_decl (d, UNKNOWN_LOCATION, NULL_TREE, NULL_TREE, asm_name); - + if (c_parser_next_token_is_keyword (parser, RID_IN)) { if (d) diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h index 7e51859..287b1df 100644 --- a/gcc/c/c-tree.h +++ b/gcc/c/c-tree.h @@ -620,7 +620,7 @@ extern void shadow_tag_warned (const struct c_declspecs *, int); extern tree start_enum (location_t, struct c_enum_contents *, tree); extern bool start_function (struct c_declspecs *, struct c_declarator *, tree); extern tree start_decl (struct c_declarator *, struct c_declspecs *, bool, - tree); + tree, location_t * = NULL); extern tree start_struct (location_t, enum tree_code, tree, class c_struct_parse_info **); extern void store_parm_decls (void); -- cgit v1.1 From 2fe5b7d1f66457c637b8bd2543a60a5faff34c40 Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Sun, 20 Sep 2020 00:16:23 +0000 Subject: Daily bump. --- gcc/c/ChangeLog | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) (limited to 'gcc/c') diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index eb68b12..839bfa1 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,59 @@ +2020-09-19 Martin Sebor + + PR c/50584 + * c-decl.c (lookup_last_decl): Define new function. + (c_decl_attributes): Call it. + (start_decl): Add argument and use it. + (finish_decl): Call build_attr_access_from_parms and decl_attributes. + (get_parm_array_spec): Define new function. + (push_parm_decl): Call get_parm_array_spec. + (start_function): Call warn_parm_array_mismatch. Build attribute + access and add it to current function. + * c-parser.c (c_parser_declaration_or_fndef): Diagnose mismatches + in forms of array parameters. + * c-tree.h (start_decl): Add argument. + +2020-09-19 Sandra Loosemore + + * c-decl.c (c_break_label, c_cont_label): Delete, and replace + with... + (in_statement): New. + (start_function): Adjust for above change. + (c_push_function_context, c_pop_function_context): Likewise. + * c-lang.h (struct language_function): Likewise. + * c-objc-common.h (LANG_HOOKS_BLOCK_MAY_FALLTHRU): Define. + * c-parser.c (objc_foreach_break_label, objc_foreach_continue_label): + New. + (c_parser_statement_after_labels): Adjust calls to c_finish_bc_stmt. + (c_parser_switch_statement): Adjust break/switch context handling + and calls to renamed functions. + (c_parser_while_statement): Adjust break/switch context handling and + build a WHILE_STMT. + (c_parser_do_statement): Ditto, with DO_STMT respectively. + (c_parser_for_statement): Ditto, with FOR_STMT respectively. + (c_parser_omp_for_loop): Adjust break/switch context handling. + * c-tree.h (c_break_label, c_cont_label): Delete. + (IN_SWITCH_STMT, IN_ITERATION_STMT): Define. + (IN_OMP_BLOCK, IN_OMP_FOR, IN_OBJC_FOREACH): Define. + (in_statement, switch_statement_break_seen_p): Declare. + (c_start_case, c_finish_case): Renamed to... + (c_start_switch, c_finish_switch). + (c_finish_bc_stmt): Adjust arguments. + * c-typeck.c (build_function_call_vec): Don't try to print + statements with %qE format. + (struct c_switch): Rename switch_expr field to switch_stmt. + Add break_stmt_seen_p field. + (c_start_case): Rename to c_start_switch. Build a SWITCH_STMT + instead of a SWITCH_EXPR. Update for changes to struct c_switch. + (do_case): Update for changes to struct c_switch. + (c_finish_case): Rename to c_finish_switch. Update for changes to + struct c_switch and change of representation from SWITCH_EXPR to + SWITCH_STMT. + (c_finish_loop): Delete. + (c_finish_bc_stmt): Update to reflect changes to break/continue + state representation. Build a BREAK_STMT or CONTINUE_STMT instead + of a GOTO_EXPR except for objc foreach loops. + 2020-09-01 Jakub Jelinek PR c++/96867 -- cgit v1.1