gpc bug?

Miguel Lobo luislm at mundivia.es
Sun Dec 13 01:08:54 CET 1998


I wrote a week ago about some 'Internal compiler error' message.
Unfortunately I was using gpc 2.0 and, as Peter Gerwinsky pointed,
that was the cause of the error; I downloaded gpc-19981124 from
debian.org and now that bug has disappeared.

I am glad to see that the compiler is now much better (although
compiling a file with errors often causes strange messages), but
I think that I might have found a new bug. The problem arises
when calling a destructor inside a dispose statement. I send a program
which manifests the problem attached to this message.

Specifically, when the list.done method is called, it should dispose
all the items in the list by calling their 'done' destructor. But
apparently sometimes this does not happen. When I run the program
I get:

descend-init: 1
descend-init: 2
descend-init: 3
descend-init: 4
extracting: descend: 1
descend-done: 1
extracting: descend: 2
extracting: descend: 3
descend-done: 3
extracting: descend: 4

So items 2 and 4 are not freed (or at least their destructors are not
called). Changing the line "dispose(extfirst, done);"
to "item :=extfirst; dispose(item,done);" solves the problem. I have
checked the program in Borland Pascal and it works, so I think is a GPC
bug.

BTW, although I plan to join the mailing list in the future I haven't
done so yet, so please mail me any answer. Thank you.
-------------- next part --------------
type
  pitem = ^item;
  item =
    object
      prev,next: pitem;
      constructor init;
      destructor done; virtual;
      procedure write; virtual;
    end;

  pdescend = ^descend;
  descend =
    object(item)
      i: integer;
      constructor init(ii: integer);
      destructor done; virtual;
      procedure write; virtual;
    end;

  plist = ^list;
  list =
    object
      first,last: pitem;
      constructor init;
      destructor done;
      function extfirst: pitem;
      procedure add(l: pitem);
      procedure adddesc(i: integer);
    end;

constructor item.init;
begin
  prev :=nil;
  next :=nil;
end;

destructor item.done;
begin
end;

procedure item.write;
begin
  writeln('item');
end;

constructor descend.init(ii: integer);
begin
  inherited init;
  i :=ii;
  writeln('descend-init: ',i);
end;

destructor descend.done;
begin
  writeln('descend-done: ',i);
  inherited done;
end;

procedure descend.write;
begin
  writeln('descend: ',i);
end;

constructor list.init;
begin
  first :=nil; last :=nil;
end;

destructor list.done;
begin
  while (first<>nil) do
    dispose(extfirst,done);
end;

function list.extfirst: pitem;
var
  item: pitem;
begin
  write('extracting: '); first^.write;
  extfirst :=first;
  if (first=nil) then exit;
  item :=first; first :=first^.next; item^.next :=nil;
  if (first<>nil) then first^.prev :=nil
  else last :=nil;
end;

procedure list.add(l: pitem);
begin
  if (first=nil) then first :=l
  else last^.next :=l;
  l^.prev :=last; last :=l;
end;

procedure list.adddesc(i: integer);
begin
  add(new(pdescend,init(i)));
end;

var
  alist: plist;

begin
  new(alist,init);
  alist^.adddesc(1);
  alist^.adddesc(2);
  alist^.adddesc(3);
  alist^.adddesc(4);
  dispose(alist,done);
end.


More information about the Gpc mailing list