[PATCH] Fix up undefined signed overflows in FIXED_SSNEG (PR libgcc/55451)

Jakub Jelinek jakub@redhat.com
Tue Dec 11 15:08:00 GMT 2012


On Tue, Dec 11, 2012 at 06:52:38AM -0800, Ian Lance Taylor wrote:
> I presume that the intent of the obfuscation is to make SSNEG look
> exactly like SSSUB.  And SSSUB appears to have the exact problems that
> you are fixing here.  So I think you ought to fix both the same way.

Ugh, I was hoping for a small patch.
Here is updated patch for the 5 routines I could quickly find by looking
around.

2012-12-11  Jakub Jelinek  <jakub@redhat.com>

	PR libgcc/55451
	* fixed-bit.c (FIXED_SSADD, FIXED_USADD, FIXED_SSSUB, FIXED_USSUB,
	FIXED_SSNEG): Avoid undefined signed overflows.

--- libgcc/fixed-bit.c.jj	2011-11-04 07:49:37.000000000 +0100
+++ libgcc/fixed-bit.c	2012-12-11 16:01:30.178653065 +0100
@@ -1,5 +1,5 @@
 /* This is a software fixed-point library.
-   Copyright (C) 2007, 2009, 2011 Free Software Foundation, Inc.
+   Copyright (C) 2007, 2009, 2011, 2012 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -80,15 +80,14 @@ FIXED_SSADD (FIXED_C_TYPE a, FIXED_C_TYP
   INT_C_TYPE x, y, z;
   memcpy (&x, &a, FIXED_SIZE);
   memcpy (&y, &b, FIXED_SIZE);
-  z = x + y;
+  z = x + (UINT_C_TYPE) y;
   if ((((x ^ y) >> I_F_BITS) & 1) == 0)
     {
       if (((z ^ x) >> I_F_BITS) & 1)
         {
-          z = 1;
-          z = z << I_F_BITS;
-          if (x >= 0)
-            z--;
+	  z = ((UINT_C_TYPE) 1) << I_F_BITS;
+	  if (x >= 0)
+	    z -= (UINT_C_TYPE) 1;
         }
     }
 #if HAVE_PADDING_BITS
@@ -108,7 +107,7 @@ FIXED_USADD (FIXED_C_TYPE a, FIXED_C_TYP
   INT_C_TYPE x, y, z;
   memcpy (&x, &a, FIXED_SIZE);
   memcpy (&y, &b, FIXED_SIZE);
-  z = x + y;
+  z = x + (UINT_C_TYPE) y;
 #if HAVE_PADDING_BITS
   z = z << PADDING_BITS;
   z = z >> PADDING_BITS;
@@ -152,15 +151,14 @@ FIXED_SSSUB (FIXED_C_TYPE a, FIXED_C_TYP
   INT_C_TYPE x, y, z;
   memcpy (&x, &a, FIXED_SIZE);
   memcpy (&y, &b, FIXED_SIZE);
-  z = x - y;
+  z = x - (UINT_C_TYPE) y;
   if (((x ^ y) >> I_F_BITS) & 1)
     {
       if (((z ^ x) >> I_F_BITS) & 1)
         {
-          z = 1;
-          z = z << I_F_BITS;
-          if (x >= 0)
-            z--;
+	  z = ((UINT_C_TYPE) 1) << I_F_BITS;
+	  if (x >= 0)
+	    z -= (UINT_C_TYPE) 1;
         }
     }
 #if HAVE_PADDING_BITS
@@ -180,7 +178,7 @@ FIXED_USSUB (FIXED_C_TYPE a, FIXED_C_TYP
   INT_C_TYPE x, y, z;
   memcpy (&x, &a, FIXED_SIZE);
   memcpy (&y, &b, FIXED_SIZE);
-  z = x - y;
+  z = x - (UINT_C_TYPE) y;
   if (x < y)
     z = 0;
 #if HAVE_PADDING_BITS
@@ -569,16 +567,11 @@ FIXED_SSNEG (FIXED_C_TYPE a)
   INT_C_TYPE x, y, z;
   memcpy (&y, &a, FIXED_SIZE);
   x = 0;
-  z = x - y;
+  z = x - (UINT_C_TYPE) y;
   if (((x ^ y) >> I_F_BITS) & 1)
     {
       if (((z ^ x) >> I_F_BITS) & 1)
-        {
-          z = 1;
-          z = z << I_F_BITS;
-          if (x >= 0)
-            z--;
-        }
+	z = (((UINT_C_TYPE) 1) << I_F_BITS) - 1;
     }
 #if HAVE_PADDING_BITS
   z = z << PADDING_BITS;


	Jakub



More information about the Gcc-patches mailing list