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