[Bug c/95141] [8/9/10/11 Regression] Incorrect integer overflow warning message for bitand expression

2020-05-20 Thread cvs-commit at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95141

--- Comment #4 from CVS Commits  ---
The master branch has been updated by Richard Biener :

https://gcc.gnu.org/g:4a88caf21a0a85129f6c985ca13ba3eb54ff5366

commit r11-509-g4a88caf21a0a85129f6c985ca13ba3eb54ff5366
Author: Richard Biener 
Date:   Tue May 19 07:58:33 2020 +0200

c/95141 - fix bogus integer overflow warning

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.

2020-05-30  Richard Biener  

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

gcc/testsuite
* gcc.dg/pr95141.c: New testcase.

[Bug c/95141] [8/9/10/11 Regression] Incorrect integer overflow warning message for bitand expression

2020-05-18 Thread rguenth at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95141

--- Comment #3 from Richard Biener  ---
(In reply to Richard Biener from comment #2)
> So there's already (OVF) at
> 
> ((long unsigned int) IA1 & 158(OVF)) & 1
> 
> but we only check
> 
> 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),
> ret, expr);
> 
> which doesn't catch the pre-existing overflow on op0 which then propagates.
> 
> The original overflow is introduced folding short 158 to signed char -98(OVF)
> via convert.c:do_narrow:
> 
> 437   /* We should do away with all this once we have a proper
> 438  type promotion/demotion pass, see PR45397.  */
> 439   expr = maybe_fold_build2_loc (dofold, loc, ex_form, typex,
> 440 convert (typex, arg0),
> 441 convert (typex, arg1));
> 
> specifically the convert (typex, arg1).
> 
> Now TREE_OVERFLOW in general is quite a fragile thing, but it's tempting to
> adjust the overflow_warning guard for this case ...
> 
> The do_narrow code also specifically looks for overflow cases that matter
> and does not perform narrowing then so clearing TREE_OVERFLOW there would
> also look reasonable.
> 
> Thus like the following?  Should be cheaper than adding walk_tree to the
> diagnostic guard.
> 
> diff --git a/gcc/convert.c b/gcc/convert.c
> index 42509c518a9..ed00ded1a89 100644
> --- a/gcc/convert.c
> +++ b/gcc/convert.c
> @@ -436,9 +436,16 @@ do_narrow (location_t loc,
> }
>/* We should do away with all this once we have a proper
>  type promotion/demotion pass, see PR45397.  */
> +  /* Above we checked for all cases where overflow matters, avoid
> +geneating overflowed constants here which otherwise propagate
> +and cause spurious warnings, see PR95141.  */
> +  tree converted_arg1 = convert (typex, arg1);
> +  if (TREE_OVERFLOW_P (converted_arg1)
> + && !TREE_OVERFLOW_P (arg1))
> +   converted_arg1 = drop_tree_overflow (converted_arg1);
>expr = maybe_fold_build2_loc (dofold, loc, ex_form, typex,
> convert (typex, arg0),
> -   convert (typex, arg1));
> +   converted_arg1);
>return convert (type, expr);
>  }

Regresses

FAIL: gcc.dg/overflow-warn-5.c  (test for warnings, line 6)

which looks like a useful warning to preserve.  Lame "walk-tree" variant
catching this case:

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

[Bug c/95141] [8/9/10/11 Regression] Incorrect integer overflow warning message for bitand expression

2020-05-15 Thread rguenth at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95141

Richard Biener  changed:

   What|Removed |Added

 Status|NEW |ASSIGNED
   Assignee|unassigned at gcc dot gnu.org  |rguenth at gcc dot 
gnu.org

--- Comment #2 from Richard Biener  ---
So there's already (OVF) at

((long unsigned int) IA1 & 158(OVF)) & 1

but we only check

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), ret,
expr);

which doesn't catch the pre-existing overflow on op0 which then propagates.

The original overflow is introduced folding short 158 to signed char -98(OVF)
via convert.c:do_narrow:

437   /* We should do away with all this once we have a proper
438  type promotion/demotion pass, see PR45397.  */
439   expr = maybe_fold_build2_loc (dofold, loc, ex_form, typex,
440 convert (typex, arg0),
441 convert (typex, arg1));

specifically the convert (typex, arg1).

Now TREE_OVERFLOW in general is quite a fragile thing, but it's tempting to
adjust the overflow_warning guard for this case ...

The do_narrow code also specifically looks for overflow cases that matter
and does not perform narrowing then so clearing TREE_OVERFLOW there would
also look reasonable.

Thus like the following?  Should be cheaper than adding walk_tree to the
diagnostic guard.

diff --git a/gcc/convert.c b/gcc/convert.c
index 42509c518a9..ed00ded1a89 100644
--- a/gcc/convert.c
+++ b/gcc/convert.c
@@ -436,9 +436,16 @@ do_narrow (location_t loc,
}
   /* We should do away with all this once we have a proper
 type promotion/demotion pass, see PR45397.  */
+  /* Above we checked for all cases where overflow matters, avoid
+geneating overflowed constants here which otherwise propagate
+and cause spurious warnings, see PR95141.  */
+  tree converted_arg1 = convert (typex, arg1);
+  if (TREE_OVERFLOW_P (converted_arg1)
+ && !TREE_OVERFLOW_P (arg1))
+   converted_arg1 = drop_tree_overflow (converted_arg1);
   expr = maybe_fold_build2_loc (dofold, loc, ex_form, typex,
convert (typex, arg0),
-   convert (typex, arg1));
+   converted_arg1);
   return convert (type, expr);
 }

[Bug c/95141] [8/9/10/11 Regression] Incorrect integer overflow warning message for bitand expression

2020-05-15 Thread jakub at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95141

Jakub Jelinek  changed:

   What|Removed |Added

 CC||jakub at gcc dot gnu.org
   Last reconfirmed||2020-05-15
   Target Milestone|--- |8.5
 Ever confirmed|0   |1
Summary|Incorrect integer overflow  |[8/9/10/11 Regression]
   |warning message for bitand  |Incorrect integer overflow
   |expression  |warning message for bitand
   ||expression
 Status|UNCONFIRMED |NEW

--- Comment #1 from Jakub Jelinek  ---
Started with r7-7544-g2d143ba8cfef7ef480c639882fd5518b7afd822b