🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: gnu.gcc.bug
Article #79

GCC 2.3.1 overlooks int overflow in constant expressions (correction)

#79
From: Paul Eggert
Date: Wed, 04 Nov 1992 21:02
221 lines
7720 bytes
My message ``GCC 2.3.1 overlooks int overflow in constant expressions''
(Message-ID: <9211030133.AA05430@farside.twinsun.com>, 3 Nov 1992) contains a
patch which unfortunately causes GCC to ignore the arithmetic overflow in the
program:

	long long x = 9223372036854775807LL + 1;

Here is a fix, expressed as both (1) a patch to my earlier patch, and (2) a
corrected version of my earlier patch, which you can use if you haven't
applied the earlier patch.


1.  a patch to the earlier patch:

Wed Nov  4 20:12:02 1992  Paul Eggert  (eggert@twinsun.com)

	* fold-const.c (force_fit_type): Don't ignore long long overflow.

===================================================================
RCS file: fold-const.c,v
retrieving revision 2.3.1.3
retrieving revision 2.3.1.4
diff -c -r2.3.1.3 -r2.3.1.4
*** fold-const.c	1992/11/03 02:49:59	2.3.1.3
--- fold-const.c	1992/11/04 20:29:55	2.3.1.4
***************
*** 131,142 ****
    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));
--- 131,141 ----
    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));
***************
*** 153,162 ****
      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.  */
--- 152,162 ----
      return 0;
  
    /* If the value's sign bit is set, extend the sign.  */
!   if (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.  */



2.  A corrected version of my earlier patch:

Wed Nov  4 20:12:02 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.1.1
diff -c -r2.3.1.1 -r2.3.1.2.1.1
*** fold-const.c	1992/11/02 23:51:14	2.3.1.1
--- fold-const.c	1992/11/04 20:59:37	2.3.1.2.1.1
***************
*** 116,127 ****
  
  /* 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)
--- 116,129 ----
  
  /* 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)
***************
*** 143,152 ****
  	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)))
--- 145,156 ----
  	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 != 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)))
***************
*** 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: <9211042102.AA13417@farside.twinsun.com>
Path: arc1-ca.pugleaf.net!sparky!uunet!charon.amdahl.com!pacbell.com!decwrl!sdd.hp.com!cs.utexas.edu!zaphod.mps.ohio-state.edu!cis.ohio-state.edu!twinsun.COM!eggert

Show Full Headers
Complete Article Headers
Newsgroups: gnu.gcc.bug
Path: arc1-ca.pugleaf.net!sparky!uunet!charon.amdahl.com!pacbell.com!decwrl!sdd.hp.com!cs.utexas.edu!zaphod.mps.ohio-state.edu!cis.ohio-state.edu!twinsun.COM!eggert
From: eggert@twinsun.COM (Paul Eggert)
Subject: GCC 2.3.1 overlooks int overflow in constant expressions (correction)
Message-ID: <9211042102.AA13417@farside.twinsun.com>
Sender: gnulists@ai.mit.edu
Organization: GNUs Not Usenet
Distribution: gnu
Date: Wed, 4 Nov 1992 21:02:50 GMT
Approved: bug-gcc@prep.ai.mit.edu
Lines: 222