https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126062

--- Comment #1 from clhermansen at gmail dot com ---
Good afternoon, all;

Please see my comments at the end.

On Wed, Jul 1, 2026 at 2:24 AM jemarch at gcc dot gnu.org <
[email protected]> wrote:

> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126062
>
>             Bug ID: 126062
>            Summary: ga68 mishandles negative integer
>            Product: gcc
>            Version: 16.0
>             Status: UNCONFIRMED
>           Severity: normal
>           Priority: P3
>          Component: algol68
>           Assignee: algol68 at gcc dot gnu.org
>           Reporter: jemarch at gcc dot gnu.org
>   Target Milestone: ---
>
> [Reported by Nelson H. F. Beebe]
>
> Consider these two programs for printing integers near the 32-bit
> integer overflow limit:
>
> % cat bigint32.c
> #include <stdint.h>
> #include <stdio.h>
> #include <stdlib.h>
>
> int
> main(void)
> {
>     int32_t k, m;
>
>     m = 2147483647;
>     (void)printf(" m =     %11d\n", m);
>
>     for (k = 0; k <= 5; ++k)
>         (void)printf("-m - %d = %11d\n", k, (-m) - k);
>
>     return (EXIT_SUCCESS);
> }
>
> % cat bigint.a68
> begin
>     int m = 2147483647;
>     int k;
>     puts(" m     = " + whole(m, 11) + "'n");
>     for k from 0 to 6
>     do
>         puts("-m - " + whole(k, 0) + " = " + whole(-m - k, 11) + "'n")
>     od
> end
>
> The first when run produces the expected output from undetected signed
> integer overflow in two's complement arithmetic (universal today):
>
> % cc bigint32.c && ./a.out
>  m = 2147483647
> -m - 0 = -2147483647
> -m - 1 = -2147483648
> -m - 2 = 2147483647
> -m - 3 = 2147483646
> -m - 4 = 2147483645
> -m - 5 = 2147483644
>
> Now see what the Algol 68 version produces:
>
> % ga68 --version
> ga68 (GCC) 17.0.0 20260426 (experimental)
> ...
>
> % ga68 bigint.a68 && ./a.out
>  m     = +2147483647
> -m - 0 = -2147483647
> -m - 1 = -8963627462
> -m - 2 = +2147483647
> -m - 3 = +2147483646
> -m - 4 = +2147483645
> -m - 5 = +2147483644
> -m - 6 = +2147483643
>
> The value for -m - 1 should be the most negative integer, -2147483648,
> but instead, the value -8963627462 (== -0x2164619c6) appears.
>
> This seems like a definite bug in the ga68 transput code, or in the
> whole() conversion function!
>
> A version for the Algol 68 Genie compiler works like the C version:
>
> % cat bigint.a68
> BEGIN
>     INT m = 2147483647;
>     INT k;
>     print((" m     = ", whole(m, 11), newline));
>     FOR k FROM 0 TO 6
>     DO
>         print(("-m - ", whole(k, 0), " = ", whole(-m - k, 11), newline))
>     OD
> END
>
> % a68g bigint.a68
>  m     = +2147483647
> -m - 0 = -2147483647
> -m - 1 = -2147483648
> -m - 2 = -2147483649
> -m - 3 = -2147483650
> -m - 4 = -2147483651
> -m - 5 = -2147483652
> -m - 6 = -2147483653
>
> --
> You are receiving this mail because:
> You are the assignee for the bug.


Looking at the above, I don't understand the comment  "A version for the
Algol 68 Genie compiler works like the C version"

The Genie numbers from -m - 2 on down are negative (remember Genie uses 64
bit integers).

The GNU Algol 68 numbers, except for -m - 1, match the C numbers.

Or am I missing something?

Anyway, since I have van Vliet's partial implementation cracked open on the
bench, I thought I would try his whole and subwhole routines to see if they
produce the correct results...

And unfortunately, they mess up on the -m - 1 value as well.

 m     = +2147483647
-m - 0 = -2147483647
-m - 1 = -8963627462
-m - 2 = +2147483647
-m - 3 = +2147483646
-m - 4 = +2147483645
-m - 5 = +2147483644
-m - 6 = +2147483643

I wonder if the problem here is that both RR and van Vliet  converters take
the ABS of the argument.  If we add a bit to Nelson's program as:

begin
    int m = 2147483647;
    int k;
    puts(" m     = " + whole(m, 11) + "'n");
    for k from 0 to 6
    do
        puts("-m - " + whole(k, 0) + " = " + whole(-m - k, 11) + "'n")
    od;
    puts("ABS  m     = " + whole(ABS m, 11) + "'n");
    for k from 0 to 6
    do
        puts("ABS (-m - " + whole(k, 0) + ") = " + whole(ABS (-m - k), 11)
+ "'n")
    od
end

and run this, we get:

 m     = +2147483647
-m - 0 = -2147483647
-m - 1 = -8963627462
-m - 2 = +2147483647
-m - 3 = +2147483646
-m - 4 = +2147483645
-m - 5 = +2147483644
-m - 6 = +2147483643
ABS  m     = +2147483647
ABS (-m - 0) = +2147483647
ABS (-m - 1) = -8963627462
ABS (-m - 2) = +2147483647
ABS (-m - 3) = +2147483646
ABS (-m - 4) = +2147483645
ABS (-m - 5) = +2147483644
ABS (-m - 6) = +2147483643

Not sure if this sheds any light on things...

Reply via email to