From e746cf96daffc2365178a934dcd1eb28ac955f4c Mon Sep 17 00:00:00 2001 From: Jonas Maebe Date: Sat, 10 Sep 2022 10:49:54 +0200 Subject: [PATCH] Overload selection: call procvars if result is compatible with parameter Previously we only autmatically called procvars without parameters in TP/Delphi modes if their result type was equal to the parameter type to which they were passed. Resolves #39748. --- compiler/htypechk.pas | 34 +++++++++++++++++----------------- tests/webtbs/tw39748.pp | 18 ++++++++++++++++++ tests/webtbs/tw39748a.pp | 27 +++++++++++++++++++++++++++ 3 files changed, 62 insertions(+), 17 deletions(-) create mode 100644 tests/webtbs/tw39748.pp create mode 100644 tests/webtbs/tw39748a.pp diff --git a/compiler/htypechk.pas b/compiler/htypechk.pas index 10317ac598..55f482eac4 100644 --- a/compiler/htypechk.pas +++ b/compiler/htypechk.pas @@ -2960,23 +2960,23 @@ implementation { Convert tp procvars when not expecting a procvar } if (currpt.left.resultdef.typ=procvardef) and not(def_to.typ in [procvardef,formaldef]) and - { Only convert to call when there is no overload or the return type - is equal to the expected type. } - ( - (count=1) or - equal_defs(tprocvardef(currpt.left.resultdef).returndef,def_to) - ) and - { and if it doesn't require any parameters } - (tprocvardef(currpt.left.resultdef).minparacount=0) then - begin - releasecurrpt:=true; - currpt:=tcallparanode(pt.getcopy); - if maybe_call_procvar(currpt.left,true) then - begin - currpt.resultdef:=currpt.left.resultdef; - def_from:=currpt.left.resultdef; - end; - end; + { if it doesn't require any parameters } + (tprocvardef(currpt.left.resultdef).minparacount=0) and + { Only convert to call when there is no overload or the return type + is compatible with the expected type. } + ( + (count=1) or + (compare_defs_ext(tprocvardef(currpt.left.resultdef).returndef,def_to,nothingn,convtype,pdoper,[])>te_incompatible) + ) then + begin + releasecurrpt:=true; + currpt:=tcallparanode(pt.getcopy); + if maybe_call_procvar(currpt.left,true) then + begin + currpt.resultdef:=currpt.left.resultdef; + def_from:=currpt.left.resultdef; + end; + end; { If we expect a procvar and the left is loadnode that returns a procdef we need to find the correct overloaded diff --git a/tests/webtbs/tw39748.pp b/tests/webtbs/tw39748.pp new file mode 100644 index 0000000000..057491f610 --- /dev/null +++ b/tests/webtbs/tw39748.pp @@ -0,0 +1,18 @@ +{$mode delphi} +uses + sysutils; +type + glenum=word; + TglGetError = function(): GLenum; cdecl; + +function test: glenum; cdecl; +begin + result:=42; +end; + +var glgeterror : TGlGeterror; +begin + glgeterror:=test; + if inttostr(glgeterror)<>'42' then + halt(1); +end. diff --git a/tests/webtbs/tw39748a.pp b/tests/webtbs/tw39748a.pp new file mode 100644 index 0000000000..d154937ab0 --- /dev/null +++ b/tests/webtbs/tw39748a.pp @@ -0,0 +1,27 @@ +{$mode delphi} +type + glenum=word; + TglGetError = function(): GLenum; cdecl; + +function test: glenum; cdecl; +begin + result:=42; +end; + +procedure call(e: longint); overload; +begin + writeln('longint'); + halt(1); +end; + +procedure call(p :tglgeterror); overload; +begin + writeln('procvar'); +end; + +var glgeterror : TGlGeterror; +begin + glgeterror:=test; + call(glgeterror) +end. +