[fpc-pascal] Fatal: Internal error 200109227... and some boolean questions
Bernd
prof7bit at googlemail.com
Wed Dec 7 20:42:55 CET 2011
Linux/i386, 2_6 branch
var
a : QWord;
x : QWordBool;
y : QWordBool;
begin
a := QWord($ffff000000000000);
x := QWordBool(a);
y := not x;
fpwinglet.lpr(21,3) Fatal: Internal error 200109227
(Line 21 is the line y := not x)
I stumbled over this while I was experimenting with finding out how to
convert/cast a QWord directly into a boolean (to use it with if and
while) without having to write (a <> 0). The following does not work:
if Boolean(a) then
...
Here the generated code will only check the lowest 8 bit.
I made some experiments:
var
a : QWord;
x : QWordBool;
y : QWordBool;
begin
a := QWord($ffff000000000000);
0x80480d5 mov $0x0,%eax
0x80480da mov $0xffff0000,%edx
x := QWordBool(a);
0x80480df mov %eax,(%esp)
0x80480e2 mov (%esp),%edi // lower dword in edi
0x80480e5 mov %edx,%esi // higher dword in esi
// y := not x;
y := False;
writeln(x);
0x80480e7 call 0x805ebf0 <fpc_get_output>
0x80480ec mov %edi,%edx // writeln will correctly print TRUE because
0x80480ee or %esi,%edx // it does OR both dwords into one!
0x80480f0 setne %dl
0x80480f3 mov %dl,%cl
0x80480f5 mov %eax,%esi
0x80480f7 mov %esi,%edx
0x80480f9 mov $0x0,%eax
0x80480fe call 0x805fc80 <fpc_write_text_boolean>
0x8048103 call 0x805a9d0 <fpc_iocheck>
0x8048108 mov %esi,%eax
0x804810a call 0x805ed70 <fpc_writeln_end>
0x804810f call 0x805a9d0 <fpc_iocheck>
writeln(y);
if Boolean(a) then
0x8048143 mov (%esp),%al
0x8048146 test %al,%al // only the lowest 8 bit
0x8048148 je 0x8048173 <main+211>
writeln('if Boolean(a)');
// x is a QWordBool
if x then
0x8048173 test %edi,%edi // Here I would expected to test all 64 bit
0x8048175 je 0x80481a0 <main+256>
writeln('if x');
// and here the NOT x does *not* produce a compiler error!
if not x then
0x80481a0 test %edi,%edi // but still only lower half of x is tested.
0x80481a2 jne 0x80481cd <main+301>
writeln('if not x');
if y then
0x80481cd mov 0x4(%esp),%eax
0x80481d1 test %eax,%eax
0x80481d3 je 0x80481fe <main+350>
writeln('if y');
This program outputs:
TRUE
FALSE
if not x
(writeln prints TRUE but the IF turns out false.)
shouldn't the compiler at least emit a warning when trying to cast
something bigger than a byte into a boolean? and shouldn't IF (and
also While) respect all 64 bits of a QWordBool? AFAIK True is defined
by anything <> 0, isn't it?
More information about the fpc-pascal
mailing list