Files
mercury/tests/hard_coded/c89_neg_int.m
Peter Wang 4ac91a2d81 Fix how large negative integers are written for C89.
C does not have negative integer constants so "(MR_Integer) -nnnn"
is the negation of a positive integer constant nnnn, converted to
MR_Integer.

In C89/C90 an unsuffixed decimal integer constant must be typed
`int' or `long int' or `unsigned long int', whichever fits first.
The negated result will have the same type. If nnnn > LONG_MAX then
it will be typed `unsigned long int'. If MR_Integer is wider than
`unsigned long int' then the conversion to MR_Integer yields a positive
value, not negative.

The solution here is essentially to write "-(MR_Integer) nnnn" so the
integer constant is converted to a signed MR_Integer before negation.

After this fix we no longer get these warnings from gcc:
"this decimal constant is unsigned only in ISO C90".
It turns out gcc was trying to tell us something.

compiler/c_util.m:
	Add predicate `output_int_expr' to write ints in a way that
	avoids the problem.

compiler/llds_out_data.m:
compiler/mlds_to_c.m:
	Use `output_int_expr' to write ints.

tests/hard_coded/Mmakefile:
tests/hard_coded/c89_neg_int.exp:
tests/hard_coded/c89_neg_int.m:
	Add test case.
2015-09-03 13:54:16 +10:00

28 lines
671 B
Mathematica

%---------------------------------------------------------------------------%
% vim: ts=4 sw=4 et ft=mercury
%---------------------------------------------------------------------------%
:- module c89_neg_int.
:- interface.
:- import_module io.
:- pred main(io::di, io::uo) is det.
:- implementation.
main(!IO) :-
show(-2147483647, !IO),
show(-2147483648, !IO),
% Disabled as they will be rejected by a compiler with 32-bit ints.
% show(-2147483649, !IO),
% show(-9223372036854775807, !IO),
% show(-9223372036854775808, !IO),
true.
:- pred show(int::in, io::di, io::uo) is det.
show(N, !IO) :-
io.write_int(N, !IO),
io.nl(!IO).