[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