}
}
- /* We are manipulating pointer values, so we don't need to warn
- about relying on undefined signed overflow. We disable the
- warning here because we use integer types so fold won't know that
- they are really pointers. */
- fold_defer_overflow_warnings ();
-
/* If what we are about to multiply by the size of the elements
contains a constant term, apply distributive law
and multiply that constant term separately.
ret = fold_build_pointer_plus_loc (loc, ptrop, intop);
- fold_undefer_and_ignore_overflow_warnings ();
-
return ret;
}
ret = fold_build_pointer_plus_loc (loc, ptrop, intop);
- fold_undefer_and_ignore_overflow_warnings ();
-
return ret;
}
\f
if (disable)
{
++c_inhibit_evaluation_warnings;
- fold_defer_overflow_warnings ();
}
}
if (enable)
{
--c_inhibit_evaluation_warnings;
- fold_undefer_and_ignore_overflow_warnings ();
}
}
#define abi_version_at_least(N) \
(flag_abi_version == 0 || flag_abi_version >= (N))
-/* Whether to emit an overflow warning whose code is C. */
-#define issue_strict_overflow_warning(c) (warn_strict_overflow >= (int) (c))
-
#endif /* ! in target library */
#endif /* ! GCC_FLAGS_H */
}
return x;
}
-\f
-/* This is nonzero if we should defer warnings about undefined
- overflow. This facility exists because these warnings are a
- special case. The code to estimate loop iterations does not want
- to issue any warnings, since it works with expressions which do not
- occur in user code. Various bits of cleanup code call fold(), but
- only use the result if it has certain characteristics (e.g., is a
- constant); that code only wants to issue a warning if the result is
- used. */
-
-static int fold_deferring_overflow_warnings;
-
-/* If a warning about undefined overflow is deferred, this is the
- warning. Note that this may cause us to turn two warnings into
- one, but that is fine since it is sufficient to only give one
- warning per expression. */
-
-static const char* fold_deferred_overflow_warning;
-
-/* If a warning about undefined overflow is deferred, this is the
- level at which the warning should be emitted. */
-
-static enum warn_strict_overflow_code fold_deferred_overflow_code;
-
-/* Start deferring overflow warnings. We could use a stack here to
- permit nested calls, but at present it is not necessary. */
-
-void
-fold_defer_overflow_warnings (void)
-{
- ++fold_deferring_overflow_warnings;
-}
-
-/* Stop deferring overflow warnings. If there is a pending warning,
- and ISSUE is true, then issue the warning if appropriate. STMT is
- the statement with which the warning should be associated (used for
- location information); STMT may be NULL. CODE is the level of the
- warning--a warn_strict_overflow_code value. This function will use
- the smaller of CODE and the deferred code when deciding whether to
- issue the warning. CODE may be zero to mean to always use the
- deferred code. */
-
-void
-fold_undefer_overflow_warnings (bool issue, const gimple *stmt, int code)
-{
- const char *warnmsg;
- location_t locus;
-
- gcc_assert (fold_deferring_overflow_warnings > 0);
- --fold_deferring_overflow_warnings;
- if (fold_deferring_overflow_warnings > 0)
- {
- if (fold_deferred_overflow_warning != NULL
- && code != 0
- && code < (int) fold_deferred_overflow_code)
- fold_deferred_overflow_code = (enum warn_strict_overflow_code) code;
- return;
- }
-
- warnmsg = fold_deferred_overflow_warning;
- fold_deferred_overflow_warning = NULL;
-
- if (!issue || warnmsg == NULL)
- return;
-
- if (warning_suppressed_p (stmt, OPT_Wstrict_overflow))
- return;
-
- /* Use the smallest code level when deciding to issue the
- warning. */
- if (code == 0 || code > (int) fold_deferred_overflow_code)
- code = fold_deferred_overflow_code;
-
- if (!issue_strict_overflow_warning (code))
- return;
-
- if (stmt == NULL)
- locus = input_location;
- else
- locus = gimple_location (stmt);
- warning_at (locus, OPT_Wstrict_overflow, "%s", warnmsg);
-}
-
-/* Stop deferring overflow warnings, ignoring any deferred
- warnings. */
-
-void
-fold_undefer_and_ignore_overflow_warnings (void)
-{
- fold_undefer_overflow_warnings (false, NULL, 0);
-}
-
-/* Whether we are deferring overflow warnings. */
-
-bool
-fold_deferring_overflow_warnings_p (void)
-{
- return fold_deferring_overflow_warnings > 0;
-}
/* Return true if the built-in mathematical function specified by CODE
is odd, i.e. -f(x) == f(-x). */
extern tree fold_ignored_result (tree);
extern tree fold_abs_const (tree, tree);
extern tree fold_indirect_ref_1 (location_t, tree, tree);
-extern void fold_defer_overflow_warnings (void);
-extern void fold_undefer_overflow_warnings (bool, const gimple *, int);
-extern void fold_undefer_and_ignore_overflow_warnings (void);
-extern bool fold_deferring_overflow_warnings_p (void);
extern enum tree_code fold_div_compare (enum tree_code, tree, tree,
tree *, tree *, bool *);
extern bool operand_equal_p (const_tree, const_tree, unsigned int flags = 0);
{
bool changed = false;
gimple *stmt = gsi_stmt (*gsi);
- bool nowarning = warning_suppressed_p (stmt, OPT_Wstrict_overflow);
unsigned i;
- fold_defer_overflow_warnings ();
/* First do required canonicalization of [TARGET_]MEM_REF addresses
after propagation.
default:;
}
- stmt = gsi_stmt (*gsi);
-
- fold_undefer_overflow_warnings (changed && !nowarning, stmt, 0);
return changed;
}
df_finish_pass ((flags & TODO_df_verify) != 0);
}
-/* Verify invariants that should hold between passes. This is a place
- to put simple sanity checks. */
-
-static void
-verify_interpass_invariants (void)
-{
- gcc_checking_assert (!fold_deferring_overflow_warnings_p ());
-}
-
/* Helper function. Verify that the properties has been turn into the
properties expected by the pass. */
/* Run post-pass cleanup. */
gcc_checking_assert (!(todo_after & TODO_verify_il));
execute_todo (todo_after);
- verify_interpass_invariants ();
/* Stop timevar. */
if (pass->tv_id != TV_NONE)
}
}
- verify_interpass_invariants ();
-
/* Stop timevar. */
if (pass->tv_id != TV_NONE)
timevar_pop (pass->tv_id);
{
edge e;
edge_iterator ei;
- bool warned;
tree val = NULL_TREE;
/* Try to convert a switch with just a single non-default case to
if (gimple_code (stmt) == GIMPLE_COND)
canonicalize_bool_cond (as_a<gcond*> (stmt), bb);
- fold_defer_overflow_warnings ();
switch (gimple_code (stmt))
{
case GIMPLE_COND:
}
taken_edge = find_taken_edge (bb, val);
if (!taken_edge)
- {
- fold_undefer_and_ignore_overflow_warnings ();
- return false;
- }
+ return false;
/* Remove all the edges except the one that is always executed. */
- warned = false;
for (ei = ei_start (bb->succs); (e = ei_safe_edge (ei)); )
{
if (e != taken_edge)
{
- if (!warned)
- {
- fold_undefer_overflow_warnings
- (true, stmt, WARN_STRICT_OVERFLOW_CONDITIONAL);
- warned = true;
- }
-
taken_edge->probability += e->probability;
remove_edge_and_dominated_blocks (e);
retval = true;
else
ei_next (&ei);
}
- if (!warned)
- fold_undefer_and_ignore_overflow_warnings ();
}
else
taken_edge = single_succ_edge (bb);
{
tree part_cond_expr;
- fold_defer_overflow_warnings ();
for (const dr_with_seg_len_pair_t &alias_pair : alias_pairs)
{
gcc_assert (alias_pair.flags);
else
*cond_expr = part_cond_expr;
}
- fold_undefer_and_ignore_overflow_warnings ();
}
/* Check if OFFSET1 and OFFSET2 (DR_OFFSETs of some data-refs) are identical
not attempt to fold them, including builtins that may profit. */
if (likelyvalue == CONSTANT)
{
- fold_defer_overflow_warnings ();
simplified = ccp_fold (stmt);
if (simplified
&& TREE_CODE (simplified) == SSA_NAME)
{
ccp_prop_value_t *val = get_value (simplified);
if (val && val->lattice_val != VARYING)
- {
- fold_undefer_overflow_warnings (true, stmt, 0);
- return *val;
- }
+ return *val;
}
else
/* We may also not place a non-valueized copy in the lattice
simplified = NULL_TREE;
}
is_constant = simplified && is_gimple_min_invariant (simplified);
- fold_undefer_overflow_warnings (is_constant, stmt, 0);
if (is_constant)
{
/* The statement produced a constant value. */
gcc_assert (TREE_CODE_CLASS (code) == tcc_comparison);
- fold_defer_overflow_warnings ();
t = fold_binary_loc (gimple_location (stmt), code, type, op0, op1);
if (!t)
- {
- fold_undefer_overflow_warnings (false, NULL, 0);
- return NULL_TREE;
- }
+ return NULL_TREE;
/* Require that we got a boolean type out if we put one in. */
gcc_assert (TREE_CODE (TREE_TYPE (t)) == TREE_CODE (type));
/* Bail out if we required an invariant but didn't get one. */
if (!t || (invariant_only && !is_gimple_min_invariant (t)))
- {
- fold_undefer_overflow_warnings (false, NULL, 0);
- return NULL_TREE;
- }
-
- bool nowarn = warning_suppressed_p (stmt, OPT_Wstrict_overflow);
- fold_undefer_overflow_warnings (!nowarn, stmt, 0);
+ return NULL_TREE;
return t;
}
if (!ret)
return expr;
- fold_defer_overflow_warnings ();
ret = fold (ret);
- fold_undefer_and_ignore_overflow_warnings ();
return ret;
}
if (iv0_niters && iv1_niters)
return false;
- /* We don't want to see undefined signed overflow warnings while
- computing the number of iterations. */
- fold_defer_overflow_warnings ();
-
iv0.base = expand_simple_operations (iv0.base);
iv1.base = expand_simple_operations (iv1.base);
bool body_from_caller = true;
if (!number_of_iterations_cond (loop, type, &iv0, code, &iv1, niter,
only_exit_p, safe))
{
- fold_undefer_and_ignore_overflow_warnings ();
return false;
}
= simplify_using_initial_conditions (loop,
niter->may_be_zero);
- fold_undefer_and_ignore_overflow_warnings ();
-
/* If NITER has simplified into a constant, update MAX. */
if (TREE_CODE (niter->niter) == INTEGER_CST)
niter->max = wi::to_widest (niter->niter);
}
}
- /* Don't issue signed overflow warnings. */
- fold_defer_overflow_warnings ();
-
for (i = 0; i < MAX_ITERATIONS_TO_TRACK; i++)
{
for (j = 0; j < 2; j++)
acnd = fold_binary (cmp, boolean_type_node, aval[0], aval[1]);
if (acnd && integer_zerop (acnd))
{
- fold_undefer_and_ignore_overflow_warnings ();
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file,
"Proved that loop %d iterates %d times using brute force.\n",
aval[j] = val[j];
val[j] = get_val_for (next[j], val[j]);
if (!is_gimple_min_invariant (val[j]))
- {
- fold_undefer_and_ignore_overflow_warnings ();
- return chrec_dont_know;
- }
+ return chrec_dont_know;
}
/* If the next iteration would use the same base values
break;
}
- fold_undefer_and_ignore_overflow_warnings ();
-
return chrec_dont_know;
}
void
estimate_numbers_of_iterations (function *fn)
{
- /* We don't want to issue signed overflow warnings while getting
- loop iteration estimates. */
- fold_defer_overflow_warnings ();
-
for (auto loop : loops_list (fn, 0))
estimate_numbers_of_iterations (loop);
-
- fold_undefer_and_ignore_overflow_warnings ();
}
/* Returns true if statement S1 dominates statement S2. */
tree type = TREE_TYPE (step);
tree unsigned_type, valid_niter;
- /* Don't issue signed overflow warnings. */
- fold_defer_overflow_warnings ();
-
/* Compute the number of iterations before we reach the bound of the
type, and verify that the loop is exited before this occurs. */
unsigned_type = unsigned_type_for (type);
wide_int_to_tree (TREE_TYPE (valid_niter),
niter))) != NULL
&& integer_nonzerop (e))
- {
- fold_undefer_and_ignore_overflow_warnings ();
- return true;
- }
+ return true;
if (at_stmt)
for (bound = loop->bounds; bound; bound = bound->next)
{
if (n_of_executions_at_most (at_stmt, bound, valid_niter))
- {
- fold_undefer_and_ignore_overflow_warnings ();
- return true;
- }
+ return true;
}
- fold_undefer_and_ignore_overflow_warnings ();
/* Try to prove loop is exited before {base, step} overflows with the
help of analyzed loop control IV. This is done only for IVs with
gimple_cond_set_lhs (dummy_cond, op0);
gimple_cond_set_rhs (dummy_cond, op1);
- /* We absolutely do not care about any type conversions
- we only care about a zero/nonzero value. */
- fold_defer_overflow_warnings ();
-
tree res = fold_binary (cond_code, boolean_type_node, op0, op1);
if (res)
while (CONVERT_EXPR_P (res))
res = TREE_OPERAND (res, 0);
- fold_undefer_overflow_warnings ((res && is_gimple_min_invariant (res)),
- stmt, WARN_STRICT_OVERFLOW_CONDITIONAL);
-
/* If we have not simplified the condition down to an invariant,
then use the pass specific callback to simplify the condition. */
if (!res
if (operand_equal_p (val1, val2, 0))
return 0;
- fold_defer_overflow_warnings ();
-
/* If VAL1 is a lower address than VAL2, return -1. */
tree t = fold_binary_to_constant (LT_EXPR, boolean_type_node, val1, val2);
if (t && integer_onep (t))
- {
- fold_undefer_and_ignore_overflow_warnings ();
- return -1;
- }
+ return -1;
/* If VAL1 is a higher address than VAL2, return +1. */
t = fold_binary_to_constant (LT_EXPR, boolean_type_node, val2, val1);
if (t && integer_onep (t))
- {
- fold_undefer_and_ignore_overflow_warnings ();
- return 1;
- }
+ return 1;
/* If VAL1 is different than VAL2, return +2. */
t = fold_binary_to_constant (NE_EXPR, boolean_type_node, val1, val2);
- fold_undefer_and_ignore_overflow_warnings ();
if (t && integer_onep (t))
return 2;