return value;
}
\f
+/* 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.
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)
/* 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. */
/* 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.
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;
}
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))
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);
}
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:
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. */