diff --git a/compiler/defutil.pas b/compiler/defutil.pas index 792c5a26e4..7efe9d130b 100644 --- a/compiler/defutil.pas +++ b/compiler/defutil.pas @@ -127,6 +127,9 @@ interface { # Returns whether def is needs to load RTTI for reference counting } function is_rtti_managed_type(def: tdef) : boolean; + {# Returns whether def is an undefined generic type, is an array of such, or points to such } + function is_undefined(p: tdef) : boolean; + { function is_in_limit_value(val_from:TConstExprInt;def_from,def_to : tdef) : boolean;} {***************************************************************************** @@ -844,6 +847,33 @@ implementation end; + function is_undefined(p: tdef): boolean; + + function is_undefined_recursive(def: tdef): Boolean; + begin + case def.typ of + undefineddef: + Result := True; + arraydef: + Result := is_undefined_recursive(tarraydef(def).elementdef); + pointerdef: + Result := is_undefined_recursive(tabstractpointerdef(def).pointeddef); + else + Result := False; + end; + end; + + begin + { If a definition is a cycle of pointers or arrays, it's not undefined, + but we need to avoid a stack overflow } + if is_cyclic(p) then + Exit(False); + + result := is_undefined_recursive(p); + end; + + + { true, if p points to an open array def } function is_open_string(p : tdef) : boolean; begin diff --git a/compiler/ncal.pas b/compiler/ncal.pas index 452d3569ff..4d8233d955 100644 --- a/compiler/ncal.pas +++ b/compiler/ncal.pas @@ -3953,18 +3953,6 @@ implementation function tcallnode.pass_typecheck:tnode; - - function is_undefined_recursive(def:tdef):boolean; - begin - { might become more refined in the future } - if def.typ=undefineddef then - result:=true - else if def.typ=arraydef then - result:=is_undefined_recursive(tarraydef(def).elementdef) - else - result:=false; - end; - var candidates : tcallcandidates; ccflags : tcallcandidatesflags; @@ -4201,7 +4189,7 @@ implementation pt:=tcallparanode(left); while assigned(pt) do begin - if is_undefined_recursive(pt.resultdef) then + if is_undefined(pt.resultdef) then begin ignoregenericparacall:=true; break;