🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: gnu.gcc.bug
Article #52

GCC 2.3.1 overlooks int overflow in constant expressions

#52
From: Paul Eggert
Date: Tue, 03 Nov 1992 01:33
176 lines
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!eggert

Show 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