This fixes an integer overflow warning that ultimatively happens because
of TREE_OVERFLOW propagating through transforms and the existing guard
against this,

375           if (TREE_OVERFLOW_P (ret)
376               && !TREE_OVERFLOW_P (op0)
377               && !TREE_OVERFLOW_P (op1))
378             overflow_warning (EXPR_LOC_OR_LOC (expr, input_location,

being insufficient.  Rather than trying to use sth like walk_tree to
exhaustively walk operands (with the possibility of introducing
quadraticness when folding larger expressions recursively) the
following amends the above with an ad-hoc test for a binary op0
with a possibly constant op1.

Bootstrapped and tested on x86_64-unknown-linux-gnu, OK?

Thanks,
Richard.

2020-05-19  Richard Biener  <rguent...@suse.de>

        PR c/95141
        c/
        * c-fold.c (c_fully_fold_internal): Enhance guard on
        overflow_warning.

        * gcc.dg/pr95141.c: New testcase.
---
 gcc/c/c-fold.c                 | 1 +
 gcc/testsuite/gcc.dg/pr95141.c | 8 ++++++++
 2 files changed, 9 insertions(+)
 create mode 100644 gcc/testsuite/gcc.dg/pr95141.c

diff --git a/gcc/c/c-fold.c b/gcc/c/c-fold.c
index 63becfeaf2c..bd21d247051 100644
--- a/gcc/c/c-fold.c
+++ b/gcc/c/c-fold.c
@@ -374,6 +374,7 @@ c_fully_fold_internal (tree expr, bool in_init, bool 
*maybe_const_operands,
        ret = fold (expr);
       if (TREE_OVERFLOW_P (ret)
          && !TREE_OVERFLOW_P (op0)
+         && !(BINARY_CLASS_P (op0) && TREE_OVERFLOW_P (TREE_OPERAND (op0, 1)))
          && !TREE_OVERFLOW_P (op1))
        overflow_warning (EXPR_LOC_OR_LOC (expr, input_location), ret, expr);
       if (code == LSHIFT_EXPR
diff --git a/gcc/testsuite/gcc.dg/pr95141.c b/gcc/testsuite/gcc.dg/pr95141.c
new file mode 100644
index 00000000000..b6cbba2f908
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr95141.c
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+uint64_t test(uint8_t IA1)
+{
+  return (uint8_t)(IA1 & 158) & 1UL; /* { dg-bogus "integer overflow" } */
+}
-- 
2.25.1

Reply via email to