From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1930) id 6B3D23846027; Fri, 25 Jun 2021 01:32:18 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 6B3D23846027 MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Martin Sebor To: gcc-cvs@gcc.gnu.org Subject: [gcc r12-1805] middle-end: add support for per-location warning groups. X-Act-Checkin: gcc X-Git-Author: Martin Sebor X-Git-Refname: refs/heads/master X-Git-Oldrev: 65870e75616ee4359d1c13b99be794e6a577bc65 X-Git-Newrev: e9e2bad7251477db92ab9ebcdc010f9282dd9890 Message-Id: <20210625013218.6B3D23846027@sourceware.org> Date: Fri, 25 Jun 2021 01:32:18 +0000 (GMT) X-BeenThere: gcc-cvs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 25 Jun 2021 01:32:18 -0000 https://gcc.gnu.org/g:e9e2bad7251477db92ab9ebcdc010f9282dd9890 commit r12-1805-ge9e2bad7251477db92ab9ebcdc010f9282dd9890 Author: Martin Sebor Date: Thu Jun 24 19:22:06 2021 -0600 middle-end: add support for per-location warning groups. gcc/ChangeLog: * builtins.c (warn_string_no_nul): Replace uses of TREE_NO_WARNING, gimple_no_warning_p and gimple_set_no_warning with warning_suppressed_p, and suppress_warning. (c_strlen): Same. (maybe_warn_for_bound): Same. (warn_for_access): Same. (check_access): Same. (expand_builtin_strncmp): Same. (fold_builtin_varargs): Same. * calls.c (maybe_warn_nonstring_arg): Same. (maybe_warn_rdwr_sizes): Same. * cfgexpand.c (expand_call_stmt): Same. * cgraphunit.c (check_global_declaration): Same. * fold-const.c (fold_undefer_overflow_warnings): Same. (fold_truth_not_expr): Same. (fold_unary_loc): Same. (fold_checksum_tree): Same. * gimple-array-bounds.cc (array_bounds_checker::check_array_ref): Same. (array_bounds_checker::check_mem_ref): Same. (array_bounds_checker::check_addr_expr): Same. (array_bounds_checker::check_array_bounds): Same. * gimple-expr.c (copy_var_decl): Same. * gimple-fold.c (gimple_fold_builtin_strcpy): Same. (gimple_fold_builtin_strncat): Same. (gimple_fold_builtin_stxcpy_chk): Same. (gimple_fold_builtin_stpcpy): Same. (gimple_fold_builtin_sprintf): Same. (fold_stmt_1): Same. * gimple-ssa-isolate-paths.c (diag_returned_locals): Same. * gimple-ssa-nonnull-compare.c (do_warn_nonnull_compare): Same. * gimple-ssa-sprintf.c (handle_printf_call): Same. * gimple-ssa-store-merging.c (imm_store_chain_info::output_merged_store): Same. * gimple-ssa-warn-restrict.c (maybe_diag_overlap): Same. * gimple-ssa-warn-restrict.h: Adjust declarations. (maybe_diag_access_bounds): Replace uses of TREE_NO_WARNING, gimple_no_warning_p and gimple_set_no_warning with warning_suppressed_p, and suppress_warning. (check_call): Same. (check_bounds_or_overlap): Same. * gimple.c (gimple_build_call_from_tree): Same. * gimplify.c (gimplify_return_expr): Same. (gimplify_cond_expr): Same. (gimplify_modify_expr_complex_part): Same. (gimplify_modify_expr): Same. (gimple_push_cleanup): Same. (gimplify_expr): Same. * omp-expand.c (expand_omp_for_generic): Same. (expand_omp_taskloop_for_outer): Same. * omp-low.c (lower_rec_input_clauses): Same. (lower_lastprivate_clauses): Same. (lower_send_clauses): Same. (lower_omp_target): Same. * tree-cfg.c (pass_warn_function_return::execute): Same. * tree-complex.c (create_one_component_var): Same. * tree-inline.c (remap_gimple_op_r): Same. (copy_tree_body_r): Same. (declare_return_variable): Same. (expand_call_inline): Same. * tree-nested.c (lookup_field_for_decl): Same. * tree-sra.c (create_access_replacement): Same. (generate_subtree_copies): Same. * tree-ssa-ccp.c (pass_post_ipa_warn::execute): Same. * tree-ssa-forwprop.c (combine_cond_expr_cond): Same. * tree-ssa-loop-ch.c (ch_base::copy_headers): Same. * tree-ssa-loop-im.c (execute_sm): Same. * tree-ssa-phiopt.c (cond_store_replacement): Same. * tree-ssa-strlen.c (maybe_warn_overflow): Same. (handle_builtin_strcpy): Same. (maybe_diag_stxncpy_trunc): Same. (handle_builtin_stxncpy_strncat): Same. (handle_builtin_strcat): Same. * tree-ssa-uninit.c (get_no_uninit_warning): Same. (set_no_uninit_warning): Same. (uninit_undefined_value_p): Same. (warn_uninit): Same. (maybe_warn_operand): Same. * tree-vrp.c (compare_values_warnv): Same. * vr-values.c (vr_values::extract_range_for_var_from_comparison_expr): Same. (test_for_singularity): Same. * gimple.h (warning_suppressed_p): New function. (suppress_warning): Same. (copy_no_warning): Same. (gimple_set_block): Call gimple_set_location. (gimple_set_location): Call copy_warning. Diff: --- gcc/builtins.c | 90 ++++++++++++++++--------------- gcc/calls.c | 90 ++++++++++++++++--------------- gcc/cfgexpand.c | 6 +-- gcc/cgraphunit.c | 2 +- gcc/fold-const.c | 13 +++-- gcc/gimple-array-bounds.cc | 21 ++++---- gcc/gimple-expr.c | 2 +- gcc/gimple-fold.c | 27 +++++----- gcc/gimple-ssa-isolate-paths.c | 5 ++ gcc/gimple-ssa-nonnull-compare.c | 2 +- gcc/gimple-ssa-sprintf.c | 10 ++-- gcc/gimple-ssa-store-merging.c | 12 +++-- gcc/gimple-ssa-warn-restrict.c | 114 +++++++++++++++++++++------------------ gcc/gimple-ssa-warn-restrict.h | 10 ++-- gcc/gimple.c | 2 +- gcc/gimple.h | 25 ++++++++- gcc/gimplify.c | 17 +++--- gcc/omp-expand.c | 6 +-- gcc/omp-low.c | 16 +++--- gcc/tree-cfg.c | 10 ++-- gcc/tree-complex.c | 4 +- gcc/tree-inline.c | 8 +-- gcc/tree-nested.c | 2 +- gcc/tree-sra.c | 8 +-- gcc/tree-ssa-ccp.c | 2 +- gcc/tree-ssa-forwprop.c | 3 +- gcc/tree-ssa-loop-ch.c | 4 +- gcc/tree-ssa-loop-im.c | 2 +- gcc/tree-ssa-phiopt.c | 9 ++-- gcc/tree-ssa-strlen.c | 68 ++++++++++++----------- gcc/tree-ssa-uninit.c | 42 ++++++++++----- gcc/tree-vrp.c | 12 ++--- gcc/vr-values.c | 8 +-- 33 files changed, 359 insertions(+), 293 deletions(-) diff --git a/gcc/builtins.c b/gcc/builtins.c index 855ad1eb6bb..e5e39386a93 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -1095,7 +1095,9 @@ warn_string_no_nul (location_t loc, tree expr, const char *fname, bool exact /* = false */, const wide_int bndrng[2] /* = NULL */) { - if ((expr && TREE_NO_WARNING (expr)) || TREE_NO_WARNING (arg)) + const opt_code opt = OPT_Wstringop_overread; + if ((expr && warning_suppressed_p (expr, opt)) + || warning_suppressed_p (arg, opt)) return; loc = expansion_point_location_if_in_system_header (loc); @@ -1123,14 +1125,14 @@ warn_string_no_nul (location_t loc, tree expr, const char *fname, if (bndrng) { if (wi::ltu_p (maxsiz, bndrng[0])) - warned = warning_at (loc, OPT_Wstringop_overread, + warned = warning_at (loc, opt, "%K%qD specified bound %s exceeds " "maximum object size %E", expr, func, bndstr, maxobjsize); else { bool maybe = wi::to_wide (size) == bndrng[0]; - warned = warning_at (loc, OPT_Wstringop_overread, + warned = warning_at (loc, opt, exact ? G_("%K%qD specified bound %s exceeds " "the size %E of unterminated array") @@ -1145,7 +1147,7 @@ warn_string_no_nul (location_t loc, tree expr, const char *fname, } } else - warned = warning_at (loc, OPT_Wstringop_overread, + warned = warning_at (loc, opt, "%K%qD argument missing terminating nul", expr, func); } @@ -1154,14 +1156,14 @@ warn_string_no_nul (location_t loc, tree expr, const char *fname, if (bndrng) { if (wi::ltu_p (maxsiz, bndrng[0])) - warned = warning_at (loc, OPT_Wstringop_overread, + warned = warning_at (loc, opt, "%qs specified bound %s exceeds " "maximum object size %E", fname, bndstr, maxobjsize); else { bool maybe = wi::to_wide (size) == bndrng[0]; - warned = warning_at (loc, OPT_Wstringop_overread, + warned = warning_at (loc, opt, exact ? G_("%qs specified bound %s exceeds " "the size %E of unterminated array") @@ -1176,7 +1178,7 @@ warn_string_no_nul (location_t loc, tree expr, const char *fname, } } else - warned = warning_at (loc, OPT_Wstringop_overread, + warned = warning_at (loc, opt, "%qs argument missing terminating nul", fname); } @@ -1185,9 +1187,9 @@ warn_string_no_nul (location_t loc, tree expr, const char *fname, { inform (DECL_SOURCE_LOCATION (decl), "referenced argument declared here"); - TREE_NO_WARNING (arg) = 1; + suppress_warning (arg, opt); if (expr) - TREE_NO_WARNING (expr) = 1; + suppress_warning (expr, opt); } } @@ -1445,14 +1447,14 @@ c_strlen (tree arg, int only_value, c_strlen_data *data, unsigned eltsize) { /* Suppress multiple warnings for propagated constant strings. */ if (only_value != 2 - && !TREE_NO_WARNING (arg) + && !warning_suppressed_p (arg, OPT_Warray_bounds) && warning_at (loc, OPT_Warray_bounds, "offset %qwi outside bounds of constant string", eltoff)) { if (decl) inform (DECL_SOURCE_LOCATION (decl), "%qE declared here", decl); - TREE_NO_WARNING (arg) = 1; + suppress_warning (arg, OPT_Warray_bounds); } return NULL_TREE; } @@ -3947,10 +3949,10 @@ determine_block_size (tree len, rtx len_rtx, accessing an object with SIZE. */ static bool -maybe_warn_for_bound (int opt, location_t loc, tree exp, tree func, +maybe_warn_for_bound (opt_code opt, location_t loc, tree exp, tree func, tree bndrng[2], tree size, const access_data *pad = NULL) { - if (!bndrng[0] || TREE_NO_WARNING (exp)) + if (!bndrng[0] || warning_suppressed_p (exp, opt)) return false; tree maxobjsize = max_object_size (); @@ -4042,7 +4044,7 @@ maybe_warn_for_bound (int opt, location_t loc, tree exp, tree func, inform (EXPR_LOCATION (pad->src.ref), "source object allocated here"); } - TREE_NO_WARNING (exp) = true; + suppress_warning (exp, opt); } return warned; @@ -4089,14 +4091,14 @@ maybe_warn_for_bound (int opt, location_t loc, tree exp, tree func, return false; else if (tree_int_cst_equal (bndrng[0], bndrng[1])) warned = (func - ? warning_at (loc, OPT_Wstringop_overflow_, + ? warning_at (loc, opt, (maybe ? G_("%K%qD specified bound %E may exceed " "destination size %E") : G_("%K%qD specified bound %E exceeds " "destination size %E")), exp, func, bndrng[0], size) - : warning_at (loc, OPT_Wstringop_overflow_, + : warning_at (loc, opt, (maybe ? G_("%Kspecified bound %E may exceed " "destination size %E") @@ -4105,14 +4107,14 @@ maybe_warn_for_bound (int opt, location_t loc, tree exp, tree func, exp, bndrng[0], size)); else warned = (func - ? warning_at (loc, OPT_Wstringop_overflow_, + ? warning_at (loc, opt, (maybe ? G_("%K%qD specified bound [%E, %E] may exceed " "destination size %E") : G_("%K%qD specified bound [%E, %E] exceeds " "destination size %E")), exp, func, bndrng[0], bndrng[1], size) - : warning_at (loc, OPT_Wstringop_overflow_, + : warning_at (loc, opt, (maybe ? G_("%Kspecified bound [%E, %E] exceeds " "destination size %E") @@ -4131,7 +4133,7 @@ maybe_warn_for_bound (int opt, location_t loc, tree exp, tree func, inform (EXPR_LOCATION (pad->dst.ref), "destination object allocated here"); } - TREE_NO_WARNING (exp) = true; + suppress_warning (exp, opt); } return warned; @@ -4357,7 +4359,7 @@ warn_for_access (location_t loc, tree func, tree exp, int opt, tree range[2], exp, range[0], range[1], size)); if (warned) - TREE_NO_WARNING (exp) = true; + suppress_warning (exp, OPT_Wstringop_overread); return warned; } @@ -4400,7 +4402,7 @@ warn_for_access (location_t loc, tree func, tree exp, int opt, tree range[2], exp, range[0], range[1], size)); if (warned) - TREE_NO_WARNING (exp) = true; + suppress_warning (exp, OPT_Wstringop_overread); return warned; } @@ -4779,8 +4781,10 @@ check_access (tree exp, tree dstwrite, && tree_fits_uhwi_p (dstwrite) && tree_int_cst_lt (dstwrite, range[0])))) { - if (TREE_NO_WARNING (exp) - || (pad && pad->dst.ref && TREE_NO_WARNING (pad->dst.ref))) + const opt_code opt = OPT_Wstringop_overflow_; + if (warning_suppressed_p (exp, opt) + || (pad && pad->dst.ref + && warning_suppressed_p (pad->dst.ref, opt))) return false; location_t loc = tree_inlined_location (exp); @@ -4791,12 +4795,12 @@ check_access (tree exp, tree dstwrite, and a source of unknown length. The call will write at least one byte past the end of the destination. */ warned = (func - ? warning_at (loc, OPT_Wstringop_overflow_, + ? warning_at (loc, opt, "%K%qD writing %E or more bytes into " "a region of size %E overflows " "the destination", exp, func, range[0], dstsize) - : warning_at (loc, OPT_Wstringop_overflow_, + : warning_at (loc, opt, "%Kwriting %E or more bytes into " "a region of size %E overflows " "the destination", @@ -4817,7 +4821,7 @@ check_access (tree exp, tree dstwrite, if (warned) { - TREE_NO_WARNING (exp) = true; + suppress_warning (exp, OPT_Wstringop_overflow_); if (pad) pad->dst.inform_access (pad->mode); } @@ -4852,9 +4856,9 @@ check_access (tree exp, tree dstwrite, if (size != maxobjsize && tree_int_cst_lt (size, range[0])) { - int opt = (dstwrite || mode != access_read_only - ? OPT_Wstringop_overflow_ - : OPT_Wstringop_overread); + opt_code opt = (dstwrite || mode != access_read_only + ? OPT_Wstringop_overflow_ + : OPT_Wstringop_overread); maybe_warn_for_bound (opt, loc, exp, func, range, size, pad); return false; } @@ -4890,19 +4894,21 @@ check_access (tree exp, tree dstwrite, if (overread) { - if (TREE_NO_WARNING (exp) - || (srcstr && TREE_NO_WARNING (srcstr)) - || (pad && pad->src.ref && TREE_NO_WARNING (pad->src.ref))) + const opt_code opt = OPT_Wstringop_overread; + if (warning_suppressed_p (exp, opt) + || (srcstr && warning_suppressed_p (srcstr, opt)) + || (pad && pad->src.ref + && warning_suppressed_p (pad->src.ref, opt))) return false; location_t loc = tree_inlined_location (exp); const bool read = mode == access_read_only || mode == access_read_write; const bool maybe = pad && pad->dst.parmarray; - if (warn_for_access (loc, func, exp, OPT_Wstringop_overread, range, - slen, false, read, maybe)) + if (warn_for_access (loc, func, exp, opt, range, slen, false, read, + maybe)) { - TREE_NO_WARNING (exp) = true; + suppress_warning (exp, opt); if (pad) pad->src.inform_access (access_read_only); } @@ -7462,8 +7468,7 @@ expand_builtin_strncmp (tree exp, ATTRIBUTE_UNUSED rtx target, /* Expand the library call ourselves using a stabilized argument list to avoid re-evaluating the function's arguments twice. */ tree call = build_call_nofold_loc (loc, fndecl, 3, arg1, arg2, len); - if (TREE_NO_WARNING (exp)) - TREE_NO_WARNING (call) = true; + copy_warning (call, exp); gcc_assert (TREE_CODE (call) == CALL_EXPR); CALL_EXPR_TAILCALL (call) = CALL_EXPR_TAILCALL (exp); return expand_call (call, target, target == const0_rtx); @@ -13898,10 +13903,11 @@ maybe_emit_free_warning (tree exp) else { tree alloc_decl = gimple_call_fndecl (def_stmt); - int opt = (DECL_IS_OPERATOR_NEW_P (alloc_decl) - || DECL_IS_OPERATOR_DELETE_P (dealloc_decl) - ? OPT_Wmismatched_new_delete - : OPT_Wmismatched_dealloc); + const opt_code opt = + (DECL_IS_OPERATOR_NEW_P (alloc_decl) + || DECL_IS_OPERATOR_DELETE_P (dealloc_decl) + ? OPT_Wmismatched_new_delete + : OPT_Wmismatched_dealloc); warned = warning_at (loc, opt, "%K%qD called on pointer returned " "from a mismatched allocation " @@ -14012,7 +14018,7 @@ fold_builtin_varargs (location_t loc, tree fndecl, tree *args, int nargs) { ret = build1 (NOP_EXPR, TREE_TYPE (ret), ret); SET_EXPR_LOCATION (ret, loc); - TREE_NO_WARNING (ret) = 1; + suppress_warning (ret); return ret; } return NULL_TREE; diff --git a/gcc/calls.c b/gcc/calls.c index 4bf2b5dabe7..27e8c451635 100644 --- a/gcc/calls.c +++ b/gcc/calls.c @@ -1623,7 +1623,7 @@ maybe_warn_nonstring_arg (tree fndecl, tree exp) if (!fndecl || !fndecl_built_in_p (fndecl, BUILT_IN_NORMAL)) return false; - if (TREE_NO_WARNING (exp) || !warn_stringop_overread) + if (!warn_stringop_overread || warning_suppressed_p (exp, OPT_Wstringop_overread)) return false; /* Avoid clearly invalid calls (more checking done below). */ @@ -1739,7 +1739,7 @@ maybe_warn_nonstring_arg (tree fndecl, tree exp) exp, fndecl, bndrng[0], bndrng[1], maxobjsize); if (warned) - TREE_NO_WARNING (exp) = true; + suppress_warning (exp, OPT_Wstringop_overread); return warned; } @@ -1916,7 +1916,7 @@ maybe_warn_nonstring_arg (tree fndecl, tree exp) } if (any_arg_warned) - TREE_NO_WARNING (exp) = true; + suppress_warning (exp, OPT_Wstringop_overread); return any_arg_warned; } @@ -1979,7 +1979,7 @@ maybe_warn_rdwr_sizes (rdwr_map *rwm, tree fndecl, tree fntype, tree exp) /* Set if a warning has been issued for any argument (used to decide whether to emit an informational note at the end). */ - bool any_warned = false; + opt_code opt_warned = N_OPTS; /* A string describing the attributes that the warnings issued by this function apply to. Used to print one informational note per function @@ -2054,7 +2054,7 @@ maybe_warn_rdwr_sizes (rdwr_map *rwm, tree fndecl, tree fntype, tree exp) *sizstr = '\0'; /* Set if a warning has been issued for the current argument. */ - bool arg_warned = false; + opt_code arg_warned = N_OPTS; location_t loc = EXPR_LOCATION (exp); tree ptr = access.second.ptr; if (*sizstr @@ -2067,24 +2067,25 @@ maybe_warn_rdwr_sizes (rdwr_map *rwm, tree fndecl, tree fntype, tree exp) const std::string argtypestr = access.second.array_as_string (ptrtype); - arg_warned = warning_at (loc, OPT_Wstringop_overflow_, - "%Kbound argument %i value %s is " - "negative for a variable length array " - "argument %i of type %s", - exp, sizidx + 1, sizstr, - ptridx + 1, argtypestr.c_str ()); + if (warning_at (loc, OPT_Wstringop_overflow_, + "%Kbound argument %i value %s is " + "negative for a variable length array " + "argument %i of type %s", + exp, sizidx + 1, sizstr, + ptridx + 1, argtypestr.c_str ())) + arg_warned = OPT_Wstringop_overflow_; } - else - arg_warned = warning_at (loc, OPT_Wstringop_overflow_, - "%Kargument %i value %s is negative", - exp, sizidx + 1, sizstr); + else if (warning_at (loc, OPT_Wstringop_overflow_, + "%Kargument %i value %s is negative", + exp, sizidx + 1, sizstr)) + arg_warned = OPT_Wstringop_overflow_; - if (arg_warned) + if (arg_warned != N_OPTS) { append_attrname (access, attrstr, sizeof attrstr); /* Remember a warning has been issued and avoid warning again below for the same attribute. */ - any_warned = true; + opt_warned = arg_warned; continue; } } @@ -2122,31 +2123,33 @@ maybe_warn_rdwr_sizes (rdwr_map *rwm, tree fndecl, tree fntype, tree exp) const std::string argtypestr = access.second.array_as_string (ptrtype); - arg_warned = warning_at (loc, OPT_Wnonnull, - "%Kargument %i of variable length " - "array %s is null but " - "the corresponding bound argument " - "%i value is %s", - exp, sizidx + 1, argtypestr.c_str (), - ptridx + 1, sizstr); + if (warning_at (loc, OPT_Wnonnull, + "%Kargument %i of variable length " + "array %s is null but " + "the corresponding bound argument " + "%i value is %s", + exp, sizidx + 1, argtypestr.c_str (), + ptridx + 1, sizstr)) + arg_warned = OPT_Wnonnull; } - else - arg_warned = warning_at (loc, OPT_Wnonnull, - "%Kargument %i is null but " - "the corresponding size argument " - "%i value is %s", - exp, ptridx + 1, sizidx + 1, - sizstr); + else if (warning_at (loc, OPT_Wnonnull, + "%Kargument %i is null but " + "the corresponding size argument " + "%i value is %s", + exp, ptridx + 1, sizidx + 1, + sizstr)) + arg_warned = OPT_Wnonnull; } else if (access_size && access.second.static_p) { /* Warn about null pointers for [static N] array arguments but do not warn for ordinary (i.e., nonstatic) arrays. */ - arg_warned = warning_at (loc, OPT_Wnonnull, - "%Kargument %i to %<%T[static %E]%> " - "is null where non-null expected", - exp, ptridx + 1, argtype, - access_size); + if (warning_at (loc, OPT_Wnonnull, + "%Kargument %i to %<%T[static %E]%> " + "is null where non-null expected", + exp, ptridx + 1, argtype, + access_size)) + arg_warned = OPT_Wnonnull; } if (arg_warned) @@ -2154,7 +2157,7 @@ maybe_warn_rdwr_sizes (rdwr_map *rwm, tree fndecl, tree fntype, tree exp) append_attrname (access, attrstr, sizeof attrstr); /* Remember a warning has been issued and avoid warning again below for the same attribute. */ - any_warned = true; + opt_warned = OPT_Wnonnull; continue; } } @@ -2190,17 +2193,17 @@ maybe_warn_rdwr_sizes (rdwr_map *rwm, tree fndecl, tree fntype, tree exp) /* Clear the no-warning bit in case it was set by check_access in a prior iteration so that accesses via different arguments are diagnosed. */ - TREE_NO_WARNING (exp) = false; + suppress_warning (exp, OPT_Wstringop_overflow_, false); access_mode mode = data.mode; if (mode == access_deferred) mode = TYPE_READONLY (argtype) ? access_read_only : access_read_write; check_access (exp, access_size, /*maxread=*/ NULL_TREE, srcsize, dstsize, mode, &data); - if (TREE_NO_WARNING (exp)) + if (warning_suppressed_p (exp, OPT_Wstringop_overflow_)) + opt_warned = OPT_Wstringop_overflow_; + if (opt_warned != N_OPTS) { - any_warned = true; - if (access.second.internal_p) inform (loc, "referencing argument %u of type %qT", ptridx + 1, ptrtype); @@ -2222,7 +2225,7 @@ maybe_warn_rdwr_sizes (rdwr_map *rwm, tree fndecl, tree fntype, tree exp) "in a call with type %qT and attribute %qs", fntype, attrstr); } - else if (any_warned) + else if (opt_warned != N_OPTS) { if (fndecl) inform (DECL_SOURCE_LOCATION (fndecl), @@ -2233,7 +2236,8 @@ maybe_warn_rdwr_sizes (rdwr_map *rwm, tree fndecl, tree fntype, tree exp) } /* Set the bit in case if was cleared and not set above. */ - TREE_NO_WARNING (exp) = true; + if (opt_warned != N_OPTS) + suppress_warning (exp, opt_warned); } /* Fill in ARGS_SIZE and ARGS array based on the parameters found in diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c index 6394cfdcb56..3edd53c37dc 100644 --- a/gcc/cfgexpand.c +++ b/gcc/cfgexpand.c @@ -2807,9 +2807,6 @@ expand_call_stmt (gcall *stmt) if (gimple_call_nothrow_p (stmt)) TREE_NOTHROW (exp) = 1; - if (gimple_no_warning_p (stmt)) - TREE_NO_WARNING (exp) = 1; - CALL_EXPR_TAILCALL (exp) = gimple_call_tail_p (stmt); CALL_EXPR_MUST_TAIL_CALL (exp) = gimple_call_must_tail_p (stmt); CALL_EXPR_RETURN_SLOT_OPT (exp) = gimple_call_return_slot_opt_p (stmt); @@ -2823,6 +2820,9 @@ expand_call_stmt (gcall *stmt) CALL_EXPR_BY_DESCRIPTOR (exp) = gimple_call_by_descriptor_p (stmt); SET_EXPR_LOCATION (exp, gimple_location (stmt)); + /* Must come after copying location. */ + copy_warning (exp, stmt); + /* Ensure RTL is created for debug args. */ if (decl && DECL_HAS_DEBUG_ARGS_P (decl)) { diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index 098eb99dc95..55cb0347149 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -1074,7 +1074,7 @@ check_global_declaration (symtab_node *snode) && ! DECL_ARTIFICIAL (decl) && ! TREE_PUBLIC (decl)) { - if (TREE_NO_WARNING (decl)) + if (warning_suppressed_p (decl, OPT_Wunused)) ; else if (snode->referred_to_p (/*include_self=*/false)) pedwarn (input_location, 0, "%q+F used but never defined", decl); diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 0b33ee99a81..3aafbc98800 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -250,7 +250,7 @@ fold_undefer_overflow_warnings (bool issue, const gimple *stmt, int code) if (!issue || warnmsg == NULL) return; - if (gimple_no_warning_p (stmt)) + if (warning_suppressed_p (stmt, OPT_Wstrict_overflow)) return; /* Use the smallest code level when deciding to issue the @@ -4250,8 +4250,7 @@ fold_truth_not_expr (location_t loc, tree arg) tree ret = build2_loc (loc, code, type, TREE_OPERAND (arg, 0), TREE_OPERAND (arg, 1)); - if (TREE_NO_WARNING (arg)) - TREE_NO_WARNING (ret) = 1; + copy_warning (ret, arg); return ret; } @@ -9346,7 +9345,7 @@ fold_unary_loc (location_t loc, enum tree_code code, tree type, tree op0) tem = fold_build1_loc (loc, code, type, TREE_OPERAND (op0, 1)); /* First do the assignment, then return converted constant. */ tem = build2_loc (loc, COMPOUND_EXPR, TREE_TYPE (tem), op0, tem); - TREE_NO_WARNING (tem) = 1; + suppress_warning (tem /* What warning? */); TREE_USED (tem) = 1; return tem; } @@ -13519,10 +13518,10 @@ fold_checksum_tree (const_tree expr, struct md5_ctx *ctx, TYPE_CACHED_VALUES (tmp) = NULL; } } - else if (TREE_NO_WARNING (expr) && (DECL_P (expr) || EXPR_P (expr))) + else if (warning_suppressed_p (expr) && (DECL_P (expr) || EXPR_P (expr))) { - /* Allow TREE_NO_WARNING to be set. Perhaps we shouldn't allow that - and change builtins.c etc. instead - see PR89543. */ + /* Allow the no-warning bit to be set. Perhaps we shouldn't allow + that and change builtins.c etc. instead - see PR89543. */ size_t sz = tree_size (expr); buf = XALLOCAVAR (union tree_node, sz); memcpy ((char *) buf, expr, sz); diff --git a/gcc/gimple-array-bounds.cc b/gcc/gimple-array-bounds.cc index 199d9f5d216..13f08685f8f 100644 --- a/gcc/gimple-array-bounds.cc +++ b/gcc/gimple-array-bounds.cc @@ -175,7 +175,7 @@ bool array_bounds_checker::check_array_ref (location_t location, tree ref, bool ignore_off_by_one) { - if (TREE_NO_WARNING (ref)) + if (warning_suppressed_p (ref, OPT_Warray_bounds)) /* Return true to have the caller prevent warnings for enclosing refs. */ return true; @@ -346,7 +346,7 @@ array_bounds_checker::check_array_ref (location_t location, tree ref, /* Avoid more warnings when checking more significant subscripts of the same expression. */ ref = TREE_OPERAND (ref, 0); - TREE_NO_WARNING (ref) = 1; + suppress_warning (ref, OPT_Warray_bounds); if (decl) ref = decl; @@ -411,7 +411,7 @@ bool array_bounds_checker::check_mem_ref (location_t location, tree ref, bool ignore_off_by_one) { - if (TREE_NO_WARNING (ref)) + if (warning_suppressed_p (ref, OPT_Warray_bounds)) return false; tree arg = TREE_OPERAND (ref, 0); @@ -770,7 +770,7 @@ array_bounds_checker::check_mem_ref (location_t location, tree ref, } } - TREE_NO_WARNING (ref) = 1; + suppress_warning (ref, OPT_Warray_bounds); return true; } @@ -787,7 +787,7 @@ array_bounds_checker::check_mem_ref (location_t location, tree ref, "intermediate array offset %wi is outside array bounds " "of %qT", tmpidx, reftype)) { - TREE_NO_WARNING (ref) = 1; + suppress_warning (ref, OPT_Warray_bounds); return true; } } @@ -818,7 +818,7 @@ array_bounds_checker::check_addr_expr (location_t location, tree t) warned = check_mem_ref (location, t, ignore_off_by_one); if (warned) - TREE_NO_WARNING (t) = true; + suppress_warning (t, OPT_Warray_bounds); t = TREE_OPERAND (t, 0); } @@ -826,7 +826,7 @@ array_bounds_checker::check_addr_expr (location_t location, tree t) if (TREE_CODE (t) != MEM_REF || TREE_CODE (TREE_OPERAND (t, 0)) != ADDR_EXPR - || TREE_NO_WARNING (t)) + || warning_suppressed_p (t, OPT_Warray_bounds)) return; tree tem = TREE_OPERAND (TREE_OPERAND (t, 0), 0); @@ -886,7 +886,7 @@ array_bounds_checker::check_addr_expr (location_t location, tree t) if (DECL_P (t)) inform (DECL_SOURCE_LOCATION (t), "while referencing %qD", t); - TREE_NO_WARNING (t) = 1; + suppress_warning (t, OPT_Warray_bounds); } } @@ -980,9 +980,10 @@ array_bounds_checker::check_array_bounds (tree *tp, int *walk_subtree, See pr98266 and pr97595. */ *walk_subtree = false; - /* Propagate the no-warning bit to the outer expression. */ + /* Propagate the no-warning bit to the outer statement to avoid also + issuing -Wstringop-overflow/-overread for the out-of-bounds accesses. */ if (warned) - TREE_NO_WARNING (t) = true; + suppress_warning (wi->stmt, OPT_Warray_bounds); return NULL_TREE; } diff --git a/gcc/gimple-expr.c b/gcc/gimple-expr.c index c3211795d33..a2563a45c37 100644 --- a/gcc/gimple-expr.c +++ b/gcc/gimple-expr.c @@ -377,7 +377,6 @@ copy_var_decl (tree var, tree name, tree type) DECL_ARTIFICIAL (copy) = DECL_ARTIFICIAL (var); DECL_IGNORED_P (copy) = DECL_IGNORED_P (var); DECL_CONTEXT (copy) = DECL_CONTEXT (var); - TREE_NO_WARNING (copy) = TREE_NO_WARNING (var); TREE_USED (copy) = 1; DECL_SEEN_IN_BIND_EXPR_P (copy) = 1; DECL_ATTRIBUTES (copy) = DECL_ATTRIBUTES (var); @@ -387,6 +386,7 @@ copy_var_decl (tree var, tree name, tree type) DECL_USER_ALIGN (copy) = 1; } + copy_warning (copy, var); return copy; } diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c index 1c0e930aba5..68031538145 100644 --- a/gcc/gimple-fold.c +++ b/gcc/gimple-fold.c @@ -2044,7 +2044,7 @@ gimple_fold_builtin_strcpy (gimple_stmt_iterator *gsi, not point to objects and so do not indicate an overlap; such calls could be the result of sanitization and jump threading). */ - if (!integer_zerop (dest) && !gimple_no_warning_p (stmt)) + if (!integer_zerop (dest) && !warning_suppressed_p (stmt, OPT_Wrestrict)) { tree func = gimple_call_fndecl (stmt); @@ -2071,9 +2071,9 @@ gimple_fold_builtin_strcpy (gimple_stmt_iterator *gsi, if (nonstr) { /* Avoid folding calls with unterminated arrays. */ - if (!gimple_no_warning_p (stmt)) + if (!warning_suppressed_p (stmt, OPT_Wstringop_overread)) warn_string_no_nul (loc, NULL_TREE, "strcpy", src, nonstr); - gimple_set_no_warning (stmt, true); + suppress_warning (stmt, OPT_Wstringop_overread); return false; } @@ -2481,7 +2481,7 @@ gimple_fold_builtin_strncat (gimple_stmt_iterator *gsi) unsigned HOST_WIDE_INT dstsize; - bool nowarn = gimple_no_warning_p (stmt); + bool nowarn = warning_suppressed_p (stmt, OPT_Wstringop_overflow_); if (!nowarn && compute_builtin_object_size (dst, 1, &dstsize)) { @@ -2504,7 +2504,7 @@ gimple_fold_builtin_strncat (gimple_stmt_iterator *gsi) "destination size %wu"), stmt, fndecl, len, dstsize); if (nowarn) - gimple_set_no_warning (stmt, true); + suppress_warning (stmt, OPT_Wstringop_overflow_); } } @@ -2520,7 +2520,7 @@ gimple_fold_builtin_strncat (gimple_stmt_iterator *gsi) if (warning_at (loc, OPT_Wstringop_overflow_, "%G%qD specified bound %E equals source length", stmt, fndecl, len)) - gimple_set_no_warning (stmt, true); + suppress_warning (stmt, OPT_Wstringop_overflow_); } tree fn = builtin_decl_implicit (BUILT_IN_STRCAT); @@ -3105,7 +3105,8 @@ gimple_fold_builtin_stxcpy_chk (gimple_stmt_iterator *gsi, not point to objects and so do not indicate an overlap; such calls could be the result of sanitization and jump threading). */ - if (!integer_zerop (dest) && !gimple_no_warning_p (stmt)) + if (!integer_zerop (dest) + && !warning_suppressed_p (stmt, OPT_Wrestrict)) { tree func = gimple_call_fndecl (stmt); @@ -3288,10 +3289,10 @@ gimple_fold_builtin_stpcpy (gimple_stmt_iterator *gsi) if (data.decl) { /* Avoid folding calls with unterminated arrays. */ - if (!gimple_no_warning_p (stmt)) + if (!warning_suppressed_p (stmt, OPT_Wstringop_overread)) warn_string_no_nul (loc, NULL_TREE, "stpcpy", src, data.decl, size, exact); - gimple_set_no_warning (stmt, true); + suppress_warning (stmt, OPT_Wstringop_overread); return false; } @@ -3554,8 +3555,7 @@ gimple_fold_builtin_sprintf (gimple_stmt_iterator *gsi) /* Propagate the NO_WARNING bit to avoid issuing the same warning more than once. */ - if (gimple_no_warning_p (stmt)) - gimple_set_no_warning (repl, true); + copy_warning (repl, stmt); gimple_seq_add_stmt_without_update (&stmts, repl); if (tree lhs = gimple_call_lhs (stmt)) @@ -3606,8 +3606,7 @@ gimple_fold_builtin_sprintf (gimple_stmt_iterator *gsi) /* Propagate the NO_WARNING bit to avoid issuing the same warning more than once. */ - if (gimple_no_warning_p (stmt)) - gimple_set_no_warning (repl, true); + copy_warning (repl, stmt); gimple_seq_add_stmt_without_update (&stmts, repl); if (tree lhs = gimple_call_lhs (stmt)) @@ -6065,7 +6064,7 @@ fold_stmt_1 (gimple_stmt_iterator *gsi, bool inplace, tree (*valueize) (tree)) { bool changed = false; gimple *stmt = gsi_stmt (*gsi); - bool nowarning = gimple_no_warning_p (stmt); + bool nowarning = warning_suppressed_p (stmt, OPT_Wstrict_overflow); unsigned i; fold_defer_overflow_warnings (); diff --git a/gcc/gimple-ssa-isolate-paths.c b/gcc/gimple-ssa-isolate-paths.c index eb23cd41f4b..2dafe849ad3 100644 --- a/gcc/gimple-ssa-isolate-paths.c +++ b/gcc/gimple-ssa-isolate-paths.c @@ -400,6 +400,11 @@ diag_returned_locals (bool maybe, const locmap_t &locmap) gimple *stmt = (*it).first; const args_loc_t &argsloc = (*it).second; location_t stmtloc = gimple_location (stmt); + if (stmtloc == UNKNOWN_LOCATION) + /* When multiple return statements are merged into one it + may not have an associated location. Use the location + of the closing brace instead. */ + stmtloc = cfun->function_end_locus; auto_diagnostic_group d; unsigned nargs = argsloc.locvec.length (); diff --git a/gcc/gimple-ssa-nonnull-compare.c b/gcc/gimple-ssa-nonnull-compare.c index 9d7894633dc..f2757b66b28 100644 --- a/gcc/gimple-ssa-nonnull-compare.c +++ b/gcc/gimple-ssa-nonnull-compare.c @@ -97,7 +97,7 @@ do_warn_nonnull_compare (function *fun, tree arg) if (op && (POINTER_TYPE_P (TREE_TYPE (arg)) ? integer_zerop (op) : integer_minus_onep (op)) - && !gimple_no_warning_p (stmt)) + && !warning_suppressed_p (stmt, OPT_Wnonnull_compare)) warning_at (loc, OPT_Wnonnull_compare, "% argument %qD compared to NULL", arg); } diff --git a/gcc/gimple-ssa-sprintf.c b/gcc/gimple-ssa-sprintf.c index fc744669e4b..41e3be6f9f4 100644 --- a/gcc/gimple-ssa-sprintf.c +++ b/gcc/gimple-ssa-sprintf.c @@ -330,7 +330,8 @@ get_format_string (tree format, location_t *ploc) static bool ATTRIBUTE_GCC_DIAG (5, 6) fmtwarn (const substring_loc &fmt_loc, location_t param_loc, - const char *corrected_substring, int opt, const char *gmsgid, ...) + const char *corrected_substring, opt_code opt, + const char *gmsgid, ...) { format_string_diagnostic_t diag (fmt_loc, NULL, param_loc, NULL, corrected_substring); @@ -345,7 +346,8 @@ fmtwarn (const substring_loc &fmt_loc, location_t param_loc, static bool ATTRIBUTE_GCC_DIAG (6, 8) ATTRIBUTE_GCC_DIAG (7, 8) fmtwarn_n (const substring_loc &fmt_loc, location_t param_loc, - const char *corrected_substring, int opt, unsigned HOST_WIDE_INT n, + const char *corrected_substring, opt_code opt, + unsigned HOST_WIDE_INT n, const char *singular_gmsgid, const char *plural_gmsgid, ...) { format_string_diagnostic_t diag (fmt_loc, NULL, param_loc, NULL, @@ -921,7 +923,7 @@ struct call_info } /* Return the warning option corresponding to the called function. */ - int warnopt () const + opt_code warnopt () const { return bounded ? OPT_Wformat_truncation_ : OPT_Wformat_overflow_; } @@ -4680,7 +4682,7 @@ handle_printf_call (gimple_stmt_iterator *gsi, pointer_query &ptr_qry) bool success = compute_format_length (info, &res, ptr_qry.rvals); if (res.warned) - gimple_set_no_warning (info.callstmt, true); + suppress_warning (info.callstmt, info.warnopt ()); /* When optimizing and the printf return value optimization is enabled, attempt to substitute the computed result for the return value of diff --git a/gcc/gimple-ssa-store-merging.c b/gcc/gimple-ssa-store-merging.c index 632947950e4..20959acc1c6 100644 --- a/gcc/gimple-ssa-store-merging.c +++ b/gcc/gimple-ssa-store-merging.c @@ -4339,10 +4339,12 @@ imm_store_chain_info::output_merged_store (merged_store_group *group) MR_DEPENDENCE_BASE (ops[j]) = base; } if (!integer_zerop (mask)) - /* The load might load some bits (that will be masked off - later on) uninitialized, avoid -W*uninitialized - warnings in that case. */ - TREE_NO_WARNING (ops[j]) = 1; + { + /* The load might load some bits (that will be masked + off later on) uninitialized, avoid -W*uninitialized + warnings in that case. */ + suppress_warning (ops[j], OPT_Wuninitialized); + } stmt = gimple_build_assign (make_ssa_name (dest_type), ops[j]); gimple_set_location (stmt, load_loc); @@ -4524,7 +4526,7 @@ imm_store_chain_info::output_merged_store (merged_store_group *group) provably uninitialized (no stores at all yet or previous store a CLOBBER) we'd optimize away the load and replace it e.g. with 0. */ - TREE_NO_WARNING (load_src) = 1; + suppress_warning (load_src, OPT_Wuninitialized); stmt = gimple_build_assign (tem, load_src); gimple_set_location (stmt, loc); gimple_set_vuse (stmt, new_vuse); diff --git a/gcc/gimple-ssa-warn-restrict.c b/gcc/gimple-ssa-warn-restrict.c index c8c9f9581a8..02771e4cd60 100644 --- a/gcc/gimple-ssa-warn-restrict.c +++ b/gcc/gimple-ssa-warn-restrict.c @@ -1431,7 +1431,7 @@ maybe_diag_overlap (location_t loc, gimple *call, builtin_access &acs) if (!acs.overlap ()) return false; - if (gimple_no_warning_p (call)) + if (warning_suppressed_p (call, OPT_Wrestrict)) return true; /* For convenience. */ @@ -1680,10 +1680,11 @@ maybe_diag_overlap (location_t loc, gimple *call, builtin_access &acs) be issued, false otherwise. Both initial values of the offsets and their final value computed by the function by incrementing the initial value by the size are - validated. Return true if the offsets are not valid and a diagnostic - has been issued, or would have been issued if DO_WARN had been true. */ + validated. Return the warning number if the offsets are not valid + and a diagnostic has been issued, or would have been issued if + DO_WARN had been true, otherwise an invalid warning number. */ -static bool +static opt_code maybe_diag_access_bounds (gimple *call, tree func, int strict, const builtin_memref &ref, offset_int wroff, bool do_warn) @@ -1695,28 +1696,31 @@ maybe_diag_access_bounds (gimple *call, tree func, int strict, since the result is used to make codegen decisions. */ if (ref.sizrange[0] > maxobjsize) { + const opt_code opt = OPT_Wstringop_overflow_; /* Return true without issuing a warning. */ if (!do_warn) - return true; + return opt; - if (ref.ref && TREE_NO_WARNING (ref.ref)) - return false; + if (ref.ref && warning_suppressed_p (ref.ref, OPT_Wstringop_overflow_)) + return no_warning; + bool warned = false; if (warn_stringop_overflow) { if (ref.sizrange[0] == ref.sizrange[1]) - return warning_at (loc, OPT_Wstringop_overflow_, - "%G%qD specified bound %wu " - "exceeds maximum object size %wu", - call, func, ref.sizrange[0].to_uhwi (), - maxobjsize.to_uhwi ()); - - return warning_at (loc, OPT_Wstringop_overflow_, - "%G%qD specified bound between %wu and %wu " - "exceeds maximum object size %wu", - call, func, ref.sizrange[0].to_uhwi (), - ref.sizrange[1].to_uhwi (), - maxobjsize.to_uhwi ()); + warned = warning_at (loc, opt, + "%G%qD specified bound %wu " + "exceeds maximum object size %wu", + call, func, ref.sizrange[0].to_uhwi (), + maxobjsize.to_uhwi ()); + else + warned = warning_at (loc, opt, + "%G%qD specified bound between %wu and %wu " + "exceeds maximum object size %wu", + call, func, ref.sizrange[0].to_uhwi (), + ref.sizrange[1].to_uhwi (), + maxobjsize.to_uhwi ()); + return warned ? opt : no_warning; } } @@ -1729,18 +1733,19 @@ maybe_diag_access_bounds (gimple *call, tree func, int strict, offset_int ooboff[] = { ref.offrange[0], ref.offrange[1], wroff }; tree oobref = ref.offset_out_of_bounds (strict, ooboff); if (!oobref) - return false; + return no_warning; + const opt_code opt = OPT_Warray_bounds; /* Return true without issuing a warning. */ if (!do_warn) - return true; + return opt; if (!warn_array_bounds) - return false; + return no_warning; - if (TREE_NO_WARNING (ref.ptr) - || (ref.ref && TREE_NO_WARNING (ref.ref))) - return false; + if (warning_suppressed_p (ref.ptr, opt) + || (ref.ref && warning_suppressed_p (ref.ref, opt))) + return no_warning; char rangestr[2][64]; if (ooboff[0] == ooboff[1] @@ -1770,7 +1775,7 @@ maybe_diag_access_bounds (gimple *call, tree func, int strict, && TREE_CODE (type = TREE_TYPE (ref.base)) == ARRAY_TYPE) { auto_diagnostic_group d; - if (warning_at (loc, OPT_Warray_bounds, + if (warning_at (loc, opt, "%G%qD pointer overflow between offset %s " "and size %s accessing array %qD with type %qT", call, func, rangestr[0], rangestr[1], ref.base, type)) @@ -1780,13 +1785,13 @@ maybe_diag_access_bounds (gimple *call, tree func, int strict, warned = true; } else - warned = warning_at (loc, OPT_Warray_bounds, + warned = warning_at (loc, opt, "%G%qD pointer overflow between offset %s " "and size %s", call, func, rangestr[0], rangestr[1]); } else - warned = warning_at (loc, OPT_Warray_bounds, + warned = warning_at (loc, opt, "%G%qD pointer overflow between offset %s " "and size %s", call, func, rangestr[0], rangestr[1]); @@ -1802,7 +1807,7 @@ maybe_diag_access_bounds (gimple *call, tree func, int strict, { auto_diagnostic_group d; if ((ref.basesize < maxobjsize - && warning_at (loc, OPT_Warray_bounds, + && warning_at (loc, opt, form ? G_("%G%qD forming offset %s is out of " "the bounds [0, %wu] of object %qD with " @@ -1811,7 +1816,7 @@ maybe_diag_access_bounds (gimple *call, tree func, int strict, "[0, %wu] of object %qD with type %qT"), call, func, rangestr[0], ref.basesize.to_uhwi (), ref.base, TREE_TYPE (ref.base))) - || warning_at (loc, OPT_Warray_bounds, + || warning_at (loc, opt, form ? G_("%G%qD forming offset %s is out of " "the bounds of object %qD with type %qT") @@ -1826,7 +1831,7 @@ maybe_diag_access_bounds (gimple *call, tree func, int strict, } } else if (ref.basesize < maxobjsize) - warned = warning_at (loc, OPT_Warray_bounds, + warned = warning_at (loc, opt, form ? G_("%G%qD forming offset %s is out " "of the bounds [0, %wu]") @@ -1834,7 +1839,7 @@ maybe_diag_access_bounds (gimple *call, tree func, int strict, "of the bounds [0, %wu]"), call, func, rangestr[0], ref.basesize.to_uhwi ()); else - warned = warning_at (loc, OPT_Warray_bounds, + warned = warning_at (loc, opt, form ? G_("%G%qD forming offset %s is out of bounds") : G_("%G%qD offset %s is out of bounds"), @@ -1848,7 +1853,7 @@ maybe_diag_access_bounds (gimple *call, tree func, int strict, type = TREE_TYPE (type); type = TYPE_MAIN_VARIANT (type); - if (warning_at (loc, OPT_Warray_bounds, + if (warning_at (loc, opt, "%G%qD offset %s from the object at %qE is out " "of the bounds of %qT", call, func, rangestr[0], ref.base, type)) @@ -1866,7 +1871,7 @@ maybe_diag_access_bounds (gimple *call, tree func, int strict, tree refop = TREE_OPERAND (ref.ref, 0); tree type = TYPE_MAIN_VARIANT (TREE_TYPE (ref.ref)); - if (warning_at (loc, OPT_Warray_bounds, + if (warning_at (loc, opt, "%G%qD offset %s from the object at %qE is out " "of the bounds of referenced subobject %qD with " "type %qT at offset %wi", @@ -1883,7 +1888,7 @@ maybe_diag_access_bounds (gimple *call, tree func, int strict, } } - return warned; + return warned ? opt : no_warning; } /* Check a CALL statement for restrict-violations and issue warnings @@ -1894,7 +1899,7 @@ check_call (range_query *query, gimple *call) { /* Avoid checking the call if it has already been diagnosed for some reason. */ - if (gimple_no_warning_p (call)) + if (warning_suppressed_p (call, OPT_Wrestrict)) return; tree func = gimple_call_fndecl (call); @@ -1980,11 +1985,10 @@ check_call (range_query *query, gimple *call) || (dstwr && !INTEGRAL_TYPE_P (TREE_TYPE (dstwr)))) return; - if (!check_bounds_or_overlap (query, call, dst, src, dstwr, NULL_TREE)) - return; - + opt_code opt = check_bounds_or_overlap (query, call, dst, src, dstwr, + NULL_TREE); /* Avoid diagnosing the call again. */ - gimple_set_no_warning (call, true); + suppress_warning (call, opt); } } /* anonymous namespace */ @@ -1996,7 +2000,7 @@ check_call (range_query *query, gimple *call) without issue a warning. Return the OPT_Wxxx constant corresponding to the warning if one has been detected and zero otherwise. */ -int +opt_code check_bounds_or_overlap (gimple *call, tree dst, tree src, tree dstsize, tree srcsize, bool bounds_only /* = false */, bool do_warn /* = true */) @@ -2006,7 +2010,7 @@ check_bounds_or_overlap (gimple *call, tree dst, tree src, tree dstsize, bounds_only, do_warn); } -int +opt_code check_bounds_or_overlap (range_query *query, gimple *call, tree dst, tree src, tree dstsize, tree srcsize, bool bounds_only /* = false */, @@ -2032,16 +2036,20 @@ check_bounds_or_overlap (range_query *query, /* Validate offsets to each reference before the access first to make sure they are within the bounds of the destination object if its size is known, or PTRDIFF_MAX otherwise. */ - if (maybe_diag_access_bounds (call, func, strict, dstref, wroff, do_warn) - || maybe_diag_access_bounds (call, func, strict, srcref, 0, do_warn)) + opt_code opt + = maybe_diag_access_bounds (call, func, strict, dstref, wroff, do_warn); + if (opt == no_warning) + opt = maybe_diag_access_bounds (call, func, strict, srcref, 0, do_warn); + + if (opt != no_warning) { if (do_warn) - gimple_set_no_warning (call, true); - return OPT_Warray_bounds; + suppress_warning (call, opt); + return opt; } if (!warn_restrict || bounds_only || !src) - return 0; + return no_warning; if (!bounds_only) { @@ -2051,7 +2059,7 @@ check_bounds_or_overlap (range_query *query, case BUILT_IN_MEMMOVE_CHK: case BUILT_IN_MEMSET: case BUILT_IN_MEMSET_CHK: - return 0; + return no_warning; default: break; } @@ -2064,26 +2072,26 @@ check_bounds_or_overlap (range_query *query, not point to objects and so do not indicate an overlap; such calls could be the result of sanitization and jump threading). */ - if (!integer_zerop (dst) && !gimple_no_warning_p (call)) + if (!integer_zerop (dst) && !warning_suppressed_p (call, OPT_Wrestrict)) { warning_at (loc, OPT_Wrestrict, "%G%qD source argument is the same as destination", call, func); - gimple_set_no_warning (call, true); + suppress_warning (call, OPT_Wrestrict); return OPT_Wrestrict; } - return 0; + return no_warning; } /* Return false when overlap has been detected. */ if (maybe_diag_overlap (loc, call, acs)) { - gimple_set_no_warning (call, true); + suppress_warning (call, OPT_Wrestrict); return OPT_Wrestrict; } - return 0; + return no_warning; } gimple_opt_pass * diff --git a/gcc/gimple-ssa-warn-restrict.h b/gcc/gimple-ssa-warn-restrict.h index ea89ccc9608..98c0e242574 100644 --- a/gcc/gimple-ssa-warn-restrict.h +++ b/gcc/gimple-ssa-warn-restrict.h @@ -20,10 +20,10 @@ #ifndef GIMPLE_SSA_WARN_RESTRICT_H -extern int check_bounds_or_overlap (gimple *, tree, tree, tree, tree, - bool = false, bool = true); -extern int check_bounds_or_overlap (class range_query *, gimple *, - tree, tree, tree, tree, - bool = false, bool = true); +extern opt_code check_bounds_or_overlap (gimple *, tree, tree, tree, tree, + bool = false, bool = true); +extern opt_code check_bounds_or_overlap (class range_query *, gimple *, + tree, tree, tree, tree, + bool = false, bool = true); #endif /* GIMPLE_SSA_WARN_RESTRICT_H */ diff --git a/gcc/gimple.c b/gcc/gimple.c index f1044e9c630..60a90667e4b 100644 --- a/gcc/gimple.c +++ b/gcc/gimple.c @@ -399,7 +399,7 @@ gimple_build_call_from_tree (tree t, tree fnptrtype) gimple_call_set_va_arg_pack (call, CALL_EXPR_VA_ARG_PACK (t)); gimple_call_set_nothrow (call, TREE_NOTHROW (t)); gimple_call_set_by_descriptor (call, CALL_EXPR_BY_DESCRIPTOR (t)); - gimple_set_no_warning (call, TREE_NO_WARNING (t)); + copy_warning (call, t); if (fnptrtype) { diff --git a/gcc/gimple.h b/gcc/gimple.h index e7dc2a45a13..be1155e262d 100644 --- a/gcc/gimple.h +++ b/gcc/gimple.h @@ -1635,6 +1635,24 @@ extern bool gimple_inexpensive_call_p (gcall *); extern bool stmt_can_terminate_bb_p (gimple *); extern location_t gimple_or_expr_nonartificial_location (gimple *, tree); +/* Return the disposition for a warning (or all warnings by default) + for a statement. */ +extern bool warning_suppressed_p (const gimple *, opt_code = all_warnings) + ATTRIBUTE_NONNULL (1); +/* Set the disposition for a warning (or all warnings by default) + at a location to enabled by default. */ +extern void suppress_warning (gimple *, opt_code = all_warnings, + bool = true) ATTRIBUTE_NONNULL (1); + +/* Copy the warning disposition mapping from one statement to another. */ +extern void copy_warning (gimple *, const gimple *) + ATTRIBUTE_NONNULL (1) ATTRIBUTE_NONNULL (2); +/* Copy the warning disposition mapping from an expression to a statement. */ +extern void copy_warning (gimple *, const_tree) + ATTRIBUTE_NONNULL (1) ATTRIBUTE_NONNULL (2); +/* Copy the warning disposition mapping from a statement to an expression. */ +extern void copy_warning (tree, const gimple *) + ATTRIBUTE_NONNULL (1) ATTRIBUTE_NONNULL (2); /* Formal (expression) temporary table handling: multiple occurrences of the same scalar expression are evaluated into the same temporary. */ @@ -1855,16 +1873,17 @@ gimple_block (const gimple *g) return LOCATION_BLOCK (g->location); } +/* Forward declare. */ +static inline void gimple_set_location (gimple *, location_t); /* Set BLOCK to be the lexical scope block holding statement G. */ static inline void gimple_set_block (gimple *g, tree block) { - g->location = set_block (g->location, block); + gimple_set_location (g, set_block (g->location, block)); } - /* Return location information for statement G. */ static inline location_t @@ -1887,6 +1906,8 @@ gimple_location_safe (const gimple *g) static inline void gimple_set_location (gimple *g, location_t location) { + /* Copy the no-warning data to the statement location. */ + copy_warning (location, g->location); g->location = location; } diff --git a/gcc/gimplify.c b/gcc/gimplify.c index 4be2febd01c..75a4a9d59fd 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -1601,7 +1601,7 @@ gimplify_return_expr (tree stmt, gimple_seq *pre_p) { maybe_add_early_return_predict_stmt (pre_p); greturn *ret = gimple_build_return (ret_expr); - gimple_set_no_warning (ret, TREE_NO_WARNING (stmt)); + copy_warning (ret, stmt); gimplify_seq_add_stmt (pre_p, ret); return GS_ALL_DONE; } @@ -1663,7 +1663,7 @@ gimplify_return_expr (tree stmt, gimple_seq *pre_p) we can wind up warning about an uninitialized value for this. Due to how this variable is constructed and initialized, this is never true. Give up and never warn. */ - TREE_NO_WARNING (result) = 1; + suppress_warning (result, OPT_Wuninitialized); gimplify_ctxp->return_temp = result; } @@ -1677,7 +1677,7 @@ gimplify_return_expr (tree stmt, gimple_seq *pre_p) maybe_add_early_return_predict_stmt (pre_p); ret = gimple_build_return (result); - gimple_set_no_warning (ret, TREE_NO_WARNING (stmt)); + copy_warning (ret, stmt); gimplify_seq_add_stmt (pre_p, ret); return GS_ALL_DONE; @@ -4252,7 +4252,8 @@ gimplify_cond_expr (tree *expr_p, gimple_seq *pre_p, fallback_t fallback) &arm2); cond_stmt = gimple_build_cond (pred_code, arm1, arm2, label_true, label_false); - gimple_set_no_warning (cond_stmt, TREE_NO_WARNING (COND_EXPR_COND (expr))); + gimple_set_location (cond_stmt, EXPR_LOCATION (expr)); + copy_warning (cond_stmt, COND_EXPR_COND (expr)); gimplify_seq_add_stmt (&seq, cond_stmt); gimple_stmt_iterator gsi = gsi_last (seq); maybe_fold_stmt (&gsi); @@ -5682,7 +5683,7 @@ gimplify_modify_expr_complex_part (tree *expr_p, gimple_seq *pre_p, ocode = code == REALPART_EXPR ? IMAGPART_EXPR : REALPART_EXPR; other = build1 (ocode, TREE_TYPE (rhs), lhs); - TREE_NO_WARNING (other) = 1; + suppress_warning (other); other = get_formal_tmp_var (other, pre_p); realpart = code == REALPART_EXPR ? rhs : other; @@ -5967,7 +5968,7 @@ gimplify_modify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, assign = gimple_build_assign (*to_p, *from_p); gimple_set_location (assign, EXPR_LOCATION (*expr_p)); if (COMPARISON_CLASS_P (*from_p)) - gimple_set_no_warning (assign, TREE_NO_WARNING (*from_p)); + copy_warning (assign, *from_p); } if (gimplify_ctxp->into_ssa && is_gimple_reg (*to_p)) @@ -6729,7 +6730,7 @@ gimple_push_cleanup (tree var, tree cleanup, bool eh_only, gimple_seq *pre_p, /* Because of this manipulation, and the EH edges that jump threading cannot redirect, the temporary (VAR) will appear to be used uninitialized. Don't warn. */ - TREE_NO_WARNING (var) = 1; + suppress_warning (var, OPT_Wuninitialized); } } else @@ -14624,7 +14625,7 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, gimplify_and_add (EH_FILTER_FAILURE (*expr_p), &failure); ehf = gimple_build_eh_filter (EH_FILTER_TYPES (*expr_p), failure); - gimple_set_no_warning (ehf, TREE_NO_WARNING (*expr_p)); + copy_warning (ehf, *expr_p); gimplify_seq_add_stmt (pre_p, ehf); ret = GS_ALL_DONE; break; diff --git a/gcc/omp-expand.c b/gcc/omp-expand.c index 50092794b92..9fd1c65883d 100644 --- a/gcc/omp-expand.c +++ b/gcc/omp-expand.c @@ -3845,7 +3845,7 @@ expand_omp_for_generic (struct omp_region *region, for (i = first_zero_iter1; i < (fd->ordered ? fd->ordered : fd->collapse); i++) if (SSA_VAR_P (counts[i])) - TREE_NO_WARNING (counts[i]) = 1; + suppress_warning (counts[i], OPT_Wuninitialized); gsi_prev (&gsi); e = split_block (entry_bb, gsi_stmt (gsi)); entry_bb = e->dest; @@ -3862,7 +3862,7 @@ expand_omp_for_generic (struct omp_region *region, be executed in that case, so just avoid uninit warnings. */ for (i = first_zero_iter2; i < fd->ordered; i++) if (SSA_VAR_P (counts[i])) - TREE_NO_WARNING (counts[i]) = 1; + suppress_warning (counts[i], OPT_Wuninitialized); if (zero_iter1_bb) make_edge (zero_iter2_bb, entry_bb, EDGE_FALLTHRU); else @@ -7051,7 +7051,7 @@ expand_omp_taskloop_for_outer (struct omp_region *region, be executed in that case, so just avoid uninit warnings. */ for (i = first_zero_iter; i < fd->collapse; i++) if (SSA_VAR_P (counts[i])) - TREE_NO_WARNING (counts[i]) = 1; + suppress_warning (counts[i], OPT_Wuninitialized); gsi_prev (&gsi); edge e = split_block (entry_bb, gsi_stmt (gsi)); entry_bb = e->dest; diff --git a/gcc/omp-low.c b/gcc/omp-low.c index 503754bfdef..410a4a6eeeb 100644 --- a/gcc/omp-low.c +++ b/gcc/omp-low.c @@ -5695,7 +5695,7 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist, able to notice this and not store anything at all, but we're generating code too early. Suppress the warning. */ if (!by_ref) - TREE_NO_WARNING (var) = 1; + suppress_warning (var, OPT_Wuninitialized); break; case OMP_CLAUSE__CONDTEMP_: @@ -6676,7 +6676,7 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist, uid = create_tmp_var (ptr_type_node, "simduid"); /* Don't want uninit warnings on simduid, it is always uninitialized, but we use it not for the value, but for the DECL_UID only. */ - TREE_NO_WARNING (uid) = 1; + suppress_warning (uid, OPT_Wuninitialized); c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__SIMDUID_); OMP_CLAUSE__SIMDUID__DECL (c) = uid; OMP_CLAUSE_CHAIN (c) = gimple_omp_for_clauses (ctx->stmt); @@ -7104,7 +7104,7 @@ lower_lastprivate_clauses (tree clauses, tree predicate, gimple_seq *body_p, if (predicate && (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE || OMP_CLAUSE_LINEAR_NO_COPYIN (c))) - TREE_NO_WARNING (new_var) = 1; + suppress_warning (new_var, OPT_Wuninitialized); } if (!maybe_simt && simduid && DECL_HAS_VALUE_EXPR_P (new_var)) @@ -7938,7 +7938,7 @@ lower_send_clauses (tree clauses, gimple_seq *ilist, gimple_seq *olist, if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c) && !by_ref && is_task_ctx (ctx)) - TREE_NO_WARNING (var) = 1; + suppress_warning (var); do_in = true; break; @@ -12800,7 +12800,7 @@ lower_omp_target (gimple_stmt_iterator *gsi_p, omp_context *ctx) { if (is_gimple_reg (var) && OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c)) - TREE_NO_WARNING (var) = 1; + suppress_warning (var); var = build_fold_addr_expr (var); } else @@ -12824,7 +12824,7 @@ lower_omp_target (gimple_stmt_iterator *gsi_p, omp_context *ctx) we'll get a warning for the store to avar. Don't warn in that case, the mapping might be implicit. */ - TREE_NO_WARNING (var) = 1; + suppress_warning (var, OPT_Wuninitialized); gimplify_assign (avar, var, &ilist); } avar = build_fold_addr_expr (avar); @@ -12978,7 +12978,7 @@ lower_omp_target (gimple_stmt_iterator *gsi_p, omp_context *ctx) if (omp_is_reference (var)) t = build_simple_mem_ref (var); else if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c)) - TREE_NO_WARNING (var) = 1; + suppress_warning (var); if (TREE_CODE (type) != POINTER_TYPE) t = fold_convert (pointer_sized_int_node, t); t = fold_convert (TREE_TYPE (x), t); @@ -12991,7 +12991,7 @@ lower_omp_target (gimple_stmt_iterator *gsi_p, omp_context *ctx) tree avar = create_tmp_var (TREE_TYPE (var)); mark_addressable (avar); if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c)) - TREE_NO_WARNING (var) = 1; + suppress_warning (var); gimplify_assign (avar, var, &ilist); avar = build_fold_addr_expr (avar); gimplify_assign (x, avar, &ilist); diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index f126d2afd9f..c73e1cbdda6 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -9445,7 +9445,7 @@ pass_warn_function_return::execute (function *fun) /* If we see "return;" in some basic block, then we do reach the end without returning a value. */ else if (warn_return_type > 0 - && !TREE_NO_WARNING (fun->decl) + && !warning_suppressed_p (fun->decl, OPT_Wreturn_type) && !VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fun->decl)))) { FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (fun)->preds) @@ -9454,14 +9454,14 @@ pass_warn_function_return::execute (function *fun) greturn *return_stmt = dyn_cast (last); if (return_stmt && gimple_return_retval (return_stmt) == NULL - && !gimple_no_warning_p (last)) + && !warning_suppressed_p (last, OPT_Wreturn_type)) { location = gimple_location (last); if (LOCATION_LOCUS (location) == UNKNOWN_LOCATION) location = fun->function_end_locus; if (warning_at (location, OPT_Wreturn_type, "control reaches end of non-void function")) - TREE_NO_WARNING (fun->decl) = 1; + suppress_warning (fun->decl, OPT_Wreturn_type); break; } } @@ -9469,7 +9469,7 @@ pass_warn_function_return::execute (function *fun) into __builtin_unreachable () call with BUILTINS_LOCATION. Recognize those too. */ basic_block bb; - if (!TREE_NO_WARNING (fun->decl)) + if (!warning_suppressed_p (fun->decl, OPT_Wreturn_type)) FOR_EACH_BB_FN (bb, fun) if (EDGE_COUNT (bb->succs) == 0) { @@ -9493,7 +9493,7 @@ pass_warn_function_return::execute (function *fun) location = fun->function_end_locus; if (warning_at (location, OPT_Wreturn_type, "control reaches end of non-void function")) - TREE_NO_WARNING (fun->decl) = 1; + suppress_warning (fun->decl, OPT_Wreturn_type); break; } } diff --git a/gcc/tree-complex.c b/gcc/tree-complex.c index d7d991714de..a528cdc7fee 100644 --- a/gcc/tree-complex.c +++ b/gcc/tree-complex.c @@ -456,12 +456,12 @@ create_one_component_var (tree type, tree orig, const char *prefix, SET_DECL_DEBUG_EXPR (r, build1 (code, type, orig)); DECL_HAS_DEBUG_EXPR_P (r) = 1; DECL_IGNORED_P (r) = 0; - TREE_NO_WARNING (r) = TREE_NO_WARNING (orig); + copy_warning (r, orig); } else { DECL_IGNORED_P (r) = 1; - TREE_NO_WARNING (r) = 1; + suppress_warning (r); } return r; diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index c5f6ba5fe18..9e041ca4d56 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -1116,7 +1116,7 @@ remap_gimple_op_r (tree *tp, int *walk_subtrees, void *data) *tp = fold_build2 (MEM_REF, type, ptr, TREE_OPERAND (*tp, 1)); TREE_THIS_VOLATILE (*tp) = TREE_THIS_VOLATILE (old); TREE_SIDE_EFFECTS (*tp) = TREE_SIDE_EFFECTS (old); - TREE_NO_WARNING (*tp) = TREE_NO_WARNING (old); + copy_warning (*tp, old); if (MR_DEPENDENCE_CLIQUE (old) != 0) { MR_DEPENDENCE_CLIQUE (*tp) @@ -1375,7 +1375,7 @@ copy_tree_body_r (tree *tp, int *walk_subtrees, void *data) *tp = fold_build2 (MEM_REF, type, ptr, TREE_OPERAND (*tp, 1)); TREE_THIS_VOLATILE (*tp) = TREE_THIS_VOLATILE (old); TREE_SIDE_EFFECTS (*tp) = TREE_SIDE_EFFECTS (old); - TREE_NO_WARNING (*tp) = TREE_NO_WARNING (old); + copy_warning (*tp, old); if (MR_DEPENDENCE_CLIQUE (old) != 0) { MR_DEPENDENCE_CLIQUE (*tp) @@ -3769,7 +3769,7 @@ declare_return_variable (copy_body_data *id, tree return_slot, tree modify_dest, /* Do not have the rest of GCC warn about this variable as it should not be visible to the user. */ - TREE_NO_WARNING (var) = 1; + suppress_warning (var /* OPT_Wuninitialized? */); declare_inline_vars (id->block, var); @@ -5027,7 +5027,7 @@ expand_call_inline (basic_block bb, gimple *stmt, copy_body_data *id, initialized. We do not want to issue a warning about that uninitialized variable. */ if (DECL_P (modify_dest)) - TREE_NO_WARNING (modify_dest) = 1; + suppress_warning (modify_dest, OPT_Wuninitialized); if (gimple_call_return_slot_opt_p (call_stmt)) { diff --git a/gcc/tree-nested.c b/gcc/tree-nested.c index 41cbca9e3b8..9edd922a303 100644 --- a/gcc/tree-nested.c +++ b/gcc/tree-nested.c @@ -411,8 +411,8 @@ lookup_field_for_decl (struct nesting_info *info, tree decl, DECL_USER_ALIGN (field) = DECL_USER_ALIGN (decl); DECL_IGNORED_P (field) = DECL_IGNORED_P (decl); DECL_NONADDRESSABLE_P (field) = !TREE_ADDRESSABLE (decl); - TREE_NO_WARNING (field) = TREE_NO_WARNING (decl); TREE_THIS_VOLATILE (field) = TREE_THIS_VOLATILE (decl); + copy_warning (field, decl); /* Declare the transformation and adjust the original DECL. For a variable or for a parameter when not optimizing, we make it point diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c index 5e86d3fbb9d..c05d22f3e8f 100644 --- a/gcc/tree-sra.c +++ b/gcc/tree-sra.c @@ -2246,12 +2246,12 @@ create_access_replacement (struct access *access, tree reg_type = NULL_TREE) DECL_HAS_DEBUG_EXPR_P (repl) = 1; } if (access->grp_no_warning) - TREE_NO_WARNING (repl) = 1; + suppress_warning (repl /* Be more selective! */); else - TREE_NO_WARNING (repl) = TREE_NO_WARNING (access->base); + copy_warning (repl, access->base); } else - TREE_NO_WARNING (repl) = 1; + suppress_warning (repl /* Be more selective! */); if (dump_file) { @@ -3562,7 +3562,7 @@ generate_subtree_copies (struct access *access, tree agg, } else { - TREE_NO_WARNING (repl) = 1; + suppress_warning (repl /* Be more selective! */); if (access->grp_partial_lhs) repl = force_gimple_operand_gsi (gsi, repl, true, NULL_TREE, !insert_after, diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c index 3834212b867..42585412325 100644 --- a/gcc/tree-ssa-ccp.c +++ b/gcc/tree-ssa-ccp.c @@ -3527,7 +3527,7 @@ pass_post_ipa_warn::execute (function *fun) for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) { gimple *stmt = gsi_stmt (gsi); - if (!is_gimple_call (stmt) || gimple_no_warning_p (stmt)) + if (!is_gimple_call (stmt) || warning_suppressed_p (stmt, OPT_Wnonnull)) continue; tree fntype = gimple_call_fntype (stmt); diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c index beb2702f3b6..db3b18b275c 100644 --- a/gcc/tree-ssa-forwprop.c +++ b/gcc/tree-ssa-forwprop.c @@ -403,7 +403,8 @@ combine_cond_expr_cond (gimple *stmt, enum tree_code code, tree type, return NULL_TREE; } - fold_undefer_overflow_warnings (!gimple_no_warning_p (stmt), stmt, 0); + bool nowarn = warning_suppressed_p (stmt, OPT_Wstrict_overflow); + fold_undefer_overflow_warnings (!nowarn, stmt, 0); return t; } diff --git a/gcc/tree-ssa-loop-ch.c b/gcc/tree-ssa-loop-ch.c index 08caa83b4b4..dfa5dc87c34 100644 --- a/gcc/tree-ssa-loop-ch.c +++ b/gcc/tree-ssa-loop-ch.c @@ -458,7 +458,7 @@ ch_base::copy_headers (function *fun) && gimple_cond_code (stmt) != NE_EXPR && INTEGRAL_TYPE_P (TREE_TYPE (lhs)) && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (lhs))) - gimple_set_no_warning (stmt, true); + suppress_warning (stmt, OPT_Wstrict_overflow_); } else if (is_gimple_assign (stmt)) { @@ -469,7 +469,7 @@ ch_base::copy_headers (function *fun) && rhs_code != NE_EXPR && INTEGRAL_TYPE_P (TREE_TYPE (rhs1)) && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (rhs1))) - gimple_set_no_warning (stmt, true); + suppress_warning (stmt, OPT_Wstrict_overflow_); } } } diff --git a/gcc/tree-ssa-loop-im.c b/gcc/tree-ssa-loop-im.c index 7de47edbcb3..48c952a1eac 100644 --- a/gcc/tree-ssa-loop-im.c +++ b/gcc/tree-ssa-loop-im.c @@ -2143,7 +2143,7 @@ execute_sm (class loop *loop, im_mem_ref *ref, /* If not emitting a load mark the uninitialized state on the loop entry as not to be warned for. */ tree uninit = create_tmp_reg (TREE_TYPE (aux->tmp_var)); - TREE_NO_WARNING (uninit) = 1; + suppress_warning (uninit, OPT_Wuninitialized); load = gimple_build_assign (aux->tmp_var, uninit); } lim_data = init_lim_data (load); diff --git a/gcc/tree-ssa-phiopt.c b/gcc/tree-ssa-phiopt.c index 02e26f974a5..ce5f0d50f7b 100644 --- a/gcc/tree-ssa-phiopt.c +++ b/gcc/tree-ssa-phiopt.c @@ -2963,9 +2963,12 @@ cond_store_replacement (basic_block middle_bb, basic_block join_bb, new_stmt = gimple_build_assign (name, lhs); gimple_set_location (new_stmt, locus); lhs = unshare_expr (lhs); - /* Set TREE_NO_WARNING on the rhs of the load to avoid uninit - warnings. */ - TREE_NO_WARNING (gimple_assign_rhs1 (new_stmt)) = 1; + { + /* Set the no-warning bit on the rhs of the load to avoid uninit + warnings. */ + tree rhs1 = gimple_assign_rhs1 (new_stmt); + suppress_warning (rhs1, OPT_Wuninitialized); + } gsi_insert_on_edge (e1, new_stmt); /* 3) Create a PHI node at the join block, with one argument diff --git a/gcc/tree-ssa-strlen.c b/gcc/tree-ssa-strlen.c index 6add8c99032..13ea107da17 100644 --- a/gcc/tree-ssa-strlen.c +++ b/gcc/tree-ssa-strlen.c @@ -1938,7 +1938,7 @@ maybe_warn_overflow (gimple *stmt, tree len, pointer_query &ptr_qry, strinfo *si = NULL, bool plus_one = false, bool rawmem = false) { - if (!len || gimple_no_warning_p (stmt)) + if (!len || warning_suppressed_p (stmt, OPT_Wstringop_overflow_)) return; /* The DECL of the function performing the write if it is done @@ -1957,7 +1957,7 @@ maybe_warn_overflow (gimple *stmt, tree len, pointer_query &ptr_qry, else return; - if (TREE_NO_WARNING (dest)) + if (warning_suppressed_p (dest, OPT_Wstringop_overflow_)) return; const int ostype = rawmem ? 0 : 1; @@ -2101,7 +2101,7 @@ maybe_warn_overflow (gimple *stmt, tree len, pointer_query &ptr_qry, if (!warned) return; - gimple_set_no_warning (stmt, true); + suppress_warning (stmt, OPT_Wstringop_overflow_); aref.inform_access (access_write_only); } @@ -2624,16 +2624,16 @@ handle_builtin_strcpy (enum built_in_function bcode, gimple_stmt_iterator *gsi, len = fold_convert_loc (loc, type, unshare_expr (srclen)); len = fold_build2_loc (loc, PLUS_EXPR, type, len, build_int_cst (type, 1)); - /* Set the no-warning bit on the transformed statement? */ - bool set_no_warning = false; + /* Disable warning for the transformed statement? */ + opt_code no_warning_opt = no_warning; - if (const strinfo *chksi = olddsi ? olddsi : dsi) - if (si - && check_bounds_or_overlap (stmt, chksi->ptr, si->ptr, NULL_TREE, len)) - { - gimple_set_no_warning (stmt, true); - set_no_warning = true; - } + if (const strinfo *chksi = si ? olddsi ? olddsi : dsi : NULL) + { + no_warning_opt = check_bounds_or_overlap (stmt, chksi->ptr, si->ptr, + NULL_TREE, len); + if (no_warning_opt) + suppress_warning (stmt, no_warning_opt); + } if (fn == NULL_TREE) return; @@ -2667,8 +2667,8 @@ handle_builtin_strcpy (enum built_in_function bcode, gimple_stmt_iterator *gsi, else if (dump_file && (dump_flags & TDF_DETAILS) != 0) fprintf (dump_file, "not possible.\n"); - if (set_no_warning) - gimple_set_no_warning (stmt, true); + if (no_warning_opt) + suppress_warning (stmt, no_warning_opt); } /* Check the size argument to the built-in forms of stpncpy and strncpy @@ -2796,7 +2796,7 @@ maybe_diag_stxncpy_trunc (gimple_stmt_iterator gsi, tree src, tree cnt, pointer_query *ptr_qry /* = NULL */) { gimple *stmt = gsi_stmt (gsi); - if (gimple_no_warning_p (stmt)) + if (warning_suppressed_p (stmt, OPT_Wstringop_truncation)) return false; wide_int cntrange[2]; @@ -3156,9 +3156,10 @@ handle_builtin_stxncpy_strncat (bool append_p, gimple_stmt_iterator *gsi) else srclenp1 = NULL_TREE; - if (check_bounds_or_overlap (stmt, dst, src, dstlenp1, srclenp1)) + opt_code opt = check_bounds_or_overlap (stmt, dst, src, dstlenp1, srclenp1); + if (opt != no_warning) { - gimple_set_no_warning (stmt, true); + suppress_warning (stmt, opt); return; } @@ -3169,7 +3170,7 @@ handle_builtin_stxncpy_strncat (bool append_p, gimple_stmt_iterator *gsi) if (!pss || pss->first <= 0) { if (maybe_diag_stxncpy_trunc (*gsi, src, len)) - gimple_set_no_warning (stmt, true); + suppress_warning (stmt, OPT_Wstringop_truncation); return; } @@ -3206,8 +3207,8 @@ handle_builtin_stxncpy_strncat (bool append_p, gimple_stmt_iterator *gsi) /* Issue -Wstringop-overflow when appending or when writing into a destination of a known size. Otherwise, when copying into a destination of an unknown size, it's truncation. */ - int opt = (append_p || dstsize - ? OPT_Wstringop_overflow_ : OPT_Wstringop_truncation); + opt_code opt = (append_p || dstsize + ? OPT_Wstringop_overflow_ : OPT_Wstringop_truncation); warned = warning_at (callloc, opt, "%G%qD specified bound depends on the length " "of the source argument", @@ -3448,8 +3449,8 @@ handle_builtin_strcat (enum built_in_function bcode, gimple_stmt_iterator *gsi, srclen = get_string_length (si); } - /* Set the no-warning bit on the transformed statement? */ - bool set_no_warning = false; + /* Disable warning for the transformed statement? */ + opt_code no_warning_opt = no_warning; if (dsi == NULL || get_string_length (dsi) == NULL_TREE) { @@ -3466,12 +3467,10 @@ handle_builtin_strcat (enum built_in_function bcode, gimple_stmt_iterator *gsi, } tree sptr = si && si->ptr ? si->ptr : src; - - if (check_bounds_or_overlap (stmt, dst, sptr, NULL_TREE, slen)) - { - gimple_set_no_warning (stmt, true); - set_no_warning = true; - } + no_warning_opt = check_bounds_or_overlap (stmt, dst, sptr, NULL_TREE, + slen); + if (no_warning_opt) + suppress_warning (stmt, no_warning_opt); } /* strcat (p, q) can be transformed into @@ -3578,11 +3577,10 @@ handle_builtin_strcat (enum built_in_function bcode, gimple_stmt_iterator *gsi, tree dstsize = fold_build2 (PLUS_EXPR, type, dstlen, one); tree sptr = si && si->ptr ? si->ptr : src; - if (check_bounds_or_overlap (stmt, dst, sptr, dstsize, srcsize)) - { - gimple_set_no_warning (stmt, true); - set_no_warning = true; - } + no_warning_opt = check_bounds_or_overlap (stmt, dst, sptr, dstsize, + srcsize); + if (no_warning_opt) + suppress_warning (stmt, no_warning_opt); } tree len = NULL_TREE; @@ -3648,8 +3646,8 @@ handle_builtin_strcat (enum built_in_function bcode, gimple_stmt_iterator *gsi, else if (dump_file && (dump_flags & TDF_DETAILS) != 0) fprintf (dump_file, "not possible.\n"); - if (set_no_warning) - gimple_set_no_warning (stmt, true); + if (no_warning_opt) + suppress_warning (stmt, no_warning_opt); } /* Handle a call to an allocation function like alloca, malloc or calloc, diff --git a/gcc/tree-ssa-uninit.c b/gcc/tree-ssa-uninit.c index 7c002f8ed87..99442d7f975 100644 --- a/gcc/tree-ssa-uninit.c +++ b/gcc/tree-ssa-uninit.c @@ -87,17 +87,33 @@ has_undefined_value_p (tree t) && possibly_undefined_names->contains (t))); } -/* Like has_undefined_value_p, but don't return true if TREE_NO_WARNING - is set on SSA_NAME_VAR. */ +/* Return true if EXPR should suppress either uninitialized warning. */ + +static inline bool +get_no_uninit_warning (tree expr) +{ + return warning_suppressed_p (expr, OPT_Wuninitialized); +} + +/* Suppress both uninitialized warnings for EXPR. */ + +static inline void +set_no_uninit_warning (tree expr) +{ + suppress_warning (expr, OPT_Wuninitialized); +} + +/* Like has_undefined_value_p, but don't return true if the no-warning + bit is set on SSA_NAME_VAR for either uninit warning. */ static inline bool uninit_undefined_value_p (tree t) { if (!has_undefined_value_p (t)) return false; - if (SSA_NAME_VAR (t) && TREE_NO_WARNING (SSA_NAME_VAR (t))) - return false; - return true; + if (!SSA_NAME_VAR (t)) + return true; + return !get_no_uninit_warning (SSA_NAME_VAR (t)); } /* Emit warnings for uninitialized variables. This is done in two passes. @@ -165,10 +181,10 @@ warn_uninit (enum opt_code wc, tree t, tree expr, tree var, /* TREE_NO_WARNING either means we already warned, or the front end wishes to suppress the warning. */ if ((context - && (gimple_no_warning_p (context) + && (warning_suppressed_p (context, OPT_Wuninitialized) || (gimple_assign_single_p (context) - && TREE_NO_WARNING (gimple_assign_rhs1 (context))))) - || TREE_NO_WARNING (expr)) + && get_no_uninit_warning (gimple_assign_rhs1 (context))))) + || get_no_uninit_warning (expr)) return; if (context != NULL && gimple_has_location (context)) @@ -185,7 +201,7 @@ warn_uninit (enum opt_code wc, tree t, tree expr, tree var, auto_diagnostic_group d; if (warning_at (location, wc, gmsgid, expr)) { - TREE_NO_WARNING (expr) = 1; + suppress_warning (expr, wc); if (location == DECL_SOURCE_LOCATION (var)) return; @@ -260,7 +276,7 @@ maybe_warn_operand (ao_ref &ref, gimple *stmt, tree lhs, tree rhs, use_operand_p luse_p; imm_use_iterator liter; - if (TREE_NO_WARNING (rhs)) + if (get_no_uninit_warning (rhs)) return NULL_TREE; /* Do not warn if the base was marked so or this is a @@ -268,7 +284,7 @@ maybe_warn_operand (ao_ref &ref, gimple *stmt, tree lhs, tree rhs, tree base = ao_ref_base (&ref); if ((VAR_P (base) && DECL_HARD_REGISTER (base)) - || TREE_NO_WARNING (base)) + || get_no_uninit_warning (base)) return NULL_TREE; /* Do not warn if the access is fully outside of the variable. */ @@ -407,7 +423,7 @@ maybe_warn_operand (ao_ref &ref, gimple *stmt, tree lhs, tree rhs, rhs = TREE_OPERAND (rhs, 0); /* Check again since RHS may have changed above. */ - if (TREE_NO_WARNING (rhs)) + if (get_no_uninit_warning (rhs)) return NULL_TREE; /* Avoid warning about empty types such as structs with no members. @@ -435,7 +451,7 @@ maybe_warn_operand (ao_ref &ref, gimple *stmt, tree lhs, tree rhs, uses or accesses by functions as it may hide important locations. */ if (lhs) - TREE_NO_WARNING (rhs) = 1; + set_no_uninit_warning (rhs); warned = true; } } diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index b9c0e65bd98..0565c9b5073 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -406,10 +406,10 @@ compare_values_warnv (tree val1, tree val2, bool *strict_overflow_p) return -2; if (strict_overflow_p != NULL - /* Symbolic range building sets TREE_NO_WARNING to declare + /* Symbolic range building sets the no-warning bit to declare that overflow doesn't happen. */ - && (!inv1 || !TREE_NO_WARNING (val1)) - && (!inv2 || !TREE_NO_WARNING (val2))) + && (!inv1 || !warning_suppressed_p (val1, OPT_Woverflow)) + && (!inv2 || !warning_suppressed_p (val2, OPT_Woverflow))) *strict_overflow_p = true; if (!inv1) @@ -432,10 +432,10 @@ compare_values_warnv (tree val1, tree val2, bool *strict_overflow_p) return -2; if (strict_overflow_p != NULL - /* Symbolic range building sets TREE_NO_WARNING to declare + /* Symbolic range building sets the no-warning bit to declare that overflow doesn't happen. */ - && (!sym1 || !TREE_NO_WARNING (val1)) - && (!sym2 || !TREE_NO_WARNING (val2))) + && (!sym1 || !warning_suppressed_p (val1, OPT_Woverflow)) + && (!sym2 || !warning_suppressed_p (val2, OPT_Woverflow))) *strict_overflow_p = true; const signop sgn = TYPE_SIGN (TREE_TYPE (val1)); diff --git a/gcc/vr-values.c b/gcc/vr-values.c index 509c8b093c5..3ae2c68499d 100644 --- a/gcc/vr-values.c +++ b/gcc/vr-values.c @@ -699,7 +699,7 @@ vr_values::extract_range_for_var_from_comparison_expr (tree var, build_int_cst (TREE_TYPE (max), 1)); /* Signal to compare_values_warnv this expr doesn't overflow. */ if (EXPR_P (max)) - TREE_NO_WARNING (max) = 1; + suppress_warning (max, OPT_Woverflow); } vr_p->update (min, max); @@ -739,7 +739,7 @@ vr_values::extract_range_for_var_from_comparison_expr (tree var, build_int_cst (TREE_TYPE (min), 1)); /* Signal to compare_values_warnv this expr doesn't overflow. */ if (EXPR_P (min)) - TREE_NO_WARNING (min) = 1; + suppress_warning (min, OPT_Woverflow); } vr_p->update (min, max); @@ -3355,7 +3355,7 @@ test_for_singularity (enum tree_code cond_code, tree op0, max = fold_build2 (MINUS_EXPR, TREE_TYPE (op0), max, one); /* Signal to compare_values_warnv this expr doesn't overflow. */ if (EXPR_P (max)) - TREE_NO_WARNING (max) = 1; + suppress_warning (max, OPT_Woverflow); } } else if (cond_code == GE_EXPR || cond_code == GT_EXPR) @@ -3369,7 +3369,7 @@ test_for_singularity (enum tree_code cond_code, tree op0, min = fold_build2 (PLUS_EXPR, TREE_TYPE (op0), min, one); /* Signal to compare_values_warnv this expr doesn't overflow. */ if (EXPR_P (min)) - TREE_NO_WARNING (min) = 1; + suppress_warning (min, OPT_Woverflow); } }