Article View: gnu.gcc.bug
Article #52GCC 2.3.1 overlooks int overflow in constant expressions
From: Paul Eggert
Date: Tue, 03 Nov 1992 01:33
Date: Tue, 03 Nov 1992 01:33
176 lines
6125 bytes
6125 bytes
GCC 2.3.1 (sparc, SunOS 4.1.2) doesn't warn about the integer overflow
in the program:
int x = 2147483647 + 1;
Here is a patch.
Tue Nov 3 00:52:08 1992 Paul Eggert (eggert@twinsun.com)
* fold-const.c (force_fit_type): Yield nonzero if target int overflows.
(const_binop, fold): Report an overflow if the target int overflows,
even if the HOST_WIDE_INT pair that represents it does not.
===================================================================
RCS file: fold-const.c,v
retrieving revision 2.3.1.1
retrieving revision 2.3.1.2
diff -c -r2.3.1.1 -r2.3.1.2
*** fold-const.c 1992/11/02 23:51:14 2.3.1.1
--- fold-const.c 1992/11/03 00:52:08 2.3.1.2
***************
*** 116,137 ****
/* Make the integer constant T valid for its type
by setting to 0 or 1 all the bits in the constant
! that don't belong in the type. */
! static void
force_fit_type (t)
tree t;
{
register int prec = TYPE_PRECISION (TREE_TYPE (t));
if (TREE_CODE (TREE_TYPE (t)) == POINTER_TYPE)
prec = POINTER_SIZE;
! /* First clear all bits that are beyond the type's precision. */
!
if (prec == 2 * HOST_BITS_PER_WIDE_INT)
! ;
! else if (prec > HOST_BITS_PER_WIDE_INT)
{
TREE_INT_CST_HIGH (t)
&= ~((HOST_WIDE_INT) (-1) << (prec - HOST_BITS_PER_WIDE_INT));
--- 116,140 ----
/* Make the integer constant T valid for its type
by setting to 0 or 1 all the bits in the constant
! that don't belong in the type.
! Yield nonzero if an arithmetic overflow occurs. */
! static int
force_fit_type (t)
tree t;
{
+ HOST_WIDE_INT low = TREE_INT_CST_LOW (t), high = TREE_INT_CST_HIGH (t);
register int prec = TYPE_PRECISION (TREE_TYPE (t));
if (TREE_CODE (TREE_TYPE (t)) == POINTER_TYPE)
prec = POINTER_SIZE;
! /* Do nothing if all the bits are in use. */
if (prec == 2 * HOST_BITS_PER_WIDE_INT)
! return 0;
!
! /* First clear all bits that are beyond the type's precision. */
! if (prec > HOST_BITS_PER_WIDE_INT)
{
TREE_INT_CST_HIGH (t)
&= ~((HOST_WIDE_INT) (-1) << (prec - HOST_BITS_PER_WIDE_INT));
***************
*** 143,156 ****
TREE_INT_CST_LOW (t) &= ~((HOST_WIDE_INT) (-1) << prec);
}
! /* If it's a signed type and value's sign bit is set, extend the sign. */
! if (! TREE_UNSIGNED (TREE_TYPE (t))
! && prec != 2 * HOST_BITS_PER_WIDE_INT
! && (prec > HOST_BITS_PER_WIDE_INT
! ? (TREE_INT_CST_HIGH (t)
! & ((HOST_WIDE_INT) 1 << (prec - HOST_BITS_PER_WIDE_INT - 1)))
! : TREE_INT_CST_LOW (t) & ((HOST_WIDE_INT) 1 << (prec - 1))))
{
/* Value is negative:
set to 1 all the bits that are outside this type's precision. */
--- 146,160 ----
TREE_INT_CST_LOW (t) &= ~((HOST_WIDE_INT) (-1) << prec);
}
! /* Unsigned types do not suffer sign extension or overflow. */
! if (TREE_UNSIGNED (TREE_TYPE (t)))
! return 0;
! /* If the value's sign bit is set, extend the sign. */
! if (prec > HOST_BITS_PER_WIDE_INT
! ? (TREE_INT_CST_HIGH (t)
! & ((HOST_WIDE_INT) 1 << (prec - HOST_BITS_PER_WIDE_INT - 1)))
! : TREE_INT_CST_LOW (t) & ((HOST_WIDE_INT) 1 << (prec - 1)))
{
/* Value is negative:
set to 1 all the bits that are outside this type's precision. */
***************
*** 166,171 ****
--- 170,178 ----
TREE_INT_CST_LOW (t) |= ((HOST_WIDE_INT) (-1) << prec);
}
}
+
+ /* Yield nonzero if overflow occurred. */
+ return ((low ^ TREE_INT_CST_LOW (t)) | (high ^ TREE_INT_CST_HIGH (t))) != 0;
}
/* Add two doubleword integers with doubleword result.
***************
*** 1269,1276 ****
}
got_it:
TREE_TYPE (t) = TREE_TYPE (arg1);
! force_fit_type (t);
! TREE_CONSTANT_OVERFLOW (t) = overflow;
return t;
}
#if ! defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
--- 1276,1282 ----
}
got_it:
TREE_TYPE (t) = TREE_TYPE (arg1);
! TREE_CONSTANT_OVERFLOW (t) = overflow | force_fit_type (t);
return t;
}
#if ! defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
***************
*** 3224,3233 ****
TREE_INT_CST_HIGH (arg0),
&low, &high);
t = build_int_2 (low, high);
- TREE_CONSTANT_OVERFLOW (t)
- = overflow | TREE_CONSTANT_OVERFLOW (arg0);
TREE_TYPE (t) = type;
! force_fit_type (t);
}
else if (TREE_CODE (arg0) == REAL_CST)
t = build_real (type, REAL_VALUE_NEGATE (TREE_REAL_CST (arg0)));
--- 3230,3240 ----
TREE_INT_CST_HIGH (arg0),
&low, &high);
t = build_int_2 (low, high);
TREE_TYPE (t) = type;
! TREE_CONSTANT_OVERFLOW (t)
! = (overflow
! | TREE_CONSTANT_OVERFLOW (arg0)
! | force_fit_type (t));
}
else if (TREE_CODE (arg0) == REAL_CST)
t = build_real (type, REAL_VALUE_NEGATE (TREE_REAL_CST (arg0)));
***************
*** 3257,3263 ****
&low, &high);
t = build_int_2 (low, high);
TREE_TYPE (t) = type;
! force_fit_type (t, overflow);
}
}
else if (TREE_CODE (arg0) == REAL_CST)
--- 3264,3273 ----
&low, &high);
t = build_int_2 (low, high);
TREE_TYPE (t) = type;
! TREE_CONSTANT_OVERFLOW (t)
! = (overflow
! | TREE_CONSTANT_OVERFLOW (arg0)
! | force_fit_type (t));
}
}
else if (TREE_CODE (arg0) == REAL_CST)
Technical Details
Message-ID:
<9211030133.AA05430@farside.twinsun.com>Path:
arc1-ca.pugleaf.net!sparky!uunet!portal!lll-winken!iggy.GW.Vitalink.COM!cs.widener.edu!umn.edu!spool.mu.edu!caen!zaphod.mps.ohio-state.edu!cis.ohio-state.edu!twinsun.COM!eggertShow Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!sparky!uunet!portal!lll-winken!iggy.GW.Vitalink.COM!cs.widener.edu!umn.edu!spool.mu.edu!caen!zaphod.mps.ohio-state.edu!cis.ohio-state.edu!twinsun.COM!eggert From: eggert@twinsun.COM (Paul Eggert) Newsgroups: gnu.gcc.bug Subject: GCC 2.3.1 overlooks int overflow in constant expressions Message-ID: <9211030133.AA05430@farside.twinsun.com> Date: 3 Nov 92 01:33:26 GMT Sender: gnulists@ai.mit.edu Distribution: gnu Organization: Gnus Not Usenet Lines: 176 Approved: bug-gcc@prep.ai.mit.edu