소스 검색

* 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 년 전
부모
커밋
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
     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 ? }