Просмотр исходного кода

* 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 лет назад
Родитель
Сommit
6e12ad817f
4 измененных файлов с 15 добавлено и 6 удалено
  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
       list:=TAsmList(arg);
       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
           { 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);

+ 2 - 0
compiler/ncal.pas

@@ -949,6 +949,8 @@ implementation
              (parasym.varspez=vs_value)) or
             (cpf_varargs_para in callparaflags)) 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,
                       aktcallnode.procdefinition.proccalloption) then
           copy_value_by_ref_para;

+ 4 - 2
compiler/ncgutil.pas

@@ -610,8 +610,10 @@ implementation
       begin
         list:=TAsmList(arg);
         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
             { 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);

+ 5 - 2
compiler/pparautl.pas

@@ -331,12 +331,15 @@ implementation
            { We need a local copy for a value parameter when only the
              address is pushed. Open arrays and Array of Const are
              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
               paramanager.push_addr_param(varspez,vardef,pd.proccalloption) and
               not(is_open_array(vardef) or
                   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);
 
            { needs high parameter ? }