aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2015-12-02 14:04:48 -0500
committerJason Merrill <jason@gcc.gnu.org>2015-12-02 14:04:48 -0500
commitf479b43da091fd3ede525b7832cd69a22fb49f9a (patch)
treea2673f4d1a0faba8a3681800dd902ffc2694cc6f /gcc
parent7426fcc84f6e0a410139f60778d8d1c1d32d0283 (diff)
downloadgcc-f479b43da091fd3ede525b7832cd69a22fb49f9a.zip
gcc-f479b43da091fd3ede525b7832cd69a22fb49f9a.tar.gz
gcc-f479b43da091fd3ede525b7832cd69a22fb49f9a.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/c-family/ChangeLog4
-rw-r--r--gcc/c-family/c-common.c44
-rw-r--r--gcc/cp/ChangeLog3
-rw-r--r--gcc/cp/call.c11
-rw-r--r--gcc/testsuite/g++.dg/warn/Wnonnull1.C7
5 files changed, 54 insertions, 15 deletions
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index e32635f..8aef600 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -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.
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index 40f86e3..a8122b3 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.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))
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index d1fe8f4..6d344ff 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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.
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 8cdda62..117dd79 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -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. */
diff --git a/gcc/testsuite/g++.dg/warn/Wnonnull1.C b/gcc/testsuite/g++.dg/warn/Wnonnull1.C
new file mode 100644
index 0000000..0f610f4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Wnonnull1.C
@@ -0,0 +1,7 @@
+// { dg-options -Wnonnull }
+
+void g(void *) __attribute__ ((nonnull (1)));
+void f(void *p)
+{
+ g(1 == 1 ? p : 0);
+}