/* Predicate aware uninitialized variable warning.
- Copyright (C) 2001-2019 Free Software Foundation, Inc.
+ Copyright (C) 2001-2020 Free Software Foundation, Inc.
Contributed by Xinliang David Li <davidxl@google.com>
This file is part of GCC.
#include "fold-const.h"
#include "gimple-iterator.h"
#include "tree-ssa.h"
-#include "params.h"
#include "tree-cfg.h"
#include "cfghooks.h"
bool found_cd_chain = false;
size_t cur_chain_len = 0;
- if (*num_calls > PARAM_VALUE (PARAM_UNINIT_CONTROL_DEP_ATTEMPTS))
+ if (*num_calls > param_uninit_control_dep_attempts)
return false;
++*num_calls;
is_value_included_in (tree val, tree boundary, enum tree_code cmpc)
{
bool inverted = false;
- bool is_unsigned;
bool result;
/* Only handle integer constant here. */
if (TREE_CODE (val) != INTEGER_CST || TREE_CODE (boundary) != INTEGER_CST)
return true;
- is_unsigned = TYPE_UNSIGNED (TREE_TYPE (val));
-
if (cmpc == GE_EXPR || cmpc == GT_EXPR || cmpc == NE_EXPR)
{
cmpc = invert_tree_comparison (cmpc, false);
inverted = true;
}
- if (is_unsigned)
- {
- if (cmpc == EQ_EXPR)
- result = tree_int_cst_equal (val, boundary);
- else if (cmpc == LT_EXPR)
- result = tree_int_cst_lt (val, boundary);
- else
- {
- gcc_assert (cmpc == LE_EXPR);
- result = tree_int_cst_le (val, boundary);
- }
- }
+ if (cmpc == EQ_EXPR)
+ result = tree_int_cst_equal (val, boundary);
+ else if (cmpc == LT_EXPR)
+ result = tree_int_cst_lt (val, boundary);
else
{
- if (cmpc == EQ_EXPR)
- result = tree_int_cst_equal (val, boundary);
- else if (cmpc == LT_EXPR)
- result = tree_int_cst_lt (val, boundary);
- else
- {
- gcc_assert (cmpc == LE_EXPR);
- result = (tree_int_cst_equal (val, boundary)
- || tree_int_cst_lt (val, boundary));
- }
+ gcc_assert (cmpc == LE_EXPR);
+ result = tree_int_cst_le (val, boundary);
}
if (inverted)
return result;
}
+/* Returns whether VAL satisfies (x CMPC BOUNDARY) predicate. CMPC can be
+ either one of the range comparison codes ({GE,LT,EQ,NE}_EXPR and the like),
+ or BIT_AND_EXPR. EXACT_P is only meaningful for the latter. It modifies the
+ question from whether VAL & BOUNDARY != 0 to whether VAL & BOUNDARY == VAL.
+ For other values of CMPC, EXACT_P is ignored. */
+
+static bool
+value_sat_pred_p (tree val, tree boundary, enum tree_code cmpc,
+ bool exact_p = false)
+{
+ if (cmpc != BIT_AND_EXPR)
+ return is_value_included_in (val, boundary, cmpc);
+
+ wide_int andw = wi::to_wide (val) & wi::to_wide (boundary);
+ if (exact_p)
+ return andw == wi::to_wide (val);
+ else
+ return andw.to_uhwi ();
+}
+
/* Returns true if PRED is common among all the predicate
chains (PREDS) (and therefore can be factored out).
NUM_PRED_CHAIN is the size of array PREDS. */
return false;
if (code2 == NE_EXPR)
- return !is_value_included_in (expr2.pred_rhs, expr1.pred_rhs, code1);
-
- if ((code1 == EQ_EXPR || code1 == BIT_AND_EXPR) && code2 == BIT_AND_EXPR)
- return (wi::to_wide (expr1.pred_rhs)
- == (wi::to_wide (expr1.pred_rhs) & wi::to_wide (expr2.pred_rhs)));
+ return !value_sat_pred_p (expr2.pred_rhs, expr1.pred_rhs, code1);
- if (code1 != code2)
- return false;
+ if (code1 == EQ_EXPR)
+ return value_sat_pred_p (expr1.pred_rhs, expr2.pred_rhs, code2);
- if (is_value_included_in (expr1.pred_rhs, expr2.pred_rhs, code2))
- return true;
+ if (code1 == code2)
+ return value_sat_pred_p (expr1.pred_rhs, expr2.pred_rhs, code2,
+ code1 == BIT_AND_EXPR);
return false;
}