From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 24382 invoked by alias); 20 Mar 2007 09:27:23 -0000 Received: (qmail 24354 invoked by uid 48); 20 Mar 2007 09:27:11 -0000 Date: Tue, 20 Mar 2007 09:27:00 -0000 Message-ID: <20070320092711.24353.qmail@sourceware.org> X-Bugzilla-Reason: CC References: Subject: [Bug fortran/31262] -fno-range-check with large integer values triggers ICE In-Reply-To: Reply-To: gcc-bugzilla@gcc.gnu.org To: gcc-bugs@gcc.gnu.org From: "fxcoudert at gcc dot gnu dot org" Mailing-List: contact gcc-bugs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-bugs-owner@gcc.gnu.org X-SW-Source: 2007-03/txt/msg01913.txt.bz2 ------- Comment #2 from fxcoudert at gcc dot gnu dot org 2007-03-20 09:27 ------- Here's a patch: Index: trans-const.c =================================================================== --- trans-const.c (revision 123017) +++ trans-const.c (working copy) @@ -165,23 +165,31 @@ } else { - unsigned HOST_WIDE_INT words[2]; - size_t count; + unsigned HOST_WIDE_INT *words; + size_t count, numb; + /* Determine the number of unsigned HOST_WIDE_INT that are required + for represent the value. */ + numb = 8*sizeof(HOST_WIDE_INT); + count = (mpz_sizeinbase (i, 2) + numb-1) / numb; + if (count < 2) + count = 2; + words = (unsigned HOST_WIDE_INT *) alloca (count * sizeof(HOST_WIDE_INT)); + /* Since we know that the value is not zero (mpz_fits_slong_p), we know that at least one word will be written, but we don't know about the second. It's quicker to zero the second word before than conditionally clear it later. */ words[1] = 0; - + /* Extract the absolute value into words. */ - mpz_export (words, &count, -1, sizeof (HOST_WIDE_INT), 0, 0, i); + mpz_export (words, &count, -1, sizeof(HOST_WIDE_INT), 0, 0, i); - /* We assume that all numbers are in range for its type, and that - we never create a type larger than 2*HWI, which is the largest - that the middle-end can handle. */ - gcc_assert (count == 1 || count == 2); - + /* We don't assume that all numbers are in range for its type. + However, we never create a type larger than 2*HWI, which is the + largest that the middle-end can handle. So, we only take the + first two elements of words, which is equivalent to wrapping the + value if it's larger than the type range. */ low = words[0]; high = words[1]; And there's a small testcase, to see that the constant trees created for overflowing values have the same value than the naturally overflowing calculation done at run-time: $ cat uu.f90 integer :: a integer(kind=8) :: b a = -3 b = -huge(b) / 7 a = a ** 73 b = 7894_8 * b - 78941_8 print *, (-3)**73, a print *, 7894_8 * (-huge(b) / 7) - 78941_8, b end $ gfortran -fno-range-check uu.f90 && ./a.out -1534976995 -1534976995 2635249153387000989 2635249153387000989 -- fxcoudert at gcc dot gnu dot org changed: What |Removed |Added ---------------------------------------------------------------------------- Keywords| |patch Known to fail| |4.1.3 4.2.0 4.3.0 Summary|-fno-range-check can trigger|-fno-range-check with large |ICE |integer values triggers ICE http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31262