Do constant folding in warn_* functions.
gcc/c-family/ * c-common.c (fold_for_warn): New. (warn_logical_operator, warn_tautological_cmp) (check_function_arguments_recurse, maybe_warn_bool_compare): Use it. gcc/cp/ * call.c (build_new_op_1): Don't fold arguments to warn_logical_operator or maybe_warn_bool_compare. From-SVN: r231198
This commit is contained in:
parent
7426fcc84f
commit
f479b43da0
|
@ -1,5 +1,9 @@
|
||||||
2015-12-02 Jason Merrill <jason@redhat.com>
|
2015-12-02 Jason Merrill <jason@redhat.com>
|
||||||
|
|
||||||
|
* c-common.c (fold_for_warn): New.
|
||||||
|
(warn_logical_operator, warn_tautological_cmp)
|
||||||
|
(check_function_arguments_recurse, maybe_warn_bool_compare): Use it.
|
||||||
|
|
||||||
* c-common.c (c_disable_warnings, c_enable_warnings, c_fully_fold)
|
* c-common.c (c_disable_warnings, c_enable_warnings, c_fully_fold)
|
||||||
(c_fully_fold_internal, decl_constant_value_for_optimization):
|
(c_fully_fold_internal, decl_constant_value_for_optimization):
|
||||||
Move to c/c-fold.c.
|
Move to c/c-fold.c.
|
||||||
|
|
|
@ -1094,6 +1094,19 @@ fix_string_type (tree value)
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Fold X for consideration by one of the warning functions when checking
|
||||||
|
whether an expression has a constant value. */
|
||||||
|
|
||||||
|
static tree
|
||||||
|
fold_for_warn (tree x)
|
||||||
|
{
|
||||||
|
if (c_dialect_cxx ())
|
||||||
|
return c_fully_fold (x, /*for_init*/false, /*maybe_constp*/NULL);
|
||||||
|
else
|
||||||
|
/* The C front-end has already folded X appropriately. */
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
/* Print a warning if a constant expression had overflow in folding.
|
/* Print a warning if a constant expression had overflow in folding.
|
||||||
Invoke this function on every expression that the language
|
Invoke this function on every expression that the language
|
||||||
requires to be a constant expression.
|
requires to be a constant expression.
|
||||||
|
@ -1207,6 +1220,9 @@ warn_logical_operator (location_t location, enum tree_code code, tree type,
|
||||||
programmer. That is, an expression such as op && MASK
|
programmer. That is, an expression such as op && MASK
|
||||||
where op should not be any boolean expression, nor a
|
where op should not be any boolean expression, nor a
|
||||||
constant, and mask seems to be a non-boolean integer constant. */
|
constant, and mask seems to be a non-boolean integer constant. */
|
||||||
|
if (TREE_CODE (op_right) == CONST_DECL)
|
||||||
|
/* An enumerator counts as a constant. */
|
||||||
|
op_right = DECL_INITIAL (op_right);
|
||||||
if (!truth_value_p (code_left)
|
if (!truth_value_p (code_left)
|
||||||
&& INTEGRAL_TYPE_P (TREE_TYPE (op_left))
|
&& INTEGRAL_TYPE_P (TREE_TYPE (op_left))
|
||||||
&& !CONSTANT_CLASS_P (op_left)
|
&& !CONSTANT_CLASS_P (op_left)
|
||||||
|
@ -1227,7 +1243,8 @@ warn_logical_operator (location_t location, enum tree_code code, tree type,
|
||||||
|
|
||||||
/* We do not warn for constants because they are typical of macro
|
/* We do not warn for constants because they are typical of macro
|
||||||
expansions that test for features. */
|
expansions that test for features. */
|
||||||
if (CONSTANT_CLASS_P (op_left) || CONSTANT_CLASS_P (op_right))
|
if (CONSTANT_CLASS_P (fold_for_warn (op_left))
|
||||||
|
|| CONSTANT_CLASS_P (fold_for_warn (op_right)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* This warning only makes sense with logical operands. */
|
/* This warning only makes sense with logical operands. */
|
||||||
|
@ -1347,7 +1364,8 @@ warn_tautological_cmp (location_t loc, enum tree_code code, tree lhs, tree rhs)
|
||||||
|
|
||||||
/* We do not warn for constants because they are typical of macro
|
/* We do not warn for constants because they are typical of macro
|
||||||
expansions that test for features, sizeof, and similar. */
|
expansions that test for features, sizeof, and similar. */
|
||||||
if (CONSTANT_CLASS_P (fold (lhs)) || CONSTANT_CLASS_P (fold (rhs)))
|
if (CONSTANT_CLASS_P (fold_for_warn (lhs))
|
||||||
|
|| CONSTANT_CLASS_P (fold_for_warn (rhs)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Don't warn for e.g.
|
/* Don't warn for e.g.
|
||||||
|
@ -9701,9 +9719,12 @@ check_function_arguments_recurse (void (*callback)
|
||||||
|
|
||||||
if (TREE_CODE (param) == COND_EXPR)
|
if (TREE_CODE (param) == COND_EXPR)
|
||||||
{
|
{
|
||||||
|
tree cond = fold_for_warn (TREE_OPERAND (param, 0));
|
||||||
/* Check both halves of the conditional expression. */
|
/* Check both halves of the conditional expression. */
|
||||||
|
if (!integer_zerop (cond))
|
||||||
check_function_arguments_recurse (callback, ctx,
|
check_function_arguments_recurse (callback, ctx,
|
||||||
TREE_OPERAND (param, 1), param_num);
|
TREE_OPERAND (param, 1), param_num);
|
||||||
|
if (!integer_nonzerop (cond))
|
||||||
check_function_arguments_recurse (callback, ctx,
|
check_function_arguments_recurse (callback, ctx,
|
||||||
TREE_OPERAND (param, 2), param_num);
|
TREE_OPERAND (param, 2), param_num);
|
||||||
return;
|
return;
|
||||||
|
@ -11984,9 +12005,14 @@ maybe_warn_bool_compare (location_t loc, enum tree_code code, tree op0,
|
||||||
if (TREE_CODE_CLASS (code) != tcc_comparison)
|
if (TREE_CODE_CLASS (code) != tcc_comparison)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
tree cst = (TREE_CODE (op0) == INTEGER_CST)
|
tree f, cst;
|
||||||
? op0 : (TREE_CODE (op1) == INTEGER_CST) ? op1 : NULL_TREE;
|
if (f = fold_for_warn (op0),
|
||||||
if (!cst)
|
TREE_CODE (f) == INTEGER_CST)
|
||||||
|
cst = op0 = f;
|
||||||
|
else if (f = fold_for_warn (op1),
|
||||||
|
TREE_CODE (f) == INTEGER_CST)
|
||||||
|
cst = op1 = f;
|
||||||
|
else
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!integer_zerop (cst) && !integer_onep (cst))
|
if (!integer_zerop (cst) && !integer_onep (cst))
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
2015-12-02 Jason Merrill <jason@redhat.com>
|
2015-12-02 Jason Merrill <jason@redhat.com>
|
||||||
|
|
||||||
|
* call.c (build_new_op_1): Don't fold arguments to
|
||||||
|
warn_logical_operator or maybe_warn_bool_compare.
|
||||||
|
|
||||||
* cp-gimplify.c (cp_fold_maybe_rvalue, cp_fold_rvalue): New.
|
* cp-gimplify.c (cp_fold_maybe_rvalue, cp_fold_rvalue): New.
|
||||||
(c_fully_fold): Use cp_fold_rvalue.
|
(c_fully_fold): Use cp_fold_rvalue.
|
||||||
(cp_fold): Use them for rvalue operands.
|
(cp_fold): Use them for rvalue operands.
|
||||||
|
|
|
@ -5687,8 +5687,8 @@ build_new_op_1 (location_t loc, enum tree_code code, int flags, tree arg1,
|
||||||
decaying an enumerator to its value. */
|
decaying an enumerator to its value. */
|
||||||
if (complain & tf_warning)
|
if (complain & tf_warning)
|
||||||
warn_logical_operator (loc, code, boolean_type_node,
|
warn_logical_operator (loc, code, boolean_type_node,
|
||||||
code_orig_arg1, fold (arg1),
|
code_orig_arg1, arg1,
|
||||||
code_orig_arg2, fold (arg2));
|
code_orig_arg2, arg2);
|
||||||
|
|
||||||
arg2 = convert_like (conv, arg2, complain);
|
arg2 = convert_like (conv, arg2, complain);
|
||||||
}
|
}
|
||||||
|
@ -5726,8 +5726,8 @@ build_new_op_1 (location_t loc, enum tree_code code, int flags, tree arg1,
|
||||||
case TRUTH_OR_EXPR:
|
case TRUTH_OR_EXPR:
|
||||||
if (complain & tf_warning)
|
if (complain & tf_warning)
|
||||||
warn_logical_operator (loc, code, boolean_type_node,
|
warn_logical_operator (loc, code, boolean_type_node,
|
||||||
code_orig_arg1, fold (arg1),
|
code_orig_arg1, arg1,
|
||||||
code_orig_arg2, fold (arg2));
|
code_orig_arg2, arg2);
|
||||||
/* Fall through. */
|
/* Fall through. */
|
||||||
case GT_EXPR:
|
case GT_EXPR:
|
||||||
case LT_EXPR:
|
case LT_EXPR:
|
||||||
|
@ -5738,8 +5738,7 @@ build_new_op_1 (location_t loc, enum tree_code code, int flags, tree arg1,
|
||||||
if ((complain & tf_warning)
|
if ((complain & tf_warning)
|
||||||
&& ((code_orig_arg1 == BOOLEAN_TYPE)
|
&& ((code_orig_arg1 == BOOLEAN_TYPE)
|
||||||
^ (code_orig_arg2 == BOOLEAN_TYPE)))
|
^ (code_orig_arg2 == BOOLEAN_TYPE)))
|
||||||
maybe_warn_bool_compare (loc, code, fold (arg1),
|
maybe_warn_bool_compare (loc, code, arg1, arg2);
|
||||||
fold (arg2));
|
|
||||||
if (complain & tf_warning && warn_tautological_compare)
|
if (complain & tf_warning && warn_tautological_compare)
|
||||||
warn_tautological_cmp (loc, code, arg1, arg2);
|
warn_tautological_cmp (loc, code, arg1, arg2);
|
||||||
/* Fall through. */
|
/* Fall through. */
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
// { dg-options -Wnonnull }
|
||||||
|
|
||||||
|
void g(void *) __attribute__ ((nonnull (1)));
|
||||||
|
void f(void *p)
|
||||||
|
{
|
||||||
|
g(1 == 1 ? p : 0);
|
||||||
|
}
|
Loading…
Reference in New Issue