Pārlūkot izejas kodu

+ introduce the tcnf_proc_2_procvar_2_voidpointer flag (for now it is only set,
but not used)

git-svn-id: trunk@38638 -

nickysn 7 gadi atpakaļ
vecāks
revīzija
c665866517
3 mainītis faili ar 22 papildinājumiem un 9 dzēšanām
  1. 7 3
      compiler/i8086/n8086inl.pas
  2. 8 3
      compiler/ncnv.pas
  3. 7 3
      compiler/nmem.pas

+ 7 - 3
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

+ 8 - 3
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;
 

+ 7 - 3
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