not really a bug but somewhat odd : checking compiler /usr/local/bin/gcc8 ... no, mpn_lshift_com

Vincent Lefevre vincent at vinc17.net
Sun Jul 28 10:44:55 UTC 2019


On 2019-07-28 06:12:06 -0400, Dennis Clarke wrote:
> configure:6813: ./a.out || ./b.out || ./a.exe || ./a_out.exe || ./conftest
> Abort trap (core dumped)

I don't know in your case, but I fear that this program is buggy.

[...]
> void
> lshift_com (rp, up, n, cnt)
>   unsigned long *rp;
>   unsigned long *up;
>   long n;
>   unsigned cnt;

It uses the old pre-ANSI K&R function definition, and AFAIK, in
this case, there is no notion of prototype, i.e. it is expected
that the caller passes compatible types as the compiler will not
be able to do type conversion. Note that the 4th parameter, cnt,
is of type unsigned int.

> {
>   unsigned long high_limb, low_limb;
>   unsigned tnc;
>   long i;
>   up += n;
>   rp += n;
>   tnc = 8 * sizeof (unsigned long) - cnt;
>   low_limb = *--up;
>   high_limb = low_limb << cnt;
>   for (i = n - 1; i != 0; i--)
>     {
>       low_limb = *--up;
>       *--rp = ~(high_limb | (low_limb >> tnc));
>       high_limb = low_limb << cnt;
>     }
>   *--rp = ~high_limb;
> }
> int
> main ()
> {
>   unsigned long *r, *r2;
>   unsigned long a[88 + 1];
>   long i;
>   for (i = 0; i < 88 + 1; i++)
>     a[i] = ~0L;
>   r = malloc (10000 * sizeof (unsigned long));
>   r2 = r;
>   for (i = 0; i < 528; i += 23)
>     {
>       lshift_com (r2, a,
>                   i / (8 * sizeof (unsigned long)) + 1,
>                   i % (8 * sizeof (unsigned long)));

Here the 4th argument is of type >= long since i is of type long.
With calling via registers, this may not be an issue (here, the
value would be correct), but if the data are passed on the stack,
this will probably not work.

>       r2 += 88 + 1;
>     }
>   if (r[2048] != 0 || r[2049] != 0 || r[2050] != 0 || r[2051] != 0 ||
>       r[2052] != 0 || r[2053] != 0 || r[2054] != 0)
>     abort ();
>   free (r);
>   return 0;
> }
[...]

If you want an example about K&R function definition issues,
consider

foo (a)
{
}

main ()
{
  foo (1, 2);
  return 0;
}

With GCC, this builds without any error.

-- 
Vincent Lefèvre <vincent at vinc17.net> - Web: <https://www.vinc17.net/>
100% accessible validated (X)HTML - Blog: <https://www.vinc17.net/blog/>
Work: CR INRIA - computer arithmetic / AriC project (LIP, ENS-Lyon)


More information about the gmp-bugs mailing list