Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2011-12

Fatal: Internal error 200109227... and some boolean questions

2 messages · 1 person · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Bernd

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?

Reply by email