hand source: TObjectList takes strong refs to stored objects

The hand-written self-hosting TObjectList stored bare Pointers and
took no ARC ref when adding.  In loops like

    while Check(tkIdent) do
    begin
      CD := TConstDecl.Create;
      ...
      ABlock.ConstDecls.Add(CD);
    end;

reassigning CD on the next iteration released the prior CD (its only
strong ref) and the list's pointer dangled.  When a later allocation
reused that heap slot, the list silently contained the wrong object,
and semantic analysis crashed in TSymbol.Create reading CD.Name from
an unrelated object's memory.

Add/Put/Delete/Clear/Destroy now AddRef on insert and Release on
remove or destroy, gated on FOwnsObjects so the semantics match the
real compiler's TObjectList.  Extract continues to transfer the ref
to the caller without release.

Lets stage-2 compile the hand source far enough to hit the next bug
(currently a nil Self in TRecordTypeDesc.AddVTableSlot during
AnalyseTypeDecls) — more hand-source polish to follow.
This commit is contained in:
Graeme Geldenhuys 2026-04-24 17:59:21 +01:00
parent 4797ce71a9
commit 5907e1d314

View file

@ -242,7 +242,20 @@ begin
end;
procedure TObjectList.Destroy;
var
I: Integer;
Src: ^Pointer;
begin
if Self.FOwnsObjects then
begin
I := 0;
while I < Self.FCount do
begin
Src := Self.FData + I * SizeOf(Pointer);
_ClassRelease(Src^);
I := I + 1
end
end;
FreeMem(Self.FData);
Self.FData := nil;
Self.FCount := 0;
@ -257,6 +270,7 @@ begin
Self.Grow;
Dest := Self.FData + Self.FCount * SizeOf(Pointer);
Dest^ := AObject;
_ClassAddRef(AObject);
Self.FCount := Self.FCount + 1;
Result := Self.FCount - 1
end;
@ -274,6 +288,9 @@ var
Dest: ^Pointer;
begin
Dest := Self.FData + AIndex * SizeOf(Pointer);
_ClassAddRef(AObject);
if Self.FOwnsObjects then
_ClassRelease(Dest^);
Dest^ := AObject
end;
@ -302,6 +319,11 @@ var
Dst: ^Pointer;
Src: ^Pointer;
begin
if Self.FOwnsObjects then
begin
Src := Self.FData + AIndex * SizeOf(Pointer);
_ClassRelease(Src^);
end;
I := AIndex;
while I < Self.FCount - 1 do
begin
@ -314,7 +336,20 @@ begin
end;
procedure TObjectList.Clear;
var
I: Integer;
Src: ^Pointer;
begin
if Self.FOwnsObjects then
begin
I := 0;
while I < Self.FCount do
begin
Src := Self.FData + I * SizeOf(Pointer);
_ClassRelease(Src^);
I := I + 1
end
end;
Self.FCount := 0
end;