Bug 19978

Summary: overflow in expression of constants should not cause multiple warnings
Product: gcc Reporter: Joseph S. Myers <jsm28>
Component: cAssignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED FIXED    
Severity: normal CC: gcc-bugs, manu, roger
Priority: P2 Keywords: diagnostic
Version: 4.0.0   
Target Milestone: 4.3.0   
Host: Target:
Build: Known to work:
Known to fail: 3.3.3 3.2.3 3.4.0 4.0.0 3.0.4 2.95.3 Last reconfirmed: 2005-12-18 01:40:23

Description Joseph S. Myers 2005-02-15 18:48:26 UTC
The test

#include <limits.h>

int
f (void)
{
  return INT_MAX + 1 - INT_MAX;
}

should yield only a single "integer overflow in expression" warning,
but yields two.  Not a regression.
Comment 1 Andrew Pinski 2005-02-15 21:20:52 UTC
Confirmed.
Comment 2 Andrew Pinski 2005-02-17 05:09:52 UTC
The problem is that we reset TREE_OVERFLOW:
  if ((TREE_CODE (value) == INTEGER_CST
       || (TREE_CODE (value) == COMPLEX_CST
           && TREE_CODE (TREE_REALPART (value)) == INTEGER_CST))
      && TREE_OVERFLOW (value))
    {
      TREE_OVERFLOW (value) = 0;
      if (skip_evaluation == 0)
        warning ("integer overflow in expression");
    }
Comment 3 Paul Schlie 2005-02-17 23:37:38 UTC
(In reply to comment #2)
> The problem is that we reset TREE_OVERFLOW:

It would seem it overflows incremented, and underflow's decremented,
only a terminal non-zero count would represent an over/underflow for
addition/subtraction, (as an intermediate over/underflow is not observable)?
Comment 4 Manuel López-Ibáñez 2006-11-26 19:27:19 UTC
(In reply to comment #3)
> (In reply to comment #2)
> > The problem is that we reset TREE_OVERFLOW:
> 
> It would seem it overflows incremented, and underflow's decremented,
> only a terminal non-zero count would represent an over/underflow for
> addition/subtraction, (as an intermediate over/underflow is not observable)?
> 

No. 1 - INT_MAX is not underflow or overflow. 
For example:
int
f2 (void)
{
  return INT_MAX + 1 - 1;
}

gives also two "integer overflow in expression" warnings.

Actually, I think the problem is that somewhere TREE_OVERFLOW() is set whenever TREE_CONSTANT_OVERFLOW() is 1. After the first warning is emitted, TREE_OVERFLOW() is set to 0 but TREE_CONSTANT_OVERFLOW() remains 1. When the next part of the expression is handled TREE_OVERFLOW() is set again because TREE_CONSTANT_OVERFLOW is still 1, so the warning is emitted a second time.

For example:

  return INT_MAX + 1 - 1 + 1 - 1 + 1 - 1;

generates 6 warnings. Is this the desired behaviour?


Comment 5 patchapp@dberlin.org 2006-12-09 01:10:24 UTC
Subject: Bug number PR c/19978

A patch for this bug has been added to the patch tracker.
The mailing list url for the patch is http://gcc.gnu.org/ml/gcc-patches/2006-12/msg00588.html
Comment 6 Manuel López-Ibáñez 2007-01-05 21:57:12 UTC
Subject: Bug 19978

Author: manu
Date: Fri Jan  5 21:57:01 2007
New Revision: 120505

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=120505
Log:
2007-01-05  Manuel Lopez-Ibanez  <manu@gcc.gnu.org>

	PR c/19978
	* tree.h (TREE_OVERFLOW_P): New.
	* c-typeck.c (parser_build_unary_op): Warn only if result
	overflowed and operands did not.
	(parser_build_binary_op): Likewise.
	(convert_for_assignment): Remove redundant overflow_warning.
	* c-common.c (overflow_warning): Don't check or set TREE_OVERFLOW.

cp/
	* semantics.c (finish_unary_op_expr): Warn only if result
	overflowed and operands did not.

testsuite/
	* gcc.dg/multiple-overflow-warn-1.c: New.
	* gcc.dg/multiple-overflow-warn-2.c: New.
	* gcc.dg/overflow-warn-6.c: New.
	* g++.dg/warn/multiple-overflow-warn-1.C: New.

Added:
    trunk/gcc/testsuite/g++.dg/warn/multiple-overflow-warn-1.C
    trunk/gcc/testsuite/gcc.dg/multiple-overflow-warn-1.c
    trunk/gcc/testsuite/gcc.dg/multiple-overflow-warn-2.c
    trunk/gcc/testsuite/gcc.dg/overflow-warn-6.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/c-common.c
    trunk/gcc/c-typeck.c
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/semantics.c
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/tree.h

Comment 7 Manuel López-Ibáñez 2007-01-06 09:34:32 UTC
Fixed in mainline.
Comment 8 Paul Schlie 2007-01-06 15:04:07 UTC
It seems that an overflow warning should be generated if an overflowed value
is utilized or results from an expression evaluation between sequence ponts?
Thereby:

x = INT_MAX + 2 - 2 ; // warning x may overflow.

z = (y = x +1, y - 2)  ; // warning y may overflow, warning z may overflow.

if (z < INT_MAX) {<something>} // warning if may overflow.