Emil Jerabek wrote:
After reading this message, I tried to experiment with set types a little bit. It turned out that the compiler segfaults on "set of Void" (this is a nonsense type, but anyway...)
GPC accepts "array of Void" (and even static variables of that type; should it?), but it crashes on "packed array of Void". More importantly, it crashes the same way on the following ISO 7185 code:
[...]
A similar file-type generates a run-time error:
Thanks for the reports. All fixed now (emil{12,13[a-c],14,15}.pas).
Frank
Sorry, should think twice before submitting a bugreport. The story with "file of record end" is more complicated then I wrote.
The test below should pass for any type (which is permissible as a file component-type, of course). It indeed works with, say, "file of Integer", but with the empty record type it fails:
[pas]% gpc -v Reading specs from /usr/local/lib/gcc-lib/i586-pc-linux-gnu/2.95.2/specs gpc version 20020318, based on 2.95.2 19991024 (release) [pas]% gpc recordend3.pas [pas]% ./a.out failed 1: (end) ... EOF = False zsh: floating point exception (core dumped) ./a.out
Apparently, the RTS doesn't track the length and current position of file variables, and tries to compute them from the byte-size of the file when needed. This is wrong for "file of record end" and similar beasts, because
(i) it makes EOF always return False (in Inspection mode, at least)
(ii) most direct access functions raise a "division by zero" signal
Here's the code of recordend3.pas:
----------- program FileTest (Output); {$macros}
const MaxLen = 100; Len = 42; TestPos = 13;
type EmptyType = record end;
var F: file of EmptyType; G: file [1 .. MaxLen] of EmptyType; I: Integer; OK: Boolean value True;
{$define Fail(Pass, Pos, Func, Result) begin WriteLn ('failed ', Pass, ': ', Pos : 5, ' ... ', Func, ' = ', Result); OK := False end }
begin Rewrite (F); for I := 1 to Len do begin if not EOF (F) then Fail (0, I, 'EOF', False); Put (F) end;
Reset (F); for I := 1 to Len do begin if EOF (F) then Fail (1, I, 'EOF', True); Get (F) end; if not EOF (F) then Fail (1, '(end)', 'EOF', False);
Rewrite (G); for I := 1 to Len do begin if not EOF (G) then Fail (2, I, 'EOF', False); if Position (G) <> I then Fail (2, I, 'Position', Position (G)); Put (G); if LastPosition (G) <> I then Fail (2, I, 'LastPosition', LastPosition (G)) end;
Reset (G); for I := 1 to Len do begin if EOF (G) then Fail (3, I, 'EOF', True); if Position (G) <> I then Fail (3, I, 'Position', Position (G)); Get (G) end; if not EOF (G) then Fail (3, '(end)', 'EOF', False);
if Empty (G) then Fail (3, '(end)', 'Empty', True);
SeekUpdate (G, TestPos); Update (G); if EOF (G) then Fail (4, TestPos, 'EOF', True); if Position (G) <> TestPos then Fail (4, TestPos, 'Position', Position (G)); if LastPosition (G) <> Len then Fail (4, TestPos, 'LastPosition', LastPosition (G));
if OK then WriteLn ('OK') end. ----------------------
Emil Jerabek