* New is_cyclic function to detect if def references itself - fixes #40010

This commit is contained in:
J. Gareth "Curious Kit" Moreton 2022-12-03 19:21:38 +00:00
parent 42d91c02bd
commit f00a932cc6
2 changed files with 41 additions and 0 deletions

View File

@ -1315,6 +1315,7 @@ implementation
end
else
if is_zero_based_array(def_to) and
not is_cyclic(def_from) and
equal_defs(tpointerdef(def_from).pointeddef,tarraydef(def_to).elementdef) then
begin
doconv:=tc_pointer_2_array;

View File

@ -229,6 +229,9 @@ interface
{# Returns true if p is a voidpointer def }
function is_voidpointer(p : tdef) : boolean;
{# Returns true if p is a cyclic reference (refers to itself at some point via pointer or array) }
function is_cyclic(p : tdef): Boolean;
{# Returns true, if definition is a float }
function is_fpu(def : tdef) : boolean;
@ -1030,6 +1033,43 @@ implementation
end;
{ true, if p is a cyclic reference (refers to itself at some point via pointer or array) }
function is_cyclic(p : tdef): Boolean;
var
DefList: array of TDef;
CurrentTop: Integer;
function is_cyclic_internal(def: tdef): Boolean;
var
X: Integer;
begin
if not (def.typ in [arraydef, pointerdef]) then
Exit(False);
CurrentTop := Length(DefList);
{ Check to see if the definition has appeared already }
for X := 0 to CurrentTop - 1 do
if def = DefList[X] then
Exit(True);
SetLength(DefList, CurrentTop + 1);
DefList[CurrentTop] := def;
case def.typ of
arraydef:
Result := is_cyclic_internal(tarraydef(def).elementdef);
pointerdef:
Result := is_cyclic_internal(tabstractpointerdef(def).pointeddef);
else
InternalError(2022120301);
end;
end;
begin
Result := is_cyclic_internal(p);
end;
{ true, if def is a 8 bit int type }
function is_8bitint(def : tdef) : boolean;
begin