Emil Jerabek wrote:
TEST baby.pas: ./a.out: value out of range (error #300 at 804d70a)
Which means:
The patch works.
Failures of awindtes* and dostest* also went away.
As for baby.pas: I found meanwhile that it is the same problem which
I reported in another mail, i.e., inability to allocate more than about 128kB of memory. The offending range check happens after the increment in AddHeapRange in rts/heap.pas:
procedure AddHeapRange (p: Pointer; Size: SizeType); var Address: PtrCard; begin Address := PtrCard (p); if (HeapLow = 0) or (Address < HeapLow) then HeapLow := Address; Inc (Address, Size - 1);
^^^^
if Address > HeapHigh then HeapHigh := Address end;
Disassembling the code reveals:
0x0804ef0f <AddHeapRange+31>: lea 0xffffffff(%eax,%edx,1),%eax 0x0804ef13 <AddHeapRange+35>: test %eax,%eax 0x0804ef15 <AddHeapRange+37>: js 0x804ef26 <AddHeapRange+54> ^^^^^^
Unfortunatly, this is correct translation of the above line according to current rules: 1 is of type integer (so it is considerd signed). Currently substractiong or adding Integer to Carginal gives Integer (same precision, signed result), so substracting 1 from size give result of type Integer. Also (Size - 1) to Address gives signed result. Since Address is unsigned range checking kicks in: it considers negative result illegal.
Somewhat similar problems hit on AMD64, but this one is worse. We were discussing privatly with Frank rules for choosing result type of arithmetic operations. This particular case can be easily fixed by making type rules slightly smarter (it is not much effort to realize that 1 do not need sign), but it is large effort to make RTS work with range checking and without using excess precision.