This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Preprocessor ICE on invalid input, with gcc-3.4.0


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;
}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]