aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMarek Polacek <polacek@redhat.com>2017-05-09 11:21:14 +0000
committerMarek Polacek <mpolacek@gcc.gnu.org>2017-05-09 11:21:14 +0000
commit684f84dea9cb2acf6c61bf461a9d50f6b7c03eca (patch)
tree16e450b9cd928ae252b2eb7bf2db23dc8cbacb15 /gcc
parent641da50a0c73f734e672f8e6b9e7d2c86bde840d (diff)
downloadgcc-684f84dea9cb2acf6c61bf461a9d50f6b7c03eca.zip
gcc-684f84dea9cb2acf6c61bf461a9d50f6b7c03eca.tar.gz
gcc-684f84dea9cb2acf6c61bf461a9d50f6b7c03eca.tar.bz2
re PR c/80525 (-Wlogical-op confused by undefined integer overflow)
PR c/80525 * c-warn.c (unwrap_c_maybe_const): New. (warn_logical_operator): Call it. * c-c++-common/Wlogical-op-1.c: Don't use -fwrapv anymore. * c-c++-common/Wlogical-op-2.c: New test. From-SVN: r247786
Diffstat (limited to 'gcc')
-rw-r--r--gcc/c-family/ChangeLog6
-rw-r--r--gcc/c-family/c-warn.c24
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/c-c++-common/Wlogical-op-1.c4
-rw-r--r--gcc/testsuite/c-c++-common/Wlogical-op-2.c12
5 files changed, 45 insertions, 7 deletions
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index 6409442..e76a628 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,9 @@
+2017-05-09 Marek Polacek <polacek@redhat.com>
+
+ PR c/80525
+ * c-warn.c (unwrap_c_maybe_const): New.
+ (warn_logical_operator): Call it.
+
2017-05-09 Nathan Sidwell <nathan@acm.org>
* c-common.c (c_register_builtin_type): Use pushdecl lang_hook.
diff --git a/gcc/c-family/c-warn.c b/gcc/c-family/c-warn.c
index 45dd583..aa0cfa9 100644
--- a/gcc/c-family/c-warn.c
+++ b/gcc/c-family/c-warn.c
@@ -30,6 +30,7 @@ along with GCC; see the file COPYING3. If not see
#include "intl.h"
#include "asan.h"
#include "gcc-rich-location.h"
+#include "gimplify.h"
/* Print a warning if a constant expression had overflow in folding.
Invoke this function on every expression that the language
@@ -112,6 +113,21 @@ overflow_warning (location_t loc, tree value)
}
}
+/* Helper function for walk_tree. Unwrap C_MAYBE_CONST_EXPRs in an expression
+ pointed to by TP. */
+
+static tree
+unwrap_c_maybe_const (tree *tp, int *walk_subtrees, void *)
+{
+ if (TREE_CODE (*tp) == C_MAYBE_CONST_EXPR)
+ {
+ *tp = C_MAYBE_CONST_EXPR_EXPR (*tp);
+ /* C_MAYBE_CONST_EXPRs don't nest. */
+ *walk_subtrees = false;
+ }
+ return NULL_TREE;
+}
+
/* Warn about uses of logical || / && operator in a context where it
is likely that the bitwise equivalent was intended by the
programmer. We have seen an expression in which CODE is a binary
@@ -189,11 +205,11 @@ warn_logical_operator (location_t location, enum tree_code code, tree type,
(with OR) or trivially false (with AND). If so, do not warn.
This is a common idiom for testing ranges of data types in
portable code. */
+ op_left = unshare_expr (op_left);
+ walk_tree_without_duplicates (&op_left, unwrap_c_maybe_const, NULL);
lhs = make_range (op_left, &in0_p, &low0, &high0, &strict_overflow_p);
if (!lhs)
return;
- if (TREE_CODE (lhs) == C_MAYBE_CONST_EXPR)
- lhs = C_MAYBE_CONST_EXPR_EXPR (lhs);
/* If this is an OR operation, invert both sides; now, the result
should be always false to get a warning. */
@@ -204,11 +220,11 @@ warn_logical_operator (location_t location, enum tree_code code, tree type,
if (tem && integer_zerop (tem))
return;
+ op_right = unshare_expr (op_right);
+ walk_tree_without_duplicates (&op_right, unwrap_c_maybe_const, NULL);
rhs = make_range (op_right, &in1_p, &low1, &high1, &strict_overflow_p);
if (!rhs)
return;
- if (TREE_CODE (rhs) == C_MAYBE_CONST_EXPR)
- rhs = C_MAYBE_CONST_EXPR_EXPR (rhs);
/* If this is an OR operation, invert both sides; now, the result
should be always false to get a warning. */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index af1e6de..98552a8 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2017-05-09 Marek Polacek <polacek@redhat.com>
+
+ PR c/80525
+ * c-c++-common/Wlogical-op-1.c: Don't use -fwrapv anymore.
+ * c-c++-common/Wlogical-op-2.c: New test.
+
2017-05-09 Senthil Kumar Selvaraj <senthil_kumar.selvaraj@atmel.com>
* gcc.dg/tree-ssa/cunroll-13.c: Use __INT32_TYPE__ for
diff --git a/gcc/testsuite/c-c++-common/Wlogical-op-1.c b/gcc/testsuite/c-c++-common/Wlogical-op-1.c
index e89a35a..c5f992a 100644
--- a/gcc/testsuite/c-c++-common/Wlogical-op-1.c
+++ b/gcc/testsuite/c-c++-common/Wlogical-op-1.c
@@ -1,8 +1,6 @@
/* PR c/63357 */
/* { dg-do compile } */
-/* For -fwrapv see PR80525, xfailing the subtest isn't possible as it passes
- with the C++ FE which doesn't have maybe_const_expr. */
-/* { dg-options "-fwrapv -Wlogical-op" } */
+/* { dg-options "-Wlogical-op" } */
#ifndef __cplusplus
# define bool _Bool
diff --git a/gcc/testsuite/c-c++-common/Wlogical-op-2.c b/gcc/testsuite/c-c++-common/Wlogical-op-2.c
new file mode 100644
index 0000000..6360ef9
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/Wlogical-op-2.c
@@ -0,0 +1,12 @@
+/* PR c/80525 */
+/* { dg-do compile } */
+/* { dg-options "-Wlogical-op" } */
+
+int
+fn (int a, int b)
+{
+ if ((a + 1) && (a + 1)) /* { dg-warning "logical .and. of equal expressions" } */
+ return a;
+ if ((a + 1) || (a + 1)) /* { dg-warning "logical .or. of equal expressions" } */
+ return b;
+}