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>
|
||||
|
||||
* 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_fully_fold_internal, decl_constant_value_for_optimization):
|
||||
Move to c/c-fold.c.
|
||||
|
@ -1094,6 +1094,19 @@ fix_string_type (tree 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.
|
||||
Invoke this function on every expression that the language
|
||||
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
|
||||
where op should not be any boolean expression, nor a
|
||||
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)
|
||||
&& INTEGRAL_TYPE_P (TREE_TYPE (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
|
||||
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;
|
||||
|
||||
/* 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
|
||||
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;
|
||||
|
||||
/* Don't warn for e.g.
|
||||
@ -9701,11 +9719,14 @@ check_function_arguments_recurse (void (*callback)
|
||||
|
||||
if (TREE_CODE (param) == COND_EXPR)
|
||||
{
|
||||
tree cond = fold_for_warn (TREE_OPERAND (param, 0));
|
||||
/* Check both halves of the conditional expression. */
|
||||
check_function_arguments_recurse (callback, ctx,
|
||||
TREE_OPERAND (param, 1), param_num);
|
||||
check_function_arguments_recurse (callback, ctx,
|
||||
TREE_OPERAND (param, 2), param_num);
|
||||
if (!integer_zerop (cond))
|
||||
check_function_arguments_recurse (callback, ctx,
|
||||
TREE_OPERAND (param, 1), param_num);
|
||||
if (!integer_nonzerop (cond))
|
||||
check_function_arguments_recurse (callback, ctx,
|
||||
TREE_OPERAND (param, 2), param_num);
|
||||
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)
|
||||
return;
|
||||
|
||||
tree cst = (TREE_CODE (op0) == INTEGER_CST)
|
||||
? op0 : (TREE_CODE (op1) == INTEGER_CST) ? op1 : NULL_TREE;
|
||||
if (!cst)
|
||||
tree f, cst;
|
||||
if (f = fold_for_warn (op0),
|
||||
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;
|
||||
|
||||
if (!integer_zerop (cst) && !integer_onep (cst))
|
||||
|
@ -1,5 +1,8 @@
|
||||
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.
|
||||
(c_fully_fold): Use cp_fold_rvalue.
|
||||
(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. */
|
||||
if (complain & tf_warning)
|
||||
warn_logical_operator (loc, code, boolean_type_node,
|
||||
code_orig_arg1, fold (arg1),
|
||||
code_orig_arg2, fold (arg2));
|
||||
code_orig_arg1, arg1,
|
||||
code_orig_arg2, arg2);
|
||||
|
||||
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:
|
||||
if (complain & tf_warning)
|
||||
warn_logical_operator (loc, code, boolean_type_node,
|
||||
code_orig_arg1, fold (arg1),
|
||||
code_orig_arg2, fold (arg2));
|
||||
code_orig_arg1, arg1,
|
||||
code_orig_arg2, arg2);
|
||||
/* Fall through. */
|
||||
case GT_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)
|
||||
&& ((code_orig_arg1 == BOOLEAN_TYPE)
|
||||
^ (code_orig_arg2 == BOOLEAN_TYPE)))
|
||||
maybe_warn_bool_compare (loc, code, fold (arg1),
|
||||
fold (arg2));
|
||||
maybe_warn_bool_compare (loc, code, arg1, arg2);
|
||||
if (complain & tf_warning && warn_tautological_compare)
|
||||
warn_tautological_cmp (loc, code, arg1, arg2);
|
||||
/* Fall through. */
|
||||
|
7
gcc/testsuite/g++.dg/warn/Wnonnull1.C
Normal file
7
gcc/testsuite/g++.dg/warn/Wnonnull1.C
Normal file
@ -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
Block a user