This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
Preprocessor ICE on invalid input, with gcc-3.4.0
- From: niels at s3 dot kth dot se (Niels Möller)
- To: gcc-bugs at gcc dot gnu dot org
- Cc: nisse <nisse at lysator dot liu dot se>
- Date: 05 May 2004 18:44:13 +0200
- Subject: Preprocessor ICE on invalid input, with gcc-3.4.0
- Reply-to: nisse <nisse at lysator dot liu dot se>
System information:
Debian GNU/Linux, uname -a: "Linux carduelis.s3.kth.se 2.4.18nisse
#1 Thu Feb 27 17:26:25 CET 2003 i686 unknown"
gcc-3.4.0, built with ./configure && make bootstrap && make install
Problem: Preprocessing crashes with
bug.c:0: internal compiler error: Segmentation fault
Please submit a full bug report,
with preprocessed source if appropriate.
See <URL:http://gcc.gnu.org/bugs.html> for instructions.
when the correct behaviour would be to output an error message
unterminated argument list invoking macro "ASSERT"
Compilation command line:
gcc -DWANT_CHECKS=1 -E bug.c
Source file (before preprocessing, but there are no #include
directives in it) is attached.
Regards,
/Niels
#define ASSERT(expr) ASSERT_ALWAYS (expr)
static void
hbgcd2 (mp_limb_t ah, mp_limb_t al, mp_limb_t bh, mp_limb_t bl, unsigned k,
struct bgcd_matrix1 *m)
{
#define MUL_Q(bits, q) do { \
/* Multiply by q */ \
r00 = (r00 << (bits)) + (q) * r10; \
r10 <<= bits; \
r01 = (r01 << (bits)) + (q) * r11; \
r11 <<= (bits); \
MP_LIMB_SIGNED_T_SWAP (r00, r10); \
MP_LIMB_SIGNED_T_SWAP (r01, r11); \
} while (0)
/* Indexed by bit 1-4 of an even number b, to determine the number of
zero bits at the least significant end. Zero if the value is not
well defined. A typical distribution looks like
bits f % % (cumulative) % (theoretical)
1 1884 45 45 50
2 1098 26 71 25
3 480 11 83 12.5
4 354 8 91 6.25
0 366 9 100 6.25
--------------
sum 3816
*/
static const unsigned char zerobits_table[0x16] =
{ 0,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1 };
mp_limb_signed_t r00, r01, r10, r11;
unsigned j;
ASSERT (ODD (al));
ASSERT (!ODD (bl));
ASSERT (k <= SMALL_STEP_BITS);
r00 = r11 = 1;
r01 = r10 = 0;
j = 0;
/* Loop while we need more than one limb of accuracy. */
while (k - j > GMP_NUMB_BITS / 2)
{
/* Through out this loop, only the 2*(GMP_NUMB_BITS - j) least
significant bits of a and b are accurate. */
unsigned bits;
mp_limb_t t0, t1;
mp_limb_signed_t q;
TRACE (printf ("hgcd2: a = %8lx %08lx\n"
" b = %8lx %08lx\n",
ah, al, bh, bl));
ASSERT (ODD (al));
ASSERT (!ODD (bl);
if (bl == 0)
goto done;
/* Table lookup is sufficient to determine the common cases, 1
<= bits <= 4 */
bits = zerobits_table[(bl / 2) & 0xf];
switch (bits)
{
case 1:
/* a and b are in the set { 1, 3 } = mod 4
b b^-1 -b^-1 | *a = 01 11
---------------+--------
01 01 11 | 11 01
11 11 01 | 01 11
*/
RSHIFT2 (bh, bl, 1);
if ((al ^ bl) & 2)
{
/* q = 1 */
MUL_Q (1, 1);
add_ssaaaa (ah, al, ah, al, bh, bl);
}
else
{
MUL_Q (1, -1);
sub_ddmmss (ah, al, ah, al, bh, bl);
}
break;
case 2:
/* a and b are in the set { 1, 3, 5, 7 } = mod 8
b b^-1 -b^-1 | *a = 001 011 101 111
---------------+--------
001 001 111 | 111 101 011 001
011 011 101 | 101 111 001 011
101 101 011 | 011 001 111 101
111 111 001 | 001 011 101 111
*/
RSHIFT2 (bh, bl, 2);
q = ((al ^ bl ^ 2) & 7) - 3;
MUL_Q (2, q);
goto hbgcd2_add;
case 0:
count_trailing_zeros (bits, bl);
/* Fall through */
default:
ASSERT (bits > 0);
if (bits + j >= k)
goto done;
RSHIFT2 (bh, bl, bits);
q = bdiv_1 (al, bl, bits);
ASSERT (ODD (q));
MUL_Q (bits, q);
hbgcd2_add:
TRACE (printf ("hbgcd2: bits = %d, q = %ld\n", bits, q));
if (q > 0)
{
/* Compute a + q b, store result in a */
umul_ppmm (t1, t0, bl, q);
al += t0;
ah += t1 + (al < t0) + q * bh; /* We don't care about overflow */
}
else
{
/* Compute a - |q| b, store result in a */
umul_ppmm (t1, t0, bl, -q);
ah -= t1 + (al < t0) - q * bh; /* We don't care about overflow */
al -= t0;
}
}
j += bits;
ASSERT ( (al & ((CNST_LIMB(1) << (bits + 1)) - 1)) == 0);
RSHIFT2 (ah, bl, bits);
MP_LIMB_T_SWAP (ah, bh);
MP_LIMB_T_SWAP (al, bl);
}
for (;;)
{
/* Through out this loop, only the 2*(k - j) least
significant bits of a and b are accurate. */
unsigned bits;
mp_limb_signed_t q;
ASSERT (!ODD (bl));
if (bl == 0 || j + 1 >= k)
break;
bits = zerobits_table[(bl / 2) & 0xf];
switch (bits)
{
case 1:
bl >>= 1;
q = ((al ^ bl) & 3) - 1;
MUL_Q (1, q);
break;
case 2:
if (j + 2 >= k)
goto done;
bl >>= 2;
q = ((al ^ bl ^ 2) & 7) - 3;
MUL_Q (2, q);
break;
case 0:
count_trailing_zeros (bits, bl);
/* Fall through */
default:
ASSERT (bits > 0);
if (bits + j >= k)
goto done;
bl >>= bits;
q = bdiv_1 (al, bl, bits);
ASSERT (ODD (q));
MUL_Q (bits, q);
}
j += bits;
al += q * bl; /* We don't care about overflow */
ASSERT ( (al & ((CNST_LIMB(1) << (bits + 1)) - 1)) == 0);
al >>= bits;
MP_LIMB_T_SWAP (al, bl);
}
done:
m->R[0][0] = r00;
m->R[0][1] = r01;
m->R[1][0] = r10;
m->R[1][1] = r11;
m->j = j;
#undef MUL_Q
}
#define BDIVMOD_N_ITCH(n, zlimbs) (MAX (4*(zlimbs), (n)))
static void
sanity_check_hbgcd (const struct bgcd_matrix *m,
const mpz_t a, const mpz_t b,
mp_srcptr cp, mp_srcptr dp, mp_size_t n, unsigned k, int finished);
static void
mpnz_set (mpz_t r, mp_srcptr xp, mp_size_t n);
static int
mpnz_equal_p (const mpz_t a, mp_srcptr bp, mp_size_t bn);
#if WANT_CHECKS
# define ASSERT_BGCD_MATRIX(m, a, b, cp, dp, n, k, f) \
sanity_check_hbgcd ((m), (a), (b), (cp), (dp), (n), (k), (f))
#else
# define ASSERT_BGCD_MATRIX(m, a, b, cp, dp, n, k, f)
#endif
/* Takes as input two n-limb numbers (typically the least
significant limbs of some larger numbers), a odd, b even, and an
integer k.
Returns an array R, an integer j, two numbers a', b' such that
/a'\ -2j /a\
\b'/ = 2 R \b/
where
a' is odd
v (2^j a') < k,
v (2^j b') >= k
*/
/* Needs temporary space for calling bgcd_matrix1_apply,
bgcd_matrix1_mul, bdivmod_n, bgcd_matrix_mul_q, and storing q. The
most demanding is bdivmod, for which we need 5*n/2 limbs. */
#define HBGCD_N_BASE_ITCH(n) (5*(n)/2)
static mp_size_t
hbgcd_n_base (mp_ptr ap, mp_ptr bp, mp_size_t n, unsigned k,
struct bgcd_matrix *m, mp_ptr tp)
{
#if WANT_CHECKS
mpz_t oa;
mpz_t ob;
mpz_init (oa);
mpz_init (ob);
mpnz_set (oa, ap, n);
mpnz_set (ob, bp, n);
#endif
MUNG_STORAGE (tp, HBGCD_N_BASE_ITCH (n), 8);
ASSERT (2 * k <= n * GMP_NUMB_BITS);
ASSERT (BGCD_MATRIX_ITCH (n) <= m->alloc);
/* Should be initialized already */
ASSERT (m->j == 0);
ASSERT (n >= 2);
ASSERT (ODD (ap[0]));
ASSERT (!ODD (bp[0]));
for (;;)
{
mp_size_t zlimbs;
unsigned zbits;
ASSERT (ODD (ap[0]));
ASSERT (!ODD (bp[0]));
ASSERT_BGCD_MATRIX (m, oa, ob, ap, bp, n, k, 0);
zlimbs = power_of_2 (&zbits, bp, n);
if (zlimbs * GMP_NUMB_BITS + zbits + m->j >= k)
break;
else if (k - m->j < SMALL_STEP_BITS)
{
/* FIXME: Some duplication with next case. */
struct bgcd_matrix1 m1;
/* Here, we may have n == 1, and then the values ap[1] and
bp[1] will not be used. */
hbgcd2 (ap[1], ap[0], bp[1], bp[0], k - m->j, &m1);
ASSERT (m1.j > 0);
/* Modifies the signs of the matrix elements. */
n = bgcd_matrix1_apply (&m1, ap, bp, n, tp);
bgcd_matrix_mul_1 (m, &m1, tp);
break;
}
else if (zlimbs == 0 && zbits < SMALL_STEP_BITS)
{
struct bgcd_matrix1 m1;
hbgcd2 (ap[1], ap[0], bp[1], bp[0], SMALL_STEP_BITS, &m1);
ASSERT (m1.j > 0);
/* Modifies the signs of the matrix elements. */
n = bgcd_matrix1_apply (&m1, ap, bp, n, tp);
bgcd_matrix_mul_1 (m, &m1, tp);
}
else
{
mp_size_t i;
mp_limb_t cy;
int qsign;
int rsign;
ASSERT (zlimbs <= (n-1) /2);
if (zbits)
ASSERT_NOCARRY (mpn_rshift (bp, bp + zlimbs, n - zlimbs, zbits));
else
MPN_COPY_INCR (bp, bp + zlimbs, n - zlimbs);
/* Needs zlimbs + 1 to store the quotient, and MAX (n, 4
zlimbs) for the computations. Since zlimbs <= (n-1)/2,
the total need is at most
(n + 1) / 2 + MAX (n, 2*(n-1)) = n/2 + 1/2 + 2*n - 2 <= 5*n/2
*/
cy = bdivmod_n (tp, &qsign, &rsign, ap, bp, n,
zlimbs, zbits, tp + zlimbs + 1);
/* Needs zlimbs + 1 + m->n <= 2*n limbs of temporary storage. */
bgcd_matrix_mul_q (m, zlimbs, zbits, tp, qsign, tp + zlimbs + 1);
if (rsign < 0)
{
m->sign[1][0] = ~m->sign[1][0];
m->sign[1][1] = ~m->sign[1][1];
}
n -= zlimbs;
if (cy > 0)
{
ap[n] = cy;
bp[n] = 0;
n++;
}
/* Swapping pointers would confuse our caller, so we have to swap
the contents. */
for (i = 0; i<n; i++)
MP_LIMB_T_SWAP (ap[i], bp[i]);
}
}
ASSERT_BGCD_MATRIX (m, oa, ob, ap, bp, n, k, 1);
#if WANT_CHECKS
mpz_clear (oa);
mpz_clear (ob);
#endif
return n;
}