Browse Source

* don't make copies of arrays passed as value parameters to cdecl routines
(since C compilers don't copy such arrays either, as they're implciitly
pointers)

git-svn-id: trunk@29871 -

Jonas Maebe 10 years ago
parent
commit
6e12ad817f
4 changed files with 15 additions and 6 deletions
  1. 4 2
      compiler/hlcgobj.pas
  2. 2 0
      compiler/ncal.pas
  3. 4 2
      compiler/ncgutil.pas
  4. 5 2
      compiler/pparautl.pas

+ 4 - 2
compiler/hlcgobj.pas

@@ -4692,8 +4692,10 @@ implementation
     begin
     begin
       list:=TAsmList(arg);
       list:=TAsmList(arg);
       if (tsym(p).typ=paravarsym) and
       if (tsym(p).typ=paravarsym) and
-         (tparavarsym(p).varspez=vs_value) and
-        (paramanager.push_addr_param(tparavarsym(p).varspez,tparavarsym(p).vardef,current_procinfo.procdef.proccalloption)) then
+         ((vo_has_local_copy in tparavarsym(p).varoptions) or
+          ((is_open_array(tparavarsym(p).vardef) or
+            is_array_of_const(tparavarsym(p).vardef)) and
+           (tparavarsym(p).varspez=vs_value))) then
         begin
         begin
           { we have no idea about the alignment at the caller side }
           { we have no idea about the alignment at the caller side }
           location_get_data_ref(list,tparavarsym(p).vardef,tparavarsym(p).initialloc,href,true,1);
           location_get_data_ref(list,tparavarsym(p).vardef,tparavarsym(p).initialloc,href,true,1);

+ 2 - 0
compiler/ncal.pas

@@ -949,6 +949,8 @@ implementation
              (parasym.varspez=vs_value)) or
              (parasym.varspez=vs_value)) or
             (cpf_varargs_para in callparaflags)) and
             (cpf_varargs_para in callparaflags)) and
            (left.nodetype<>nothingn) and
            (left.nodetype<>nothingn) and
+           (not(aktcallnode.procdefinition.proccalloption in cdecl_pocalls) or
+            (left.resultdef.typ<>arraydef)) and
            paramanager.push_addr_param(vs_value,left.resultdef,
            paramanager.push_addr_param(vs_value,left.resultdef,
                       aktcallnode.procdefinition.proccalloption) then
                       aktcallnode.procdefinition.proccalloption) then
           copy_value_by_ref_para;
           copy_value_by_ref_para;

+ 4 - 2
compiler/ncgutil.pas

@@ -610,8 +610,10 @@ implementation
       begin
       begin
         list:=TAsmList(arg);
         list:=TAsmList(arg);
         if (tsym(p).typ=paravarsym) and
         if (tsym(p).typ=paravarsym) and
-           (tparavarsym(p).varspez=vs_value) and
-          (paramanager.push_addr_param(tparavarsym(p).varspez,tparavarsym(p).vardef,current_procinfo.procdef.proccalloption)) then
+           ((vo_has_local_copy in tparavarsym(p).varoptions) or
+            ((is_open_array(tparavarsym(p).vardef) or
+              is_array_of_const(tparavarsym(p).vardef)) and
+             (tparavarsym(p).varspez=vs_value))) then
           begin
           begin
             { we have no idea about the alignment at the caller side }
             { we have no idea about the alignment at the caller side }
             hlcg.location_get_data_ref(list,tparavarsym(p).vardef,tparavarsym(p).initialloc,href,true,1);
             hlcg.location_get_data_ref(list,tparavarsym(p).vardef,tparavarsym(p).initialloc,href,true,1);

+ 5 - 2
compiler/pparautl.pas

@@ -331,12 +331,15 @@ implementation
            { We need a local copy for a value parameter when only the
            { We need a local copy for a value parameter when only the
              address is pushed. Open arrays and Array of Const are
              address is pushed. Open arrays and Array of Const are
              an exception because they are allocated at runtime and the
              an exception because they are allocated at runtime and the
-             address that is pushed is patched }
+             address that is pushed is patched. Arrays passed to cdecl routines
+             also because arrays are treated like pointers in C. }
            if (varspez=vs_value) and
            if (varspez=vs_value) and
               paramanager.push_addr_param(varspez,vardef,pd.proccalloption) and
               paramanager.push_addr_param(varspez,vardef,pd.proccalloption) and
               not(is_open_array(vardef) or
               not(is_open_array(vardef) or
                   is_array_of_const(vardef)) and
                   is_array_of_const(vardef)) and
-              not(target_info.system in systems_caller_copy_addr_value_para) then
+              not(target_info.system in systems_caller_copy_addr_value_para) and
+              (not(pd.proccalloption in cdecl_pocalls) or
+               (vardef.typ<>arraydef)) then
              include(varoptions,vo_has_local_copy);
              include(varoptions,vo_has_local_copy);
 
 
            { needs high parameter ? }
            { needs high parameter ? }