[fpc-pascal]Compiler Bug--ansistrings

Mark Emerson ChiefAngel at angelbase.com
Sat Apr 26 05:31:49 CEST 2003


I found the following compiler bug involving ansistrings, running FPC
under Linux.  The program is called bug, and it references a unit called
bug_unit.  Both appear below.

The bug_unit contains a couple of "irrelevant" declarations that remain
after I removed masses of stuff to  narrow down the bug.  More on them below.

Note that procedure test in the unit is identical to procedure test1 in
the program, except for its name.  Note also that BOTH procedures
involve appending a null character to an ansistring.

Now, as you will see, appending the null character WORKS in test1, but
causes a runtime error (216) in the unit.

If chr(0) is changed to any other char, such as chr(1), in the unit, the
program runs successfully.

Alternatively, if chr(0) is KEPT in the unit, but instead the
"irrelevant" procedure called tab_delim_escapes_to_chars is commented
out, then, once again, the program runs successfully.

We are currently having a far more difficult problem with ansistrings,
but I'm not in a position to report it yet, as it involves masses of code.

I LOVE this compiler.  Please fix it!  :)

Mark Emerson
http://angelbase.com/pascal/


program bug;

uses bug_unit;

var s : ansistring;

function test1 (item : ansistring) : ansistring;
	begin
		WRITELN ('TEST1 ITEM=', ITEM);
		TEST1 := item + chr(0);
	end;

begin
	writeln (test1 ('abc'));
	writeln (test ('abc'));
end.



unit bug_unit;

interface

function test (item : ansistring) : ansistring;

{=== Miscellaneous stuff ===}

type
   char_set_type = set of char;
   natural = cardinal;

const
   endsource_char = chr(255);
   tab_delim_char_codes = [9, 10, 13];
   letters_set_const = ['A'..'Z', 'a'..'z'];
   digits_set_const = ['0'..'9'];
   white_space_set_const = [' ', chr(9), chr(10), chr(13)];
   CRLF = chr(13)+chr(10);



{========================}
implementation


{=== STUBS TO REMOVE ===}
procedure error (error_msg : ansistring);
	begin
		writeln ('error_msg');
		halt;
	end;

function tab_delim_escapes_to_chars (s : ansistring) : ansistring;
      {going left to right, replaces \009, \010 and \013 with
      chr(9), chr(10), and chr (13) respectively.}
   var
      esc_i : longint;
      len : natural;
      j : natural;
      esc_str : string[3];
      esc_val : word;
      got_esc : boolean;
   begin 
      len := length (s);
      if len > 3 then
         for esc_i := len-3 downto 1 do
            if s[esc_i] = '\' then begin
               esc_str := '';
               got_esc := false;
               if esc_i + 3 <= length (s) then begin
                  got_esc := true;
                  for j := esc_i + 1 to esc_i + 3 do
                     if not (s[j] in digits_set_const)
                        then got_esc := false;
                  end;
               if got_esc then begin
                  esc_str := copy (s, esc_i+1, 3);
                  val (esc_str, esc_val);
                  if esc_val in tab_delim_char_codes then
                     s := copy (s, 1, esc_i-1) + chr (esc_val) +
                           copy (s, esc_i+4, len);
                  end;
               end;
      tab_delim_escapes_to_chars := s;
   end;


function test (item : ansistring) : ansistring;
	begin
		WRITELN ('TEST ITEM=', ITEM);
		TEST := item + chr(0);  
	end;

end.



More information about the fpc-pascal mailing list