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 <ja...@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