From c66586651796027f2f0ecb555af894f1de84be3d Mon Sep 17 00:00:00 2001 From: nickysn Date: Tue, 27 Mar 2018 16:15:06 +0000 Subject: [PATCH] + introduce the tcnf_proc_2_procvar_2_voidpointer flag (for now it is only set, but not used) git-svn-id: trunk@38638 - --- compiler/i8086/n8086inl.pas | 10 +++++++--- compiler/ncnv.pas | 11 ++++++++--- compiler/nmem.pas | 10 +++++++--- 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/compiler/i8086/n8086inl.pas b/compiler/i8086/n8086inl.pas index f383a08abf..66a850dc08 100644 --- a/compiler/i8086/n8086inl.pas +++ b/compiler/i8086/n8086inl.pas @@ -104,7 +104,7 @@ implementation function ti8086inlinenode.typecheck_seg: tnode; var - isprocvar: Boolean; + isprocvar,need_conv_to_voidptr: Boolean; procpointertype: tdef; hsym: tfieldvarsym; begin @@ -131,12 +131,17 @@ implementation ) then begin isprocvar:=(left.resultdef.typ=procvardef); + need_conv_to_voidptr:= + (m_tp_procvar in current_settings.modeswitches) or + (m_mac_procvar in current_settings.modeswitches); if not isprocvar then begin if current_settings.x86memorymodel in x86_far_code_models then begin left:=ctypeconvnode.create_proc_to_procvar(left); + if need_conv_to_voidptr then + include(ttypeconvnode(left).convnodeflags,tcnf_proc_2_procvar_2_voidpointer); left.fileinfo:=fileinfo; typecheckpass(left); end @@ -145,8 +150,7 @@ implementation end; { In tp procvar mode for methodpointers we need to load the proc field } - if (m_tp_procvar in current_settings.modeswitches) or - (m_mac_procvar in current_settings.modeswitches) then + if need_conv_to_voidptr then begin if not tabstractprocdef(left.resultdef).is_addressonly then begin diff --git a/compiler/ncnv.pas b/compiler/ncnv.pas index 623854d173..da74becdae 100644 --- a/compiler/ncnv.pas +++ b/compiler/ncnv.pas @@ -34,9 +34,14 @@ interface type ttypeconvnodeflag = ( - tcnf_dummyflag { todo: remove this, when the first real typeconvnode - flag is added (this is just a dummy element, because - the enum cannot be empty) } + { the typeconvnode is a proc_2_procvar, generated internally by an + address operator, such as @proc, Addr(proc), Ofs(proc) or Seg(proc), + which is then going to be converted to a void pointer. Why does it + matter? Because, on i8086 far code memory models you're allowed to + take the address of a _near_ procedure as a void pointer (which the + @ operator does in TP mode), but not as a procvar (in that case the + procedure must be far). } + tcnf_proc_2_procvar_2_voidpointer ); ttypeconvnodeflags = set of ttypeconvnodeflag; diff --git a/compiler/nmem.pas b/compiler/nmem.pas index 9fb5180384..1c1632b8c7 100644 --- a/compiler/nmem.pas +++ b/compiler/nmem.pas @@ -486,7 +486,7 @@ implementation var hp : tnode; hsym : tfieldvarsym; - isprocvar : boolean; + isprocvar,need_conv_to_voidptr: boolean; procpointertype: tdef; begin result:=nil; @@ -521,10 +521,15 @@ implementation ) then begin isprocvar:=(left.resultdef.typ=procvardef); + need_conv_to_voidptr:= + (m_tp_procvar in current_settings.modeswitches) or + (m_mac_procvar in current_settings.modeswitches); if not isprocvar then begin left:=ctypeconvnode.create_proc_to_procvar(left); + if need_conv_to_voidptr then + include(ttypeconvnode(left).convnodeflags,tcnf_proc_2_procvar_2_voidpointer); left.fileinfo:=fileinfo; typecheckpass(left); end; @@ -532,8 +537,7 @@ implementation { In tp procvar mode the result is always a voidpointer. Insert a typeconversion to voidpointer. For methodpointers we need to load the proc field } - if (m_tp_procvar in current_settings.modeswitches) or - (m_mac_procvar in current_settings.modeswitches) then + if need_conv_to_voidptr then begin if tabstractprocdef(left.resultdef).is_addressonly then begin