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.
This commit is contained in:
Martin Sebor 2021-06-24 19:22:06 -06:00
parent 65870e7561
commit e9e2bad725
33 changed files with 359 additions and 293 deletions

View File

@ -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;

View File

@ -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

View File

@ -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))
{

View File

@ -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);

View File

@ -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);

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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 ();

View File

@ -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 ();

View File

@ -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,
"%<nonnull%> argument %qD compared to NULL", arg);
}

View File

@ -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

View File

@ -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);

View File

@ -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 *

View File

@ -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 */

View File

@ -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)
{

View File

@ -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;
}

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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 <greturn *> (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;
}
}

View File

@ -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;

View File

@ -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))
{

View File

@ -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

View File

@ -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,

View File

@ -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);

View File

@ -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;
}

View File

@ -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_);
}
}
}

View File

@ -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);

View File

@ -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

View File

@ -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,

View File

@ -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;
}
}

View File

@ -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));

View File

@ -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);
}
}