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
  • [Bug algol68/126062] New: ga68 m... jemarch at gcc dot gnu.org via Gcc-bugs

Reply via email to