浏览代码

* fixed memory leaks in the compiler introduced in r21862 by marking and
releasing temporarily created function result locations

git-svn-id: trunk@21953 -

Jonas Maebe 13 年之前
父节点
当前提交
0a1157da38

+ 4 - 11
compiler/arm/cpupara.pas

@@ -42,12 +42,11 @@ unit cpupara;
           procedure getintparaloc(calloption : tproccalloption; nr : longint; def : tdef; var cgpara : tcgpara);override;
           procedure getintparaloc(calloption : tproccalloption; nr : longint; def : tdef; var cgpara : tcgpara);override;
           function create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;override;
           function create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;override;
           function create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargsparalist):longint;override;
           function create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargsparalist):longint;override;
-          function get_funcretloc(p : tabstractprocdef; side: tcallercallee; def: tdef): tcgpara;override;
+          function get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): tcgpara;override;
          private
          private
           procedure init_values(var curintreg, curfloatreg, curmmreg: tsuperregister; var cur_stack_offset: aword; var sparesinglereg: tregister);
           procedure init_values(var curintreg, curfloatreg, curmmreg: tsuperregister; var cur_stack_offset: aword; var sparesinglereg: tregister);
           function create_paraloc_info_intern(p : tabstractprocdef; side: tcallercallee; paras: tparalist;
           function create_paraloc_info_intern(p : tabstractprocdef; side: tcallercallee; paras: tparalist;
             var curintreg, curfloatreg, curmmreg: tsuperregister; var cur_stack_offset: aword; var sparesinglereg: tregister; isvariadic: boolean):longint;
             var curintreg, curfloatreg, curmmreg: tsuperregister; var cur_stack_offset: aword; var sparesinglereg: tregister; isvariadic: boolean):longint;
-          procedure create_funcretloc_info(p : tabstractprocdef; side: tcallercallee);
        end;
        end;
 
 
   implementation
   implementation
@@ -576,23 +575,17 @@ unit cpupara;
       end;
       end;
 
 
 
 
-    procedure tarmparamanager.create_funcretloc_info(p : tabstractprocdef; side: tcallercallee);
-      begin
-        p.funcretloc[side]:=get_funcretloc(p,side,p.returndef);
-      end;
-
-
-    function  tarmparamanager.get_funcretloc(p : tabstractprocdef; side: tcallercallee; def: tdef): tcgpara;
+    function  tarmparamanager.get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): tcgpara;
       var
       var
         paraloc : pcgparalocation;
         paraloc : pcgparalocation;
         retcgsize  : tcgsize;
         retcgsize  : tcgsize;
       begin
       begin
-         if set_common_funcretloc_info(p,def,retcgsize,result) then
+         if set_common_funcretloc_info(p,forcetempdef,retcgsize,result) then
            exit;
            exit;
 
 
         paraloc:=result.add_location;
         paraloc:=result.add_location;
         { Return in FPU register? }
         { Return in FPU register? }
-        if def.typ=floatdef then
+        if result.def.typ=floatdef then
           begin
           begin
             if target_info.abi = abi_eabihf then 
             if target_info.abi = abi_eabihf then 
               begin
               begin

+ 4 - 11
compiler/avr/cpupara.pas

@@ -41,12 +41,11 @@ unit cpupara;
           procedure getintparaloc(calloption : tproccalloption; nr : longint; def : tdef; var cgpara : tcgpara);override;
           procedure getintparaloc(calloption : tproccalloption; nr : longint; def : tdef; var cgpara : tcgpara);override;
           function create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;override;
           function create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;override;
           function create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargsparalist):longint;override;
           function create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargsparalist):longint;override;
-          function  get_funcretloc(p : tabstractprocdef; side: tcallercallee; def: tdef): tcgpara;override;
+          function  get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): tcgpara;override;
          private
          private
           procedure init_values(var curintreg, curfloatreg, curmmreg: tsuperregister; var cur_stack_offset: aword);
           procedure init_values(var curintreg, curfloatreg, curmmreg: tsuperregister; var cur_stack_offset: aword);
           function create_paraloc_info_intern(p : tabstractprocdef; side: tcallercallee; paras: tparalist;
           function create_paraloc_info_intern(p : tabstractprocdef; side: tcallercallee; paras: tparalist;
             var curintreg, curfloatreg, curmmreg: tsuperregister; var cur_stack_offset: aword):longint;
             var curintreg, curfloatreg, curmmreg: tsuperregister; var cur_stack_offset: aword):longint;
-          procedure create_funcretloc_info(p : tabstractprocdef; side: tcallercallee);
        end;
        end;
 
 
   implementation
   implementation
@@ -403,24 +402,18 @@ unit cpupara;
      end;
      end;
 
 
 
 
-    procedure tavrparamanager.create_funcretloc_info(p : tabstractprocdef; side: tcallercallee);
-      begin
-        p.funcretloc[side]:=get_funcretloc(p,side,p.returndef);
-      end;
-
-
     { TODO : fix tavrparamanager.get_funcretloc }
     { TODO : fix tavrparamanager.get_funcretloc }
-    function  tavrparamanager.get_funcretloc(p : tabstractprocdef; side: tcallercallee; def: tdef): tcgpara;
+    function  tavrparamanager.get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): tcgpara;
       var
       var
         retcgsize : tcgsize;
         retcgsize : tcgsize;
         paraloc : pcgparalocation;
         paraloc : pcgparalocation;
       begin
       begin
-         if set_common_funcretloc_info(p,def,retcgsize,result) then
+         if set_common_funcretloc_info(p,forcetempdef,retcgsize,result) then
            exit;
            exit;
 
 
         paraloc:=result.add_location;
         paraloc:=result.add_location;
         { Return in FPU register? }
         { Return in FPU register? }
-        if def.typ=floatdef then
+        if result.def.typ=floatdef then
           begin
           begin
             if (p.proccalloption in [pocall_softfloat]) or (cs_fp_emulation in current_settings.moduleswitches) then
             if (p.proccalloption in [pocall_softfloat]) or (cs_fp_emulation in current_settings.moduleswitches) then
               begin
               begin

+ 1 - 0
compiler/hlcgobj.pas

@@ -3310,6 +3310,7 @@ implementation
       cgpara3.done;
       cgpara3.done;
       cgpara2.done;
       cgpara2.done;
       cgpara1.done;
       cgpara1.done;
+      getmemres.resetiftemp;
     end;
     end;
 
 
   procedure thlcgobj.g_releasevaluepara_openarray(list: TAsmList; arrdef: tarraydef; const l: tlocation);
   procedure thlcgobj.g_releasevaluepara_openarray(list: TAsmList; arrdef: tarraydef; const l: tlocation);

+ 21 - 16
compiler/i386/cpupara.pas

@@ -49,9 +49,8 @@ unit cpupara;
           function create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;override;
           function create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;override;
           function create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargsparalist):longint;override;
           function create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargsparalist):longint;override;
           procedure createtempparaloc(list: TAsmList;calloption : tproccalloption;parasym : tparavarsym;can_use_final_stack_loc : boolean;var cgpara:TCGPara);override;
           procedure createtempparaloc(list: TAsmList;calloption : tproccalloption;parasym : tparavarsym;can_use_final_stack_loc : boolean;var cgpara:TCGPara);override;
-          function get_funcretloc(p : tabstractprocdef; side: tcallercallee; def: tdef): TCGPara;override;
+          function get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): TCGPara;override;
        private
        private
-          procedure create_funcretloc_info(p : tabstractprocdef; side: tcallercallee);
           procedure create_stdcall_paraloc_info(p : tabstractprocdef; side: tcallercallee;paras:tparalist;var parasize:longint);
           procedure create_stdcall_paraloc_info(p : tabstractprocdef; side: tcallercallee;paras:tparalist;var parasize:longint);
           procedure create_register_paraloc_info(p : tabstractprocdef; side: tcallercallee;paras:tparalist;var parareg,parasize:longint);
           procedure create_register_paraloc_info(p : tabstractprocdef; side: tcallercallee;paras:tparalist;var parareg,parasize:longint);
        end;
        end;
@@ -310,29 +309,35 @@ unit cpupara;
       end;
       end;
 
 
 
 
-    procedure ti386paramanager.create_funcretloc_info(p : tabstractprocdef; side: tcallercallee);
-      begin
-        p.funcretloc[side]:=get_funcretloc(p,side,p.returndef);
-      end;
-
-
-    function  ti386paramanager.get_funcretloc(p : tabstractprocdef; side: tcallercallee; def: tdef): TCGPara;
+    function  ti386paramanager.get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): TCGPara;
       var
       var
         retcgsize  : tcgsize;
         retcgsize  : tcgsize;
         paraloc : pcgparalocation;
         paraloc : pcgparalocation;
         sym: tfieldvarsym;
         sym: tfieldvarsym;
+        usedef: tdef;
+        handled: boolean;
       begin
       begin
+        if not assigned(forcetempdef) then
+          usedef:=p.returndef
+        else
+          usedef:=forcetempdef;
         { on darwin/i386, if a record has only one field and that field is a
         { on darwin/i386, if a record has only one field and that field is a
           single or double, it has to be returned like a single/double }
           single or double, it has to be returned like a single/double }
         if (target_info.system in [system_i386_darwin,system_i386_iphonesim]) and
         if (target_info.system in [system_i386_darwin,system_i386_iphonesim]) and
-           ((def.typ=recorddef) or
-            is_object(def)) and
-           tabstractrecordsymtable(tabstractrecorddef(def).symtable).has_single_field(sym) and
+           ((usedef.typ=recorddef) or
+            is_object(usedef)) and
+           tabstractrecordsymtable(tabstractrecorddef(usedef).symtable).has_single_field(sym) and
            (sym.vardef.typ=floatdef) and
            (sym.vardef.typ=floatdef) and
            (tfloatdef(sym.vardef).floattype in [s32real,s64real]) then
            (tfloatdef(sym.vardef).floattype in [s32real,s64real]) then
-          def:=sym.vardef;
-
-        if set_common_funcretloc_info(p,def,retcgsize,result) then
+          usedef:=sym.vardef;
+
+        handled:=set_common_funcretloc_info(p,usedef,retcgsize,result);
+        { normally forcetempdef is passed straight through to
+          set_common_funcretloc_info and that one will correctly determine whether
+          the location is a temporary one, but that doesn't work here because we
+          sometimes have to change the type }
+        result.temporary:=assigned(forcetempdef);
+        if handled then
           exit;
           exit;
 
 
         { darwin/x86 requires that results < sizeof(aint) are sign/zero
         { darwin/x86 requires that results < sizeof(aint) are sign/zero
@@ -349,7 +354,7 @@ unit cpupara;
           end;
           end;
 
 
         { Return in FPU register? }
         { Return in FPU register? }
-        if def.typ=floatdef then
+        if result.def.typ=floatdef then
           begin
           begin
             paraloc:=result.add_location;
             paraloc:=result.add_location;
             paraloc^.loc:=LOC_FPUREGISTER;
             paraloc^.loc:=LOC_FPUREGISTER;

+ 13 - 14
compiler/jvm/cpupara.pas

@@ -45,12 +45,11 @@ interface
         procedure getintparaloc(calloption : tproccalloption; nr : longint; def : tdef; var cgpara : tcgpara);override;
         procedure getintparaloc(calloption : tproccalloption; nr : longint; def : tdef; var cgpara : tcgpara);override;
         function  create_paraloc_info(p : TAbstractProcDef; side: tcallercallee):longint;override;
         function  create_paraloc_info(p : TAbstractProcDef; side: tcallercallee):longint;override;
         function  create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargsparalist):longint;override;
         function  create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargsparalist):longint;override;
-        function  get_funcretloc(p : tabstractprocdef; side: tcallercallee; def: tdef): tcgpara;override;
+        function  get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): tcgpara;override;
         function param_use_paraloc(const cgpara: tcgpara): boolean; override;
         function param_use_paraloc(const cgpara: tcgpara): boolean; override;
         function ret_in_param(def: tdef; calloption: tproccalloption): boolean; override;
         function ret_in_param(def: tdef; calloption: tproccalloption): boolean; override;
         function is_stack_paraloc(paraloc: pcgparalocation): boolean;override;
         function is_stack_paraloc(paraloc: pcgparalocation): boolean;override;
       private
       private
-        procedure create_funcretloc_info(p : tabstractprocdef; side: tcallercallee);
         procedure create_paraloc_info_intern(p : tabstractprocdef; side: tcallercallee; paras: tparalist;
         procedure create_paraloc_info_intern(p : tabstractprocdef; side: tcallercallee; paras: tparalist;
                                              var parasize:longint);
                                              var parasize:longint);
       end;
       end;
@@ -111,23 +110,23 @@ implementation
       end;
       end;
 
 
 
 
-    procedure TJVMParaManager.create_funcretloc_info(p : tabstractprocdef; side: tcallercallee);
-      begin
-        p.funcretloc[side]:=get_funcretloc(p,side,p.returndef);
-      end;
-
-
-    function TJVMParaManager.get_funcretloc(p : tabstractprocdef; side: tcallercallee; def: tdef): tcgpara;
+    function TJVMParaManager.get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): tcgpara;
       var
       var
         paraloc : pcgparalocation;
         paraloc : pcgparalocation;
         retcgsize  : tcgsize;
         retcgsize  : tcgsize;
       begin
       begin
-        def:=get_para_push_size(def);
         result.init;
         result.init;
         result.alignment:=get_para_align(p.proccalloption);
         result.alignment:=get_para_align(p.proccalloption);
-        result.def:=def;
+        if not assigned(forcetempdef) then
+          result.def:=p.returndef
+        else
+          begin
+            result.def:=forcetempdef;
+            result.temporary:=true;
+          end;
+        result.def:=get_para_push_size(result.def);
         { void has no location }
         { void has no location }
-        if is_void(def) then
+        if is_void(result.def) then
           begin
           begin
             paraloc:=result.add_location;
             paraloc:=result.add_location;
             result.size:=OS_NO;
             result.size:=OS_NO;
@@ -144,8 +143,8 @@ implementation
           end
           end
         else
         else
           begin
           begin
-            retcgsize:=def_cgsize(def);
-            result.intsize:=def.size;
+            retcgsize:=def_cgsize(result.def);
+            result.intsize:=result.def.size;
           end;
           end;
         result.size:=retcgsize;
         result.size:=retcgsize;
 
 

+ 4 - 11
compiler/m68k/cpupara.pas

@@ -44,9 +44,8 @@ unit cpupara;
           procedure getintparaloc(calloption : tproccalloption; nr : longint; def : tdef; var cgpara : tcgpara);override;
           procedure getintparaloc(calloption : tproccalloption; nr : longint; def : tdef; var cgpara : tcgpara);override;
           function create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;override;
           function create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;override;
           function push_addr_param(varspez:tvarspez;def : tdef;calloption : tproccalloption) : boolean;override;
           function push_addr_param(varspez:tvarspez;def : tdef;calloption : tproccalloption) : boolean;override;
-          function get_funcretloc(p : tabstractprocdef; side: tcallercallee; def: tdef): tcgpara;override;
+          function get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): tcgpara;override;
           procedure createtempparaloc(list: TAsmList;calloption : tproccalloption;parasym : tparavarsym;can_use_final_stack_loc : boolean;var cgpara:TCGPara);override;
           procedure createtempparaloc(list: TAsmList;calloption : tproccalloption;parasym : tparavarsym;can_use_final_stack_loc : boolean;var cgpara:TCGPara);override;
-          procedure create_funcretloc_info(p : tabstractprocdef; side: tcallercallee);
           function create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargsparalist):longint;override;
           function create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargsparalist):longint;override;
           function parseparaloc(p : tparavarsym;const s : string) : boolean;override;
           function parseparaloc(p : tparavarsym;const s : string) : boolean;override;
           function parsefuncretloc(p : tabstractprocdef; const s : string) : boolean;override;
           function parsefuncretloc(p : tabstractprocdef; const s : string) : boolean;override;
@@ -187,23 +186,17 @@ unit cpupara;
         curfloatreg:=RS_FP0;
         curfloatreg:=RS_FP0;
       end;
       end;
 
 
-    procedure tm68kparamanager.create_funcretloc_info(p: tabstractprocdef; side: tcallercallee);
-      begin
-        p.funcretloc[side]:=get_funcretloc(p,side,p.returndef);
-      end;
-
-
-    function tm68kparamanager.get_funcretloc(p : tabstractprocdef; side: tcallercallee; def: tdef): tcgpara;
+    function tm68kparamanager.get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): tcgpara;
       var
       var
         paraloc : pcgparalocation;
         paraloc : pcgparalocation;
         retcgsize  : tcgsize;
         retcgsize  : tcgsize;
       begin
       begin
-        if set_common_funcretloc_info(p,def,retcgsize,result) then
+        if set_common_funcretloc_info(p,forcetempdef,retcgsize,result) then
           exit;
           exit;
 
 
         paraloc:=result.add_location;
         paraloc:=result.add_location;
         { Return in FPU register? }
         { Return in FPU register? }
-        if not(cs_fp_emulation in current_settings.moduleswitches) and (p.returndef.typ=floatdef) then
+        if not(cs_fp_emulation in current_settings.moduleswitches) and (result.def.typ=floatdef) then
           begin
           begin
             paraloc^.loc:=LOC_FPUREGISTER;
             paraloc^.loc:=LOC_FPUREGISTER;
             paraloc^.register:=NR_FPU_RESULT_REG;
             paraloc^.register:=NR_FPU_RESULT_REG;

+ 6 - 13
compiler/mips/cpupara.pas

@@ -79,11 +79,10 @@ interface
         procedure getintparaloc(calloption : tproccalloption; nr : longint; def : tdef; var cgpara : tcgpara);override;
         procedure getintparaloc(calloption : tproccalloption; nr : longint; def : tdef; var cgpara : tcgpara);override;
         function  create_paraloc_info(p : TAbstractProcDef; side: tcallercallee):longint;override;
         function  create_paraloc_info(p : TAbstractProcDef; side: tcallercallee):longint;override;
         function  create_varargs_paraloc_info(p : TAbstractProcDef; varargspara:tvarargsparalist):longint;override;
         function  create_varargs_paraloc_info(p : TAbstractProcDef; varargspara:tvarargsparalist):longint;override;
-        function  get_funcretloc(p : tabstractprocdef; side: tcallercallee; def: tdef): tcgpara;override;
+        function  get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): tcgpara;override;
       private
       private
         intparareg,
         intparareg,
         intparasize : longint;
         intparasize : longint;
-        procedure create_funcretloc_info(p : tabstractprocdef; side: tcallercallee);
         procedure create_paraloc_info_intern(p : tabstractprocdef; side: tcallercallee; paras: tparalist);
         procedure create_paraloc_info_intern(p : tabstractprocdef; side: tcallercallee; paras: tparalist);
       end;
       end;
 
 
@@ -181,22 +180,16 @@ implementation
       end;
       end;
 
 
 
 
-    procedure TMIPSParaManager.create_funcretloc_info(p : tabstractprocdef; side: tcallercallee);
-      begin
-        p.funcretloc[side]:=get_funcretloc(p,side,p.returndef);
-      end;
-
-
-    function TMIPSParaManager.get_funcretloc(p : tabstractprocdef; side: tcallercallee; def: tdef): tcgpara;
+    function TMIPSParaManager.get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): tcgpara;
       var
       var
         paraloc : pcgparalocation;
         paraloc : pcgparalocation;
         retcgsize  : tcgsize;
         retcgsize  : tcgsize;
       begin
       begin
-        if set_common_funcretloc_info(p,def,retcgsize,result) then
+        if set_common_funcretloc_info(p,forcetempdef,retcgsize,result) then
           begin
           begin
             { Return is passed as var parameter,
             { Return is passed as var parameter,
               in this case we use the first register R4 for it }
               in this case we use the first register R4 for it }
-            if ret_in_param(def,p.proccalloption) then
+            if ret_in_param(result.def,p.proccalloption) then
               begin
               begin
                 if intparareg=0 then
                 if intparareg=0 then
                   inc(intparareg);
                   inc(intparareg);
@@ -222,14 +215,14 @@ implementation
                   begin
                   begin
                     getIntParaLoc(p.proccalloption,1,result.def,result);
                     getIntParaLoc(p.proccalloption,1,result.def,result);
                   end;
                   end;
-                result.def:=getpointerdef(def);
+                result.def:=getpointerdef(result.def);
               end;
               end;
             exit;
             exit;
           end;
           end;
 
 
         paraloc:=result.add_location;
         paraloc:=result.add_location;
         { Return in FPU register? }
         { Return in FPU register? }
-        if p.returndef.typ=floatdef then
+        if result.def.typ=floatdef then
           begin
           begin
             paraloc^.loc:=LOC_FPUREGISTER;
             paraloc^.loc:=LOC_FPUREGISTER;
             paraloc^.register:=NR_FPU_RESULT_REG;
             paraloc^.register:=NR_FPU_RESULT_REG;

+ 3 - 4
compiler/ncgcal.pas

@@ -872,9 +872,9 @@ implementation
                         if cnf_inherited in callnodeflags then
                         if cnf_inherited in callnodeflags then
                           hlcg.a_call_name_inherited(current_asmdata.CurrAsmList,tprocdef(procdefinition),tprocdef(procdefinition).mangledname)
                           hlcg.a_call_name_inherited(current_asmdata.CurrAsmList,tprocdef(procdefinition),tprocdef(procdefinition).mangledname)
                         else
                         else
-                          hlcg.a_call_name(current_asmdata.CurrAsmList,tprocdef(procdefinition),tprocdef(procdefinition).mangledname,typedef,po_weakexternal in procdefinition.procoptions)
+                          hlcg.a_call_name(current_asmdata.CurrAsmList,tprocdef(procdefinition),tprocdef(procdefinition).mangledname,typedef,po_weakexternal in procdefinition.procoptions).resetiftemp
                       else
                       else
-                        hlcg.a_call_name(current_asmdata.CurrAsmList,tprocdef(procdefinition),name_to_call,typedef,po_weakexternal in procdefinition.procoptions);
+                        hlcg.a_call_name(current_asmdata.CurrAsmList,tprocdef(procdefinition),name_to_call,typedef,po_weakexternal in procdefinition.procoptions).resetiftemp;
                       extra_post_call_code;
                       extra_post_call_code;
                     end;
                     end;
                end;
                end;
@@ -1019,8 +1019,7 @@ implementation
 
 
     destructor tcgcallnode.destroy;
     destructor tcgcallnode.destroy;
       begin
       begin
-        if assigned(typedef) then
-          retloc.done;
+        retloc.resetiftemp;
         inherited destroy;
         inherited destroy;
       end;
       end;
 
 

+ 11 - 2
compiler/parabase.pas

@@ -73,18 +73,20 @@ unit parabase;
        end;
        end;
 
 
        TCGPara = object
        TCGPara = object
+          Def       : tdef; { Type of the parameter }
           Location  : PCGParalocation;
           Location  : PCGParalocation;
           IntSize   : tcgint; { size of the total location in bytes }
           IntSize   : tcgint; { size of the total location in bytes }
+          DefDeref  : tderef;
           Alignment : ShortInt;
           Alignment : ShortInt;
           Size      : TCGSize;  { Size of the parameter included in all locations }
           Size      : TCGSize;  { Size of the parameter included in all locations }
-          Def       : tdef; { Type of the parameter }
-          DefDeref  : tderef;
+          Temporary : boolean;  { created on the fly, no permanent references exist to this somewhere that will cause it to be disposed }
 {$ifdef powerpc}
 {$ifdef powerpc}
           composite: boolean; { under the AIX abi, how certain parameters are passed depends on whether they are composite or not }
           composite: boolean; { under the AIX abi, how certain parameters are passed depends on whether they are composite or not }
 {$endif powerpc}
 {$endif powerpc}
           constructor init;
           constructor init;
           destructor  done;
           destructor  done;
           procedure   reset;
           procedure   reset;
+          procedure   resetiftemp; { reset if Temporary }
           function    getcopy:tcgpara;
           function    getcopy:tcgpara;
           procedure   check_simple_location;
           procedure   check_simple_location;
           function    add_location:pcgparalocation;
           function    add_location:pcgparalocation;
@@ -132,6 +134,7 @@ implementation
         intsize:=0;
         intsize:=0;
         location:=nil;
         location:=nil;
         def:=nil;
         def:=nil;
+        temporary:=false;
 {$ifdef powerpc}
 {$ifdef powerpc}
         composite:=false;
         composite:=false;
 {$endif powerpc}
 {$endif powerpc}
@@ -162,6 +165,12 @@ implementation
 {$endif powerpc}
 {$endif powerpc}
       end;
       end;
 
 
+    procedure TCGPara.resetiftemp;
+      begin
+        if temporary then
+          reset;
+      end;
+
 
 
     function tcgpara.getcopy:tcgpara;
     function tcgpara.getcopy:tcgpara;
       var
       var

+ 22 - 9
compiler/paramgr.pas

@@ -114,7 +114,8 @@ unit paramgr;
             function result instead of its actual result. Used if the compiler
             function result instead of its actual result. Used if the compiler
             forces the function result to something different than the real
             forces the function result to something different than the real
             result.  }
             result.  }
-          function  get_funcretloc(p : tabstractprocdef; side: tcallercallee; def: tdef): tcgpara;virtual;abstract;
+          function  get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): tcgpara;virtual;abstract;
+          procedure create_funcretloc_info(p : tabstractprocdef; side: tcallercallee);
 
 
           { This is used to populate the location information on all parameters
           { This is used to populate the location information on all parameters
             for the routine when it is being inlined. It returns
             for the routine when it is being inlined. It returns
@@ -143,7 +144,7 @@ unit paramgr;
          strict protected
          strict protected
           { common part of get_funcretloc; returns true if retloc is completely
           { common part of get_funcretloc; returns true if retloc is completely
             initialized afterwards }
             initialized afterwards }
-          function set_common_funcretloc_info(p : tabstractprocdef; def: tdef; out retcgsize: tcgsize; out retloc: tcgpara): boolean;
+          function set_common_funcretloc_info(p : tabstractprocdef; forcetempdef: tdef; out retcgsize: tcgsize; out retloc: tcgpara): boolean;
        end;
        end;
 
 
 
 
@@ -453,6 +454,12 @@ implementation
       end;
       end;
 
 
 
 
+    procedure tparamanager.create_funcretloc_info(p : tabstractprocdef; side: tcallercallee);
+      begin
+        p.funcretloc[side]:=get_funcretloc(p,side,nil);
+      end;
+
+
     function tparamanager.create_inline_paraloc_info(p : tabstractprocdef):longint;
     function tparamanager.create_inline_paraloc_info(p : tabstractprocdef):longint;
       begin
       begin
         { We need to return the size allocated }
         { We need to return the size allocated }
@@ -497,16 +504,22 @@ implementation
       end;
       end;
 
 
 
 
-    function tparamanager.set_common_funcretloc_info(p : tabstractprocdef; def: tdef; out retcgsize: tcgsize; out retloc: tcgpara): boolean;
+    function tparamanager.set_common_funcretloc_info(p : tabstractprocdef; forcetempdef: tdef; out retcgsize: tcgsize; out retloc: tcgpara): boolean;
       var
       var
         paraloc : pcgparalocation;
         paraloc : pcgparalocation;
       begin
       begin
         result:=true;
         result:=true;
         retloc.init;
         retloc.init;
-        retloc.def:=def;
+        if not assigned(forcetempdef) then
+          retloc.def:=p.returndef
+        else
+          begin
+            retloc.def:=forcetempdef;
+            retloc.temporary:=true;
+          end;
         retloc.alignment:=get_para_align(p.proccalloption);
         retloc.alignment:=get_para_align(p.proccalloption);
         { void has no location }
         { void has no location }
-        if is_void(def) then
+        if is_void(retloc.def) then
           begin
           begin
             paraloc:=retloc.add_location;
             paraloc:=retloc.add_location;
             retloc.size:=OS_NO;
             retloc.size:=OS_NO;
@@ -528,14 +541,14 @@ implementation
           end
           end
         else
         else
           begin
           begin
-            retcgsize:=def_cgsize(def);
-            retloc.intsize:=def.size;
+            retcgsize:=def_cgsize(retloc.def);
+            retloc.intsize:=retloc.def.size;
           end;
           end;
         retloc.size:=retcgsize;
         retloc.size:=retcgsize;
         { Return is passed as var parameter }
         { Return is passed as var parameter }
-        if ret_in_param(def,p.proccalloption) then
+        if ret_in_param(retloc.def,p.proccalloption) then
           begin
           begin
-            retloc.def:=getpointerdef(def);
+            retloc.def:=getpointerdef(retloc.def);
             paraloc:=retloc.add_location;
             paraloc:=retloc.add_location;
             paraloc^.loc:=LOC_REFERENCE;
             paraloc^.loc:=LOC_REFERENCE;
             paraloc^.size:=retcgsize;
             paraloc^.size:=retcgsize;

+ 4 - 11
compiler/powerpc/cpupara.pas

@@ -40,8 +40,7 @@ unit cpupara;
           procedure getintparaloc(calloption : tproccalloption; nr : longint; def : tdef; var cgpara : tcgpara);override;
           procedure getintparaloc(calloption : tproccalloption; nr : longint; def : tdef; var cgpara : tcgpara);override;
           function create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;override;
           function create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;override;
           function create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargsparalist):longint;override;
           function create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargsparalist):longint;override;
-          function get_funcretloc(p : tabstractprocdef; side: tcallercallee; def: tdef): tcgpara;override;
-          procedure create_funcretloc_info(p : tabstractprocdef; side: tcallercallee);
+          function get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): tcgpara;override;
          private
          private
           procedure init_values(var curintreg, curfloatreg, curmmreg: tsuperregister; var cur_stack_offset: aword);
           procedure init_values(var curintreg, curfloatreg, curmmreg: tsuperregister; var cur_stack_offset: aword);
           function create_paraloc_info_intern(p : tabstractprocdef; side: tcallercallee; paras:tparalist;
           function create_paraloc_info_intern(p : tabstractprocdef; side: tcallercallee; paras:tparalist;
@@ -246,23 +245,17 @@ unit cpupara;
       end;
       end;
 
 
 
 
-    procedure tppcparamanager.create_funcretloc_info(p : tabstractprocdef; side: tcallercallee);
-      begin
-        p.funcretloc[side]:=get_funcretloc(p,side,p.returndef);
-      end;
-
-
-    function tppcparamanager.get_funcretloc(p : tabstractprocdef; side: tcallercallee; def: tdef): tcgpara;
+    function tppcparamanager.get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): tcgpara;
       var
       var
         paraloc : pcgparalocation;
         paraloc : pcgparalocation;
         retcgsize  : tcgsize;
         retcgsize  : tcgsize;
       begin
       begin
-        if set_common_funcretloc_info(p,def,retcgsize,result) then
+        if set_common_funcretloc_info(p,forcetempdef,retcgsize,result) then
           exit;
           exit;
 
 
         paraloc:=result.add_location;
         paraloc:=result.add_location;
         { Return in FPU register? }
         { Return in FPU register? }
-        if def.typ=floatdef then
+        if result.def.typ=floatdef then
           begin
           begin
             paraloc^.loc:=LOC_FPUREGISTER;
             paraloc^.loc:=LOC_FPUREGISTER;
             paraloc^.register:=NR_FPU_RESULT_REG;
             paraloc^.register:=NR_FPU_RESULT_REG;

+ 4 - 11
compiler/powerpc64/cpupara.pas

@@ -44,8 +44,7 @@ type
     function create_paraloc_info(p: tabstractprocdef; side: tcallercallee): longint; override;
     function create_paraloc_info(p: tabstractprocdef; side: tcallercallee): longint; override;
     function create_varargs_paraloc_info(p: tabstractprocdef; varargspara:
     function create_varargs_paraloc_info(p: tabstractprocdef; varargspara:
       tvarargsparalist): longint; override;
       tvarargsparalist): longint; override;
-    function get_funcretloc(p : tabstractprocdef; side: tcallercallee; def: tdef): tcgpara;override;
-    procedure create_funcretloc_info(p: tabstractprocdef; side: tcallercallee);
+    function get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): tcgpara;override;
 
 
   private
   private
     procedure init_values(var curintreg, curfloatreg, curmmreg: tsuperregister;
     procedure init_values(var curintreg, curfloatreg, curmmreg: tsuperregister;
@@ -202,24 +201,18 @@ begin
   curmmreg := RS_M2;
   curmmreg := RS_M2;
 end;
 end;
 
 
-procedure tppcparamanager.create_funcretloc_info(p: tabstractprocdef; side:
-  tcallercallee);
-begin
-  p.funcretloc[side]:=get_funcretloc(p,side,p.returndef);
-end;
-
 function tppcparamanager.get_funcretloc(p : tabstractprocdef; side:
 function tppcparamanager.get_funcretloc(p : tabstractprocdef; side:
-  tcallercallee; def: tdef): tcgpara;
+  tcallercallee; forcetempdef: tdef): tcgpara;
 var
 var
   paraloc : pcgparalocation;
   paraloc : pcgparalocation;
   retcgsize  : tcgsize;
   retcgsize  : tcgsize;
 begin
 begin
-  if set_common_funcretloc_info(p,def,retcgsize,result) then
+  if set_common_funcretloc_info(p,forcetempdef,retcgsize,result) then
     exit;
     exit;
 
 
   paraloc:=result.add_location;
   paraloc:=result.add_location;
   { Return in FPU register? }
   { Return in FPU register? }
-  if def.typ=floatdef then
+  if result.def.typ=floatdef then
     begin
     begin
       paraloc^.loc:=LOC_FPUREGISTER;
       paraloc^.loc:=LOC_FPUREGISTER;
       paraloc^.register:=NR_FPU_RESULT_REG;
       paraloc^.register:=NR_FPU_RESULT_REG;

+ 4 - 11
compiler/sparc/cpupara.pas

@@ -41,9 +41,8 @@ interface
         procedure getintparaloc(calloption : tproccalloption; nr : longint; def : tdef; var cgpara : tcgpara);override;
         procedure getintparaloc(calloption : tproccalloption; nr : longint; def : tdef; var cgpara : tcgpara);override;
         function  create_paraloc_info(p : TAbstractProcDef; side: tcallercallee):longint;override;
         function  create_paraloc_info(p : TAbstractProcDef; side: tcallercallee):longint;override;
         function  create_varargs_paraloc_info(p : TAbstractProcDef; varargspara:tvarargsparalist):longint;override;
         function  create_varargs_paraloc_info(p : TAbstractProcDef; varargspara:tvarargsparalist):longint;override;
-        function  get_funcretloc(p : tabstractprocdef; side: tcallercallee; def: tdef): tcgpara;override;
+        function  get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): tcgpara;override;
       private
       private
-        procedure create_funcretloc_info(p : tabstractprocdef; side: tcallercallee);
         procedure create_paraloc_info_intern(p : tabstractprocdef; side: tcallercallee; paras: tparalist;
         procedure create_paraloc_info_intern(p : tabstractprocdef; side: tcallercallee; paras: tparalist;
                                              var intparareg,parasize:longint);
                                              var intparareg,parasize:longint);
       end;
       end;
@@ -140,23 +139,17 @@ implementation
       end;
       end;
 
 
 
 
-    procedure tsparcparamanager.create_funcretloc_info(p : tabstractprocdef; side: tcallercallee);
-      begin
-        p.funcretloc[side]:=get_funcretloc(p,side,p.returndef);
-      end;
-
-
-    function tsparcparamanager.get_funcretloc(p : tabstractprocdef; side: tcallercallee; def: tdef): tcgpara;
+    function tsparcparamanager.get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): tcgpara;
       var
       var
         paraloc : pcgparalocation;
         paraloc : pcgparalocation;
         retcgsize  : tcgsize;
         retcgsize  : tcgsize;
       begin
       begin
-        if set_common_funcretloc_info(p,def,retcgsize,result) then
+        if set_common_funcretloc_info(p,forcetempdef,retcgsize,result) then
           exit;
           exit;
 
 
         paraloc:=result.add_location;
         paraloc:=result.add_location;
         { Return in FPU register? }
         { Return in FPU register? }
-        if def.typ=floatdef then
+        if result.def.typ=floatdef then
           begin
           begin
             paraloc^.loc:=LOC_FPUREGISTER;
             paraloc^.loc:=LOC_FPUREGISTER;
             paraloc^.register:=NR_FPU_RESULT_REG;
             paraloc^.register:=NR_FPU_RESULT_REG;

+ 1 - 3
compiler/x86/cgx86.pas

@@ -515,9 +515,7 @@ unit cgx86;
              end
              end
           end
           end
         else if (cs_create_pic in current_settings.moduleswitches) and
         else if (cs_create_pic in current_settings.moduleswitches) and
-           assigned(ref.symbol) and
-           not((ref.symbol.bind=AB_LOCAL) and
-               (ref.symbol.typ in [AT_LABEL,AT_FUNCTION])) then
+           assigned(ref.symbol) then
           begin
           begin
             reference_reset_symbol(href,ref.symbol,0,sizeof(pint));
             reference_reset_symbol(href,ref.symbol,0,sizeof(pint));
             href.base:=current_procinfo.got;
             href.base:=current_procinfo.got;

+ 6 - 13
compiler/x86_64/cpupara.pas

@@ -35,7 +35,6 @@ unit cpupara;
     type
     type
        tx86_64paramanager = class(tparamanager)
        tx86_64paramanager = class(tparamanager)
        private
        private
-          procedure create_funcretloc_info(p : tabstractprocdef; side: tcallercallee);
           procedure create_paraloc_info_intern(p : tabstractprocdef; side: tcallercallee;paras:tparalist;
           procedure create_paraloc_info_intern(p : tabstractprocdef; side: tcallercallee;paras:tparalist;
                                                var intparareg,mmparareg,parasize:longint;varargsparas: boolean);
                                                var intparareg,mmparareg,parasize:longint;varargsparas: boolean);
        public
        public
@@ -48,7 +47,7 @@ unit cpupara;
           function get_volatile_registers_fpu(calloption : tproccalloption):tcpuregisterset;override;
           function get_volatile_registers_fpu(calloption : tproccalloption):tcpuregisterset;override;
           function create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;override;
           function create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;override;
           function create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargsparalist):longint;override;
           function create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargsparalist):longint;override;
-          function get_funcretloc(p : tabstractprocdef; side: tcallercallee; def: tdef): tcgpara;override;
+          function get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): tcgpara;override;
        end;
        end;
 
 
   implementation
   implementation
@@ -791,13 +790,7 @@ unit cpupara;
       end;
       end;
 
 
 
 
-    procedure tx86_64paramanager.create_funcretloc_info(p : tabstractprocdef; side: tcallercallee);
-      begin
-        p.funcretloc[side]:=get_funcretloc(p,side,p.returndef);
-      end;
-
-
-    function tx86_64paramanager.get_funcretloc(p : tabstractprocdef; side: tcallercallee; def: tdef): tcgpara;
+    function tx86_64paramanager.get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): tcgpara;
       const
       const
         intretregs: array[0..1] of tregister = (NR_FUNCTION_RETURN_REG,NR_FUNCTION_RETURN_REG_HIGH);
         intretregs: array[0..1] of tregister = (NR_FUNCTION_RETURN_REG,NR_FUNCTION_RETURN_REG_HIGH);
         mmretregs: array[0..1] of tregister = (NR_MM_RESULT_REG,NR_MM_RESULT_REG_HIGH);
         mmretregs: array[0..1] of tregister = (NR_MM_RESULT_REG,NR_MM_RESULT_REG_HIGH);
@@ -810,7 +803,7 @@ unit cpupara;
         retcgsize : tcgsize;
         retcgsize : tcgsize;
         paraloc : pcgparalocation;
         paraloc : pcgparalocation;
       begin
       begin
-        if set_common_funcretloc_info(p,def,retcgsize,result) then
+        if set_common_funcretloc_info(p,forcetempdef,retcgsize,result) then
           exit;
           exit;
 
 
         { integer sizes < 32 bit have to be sign/zero extended to 32 bit on
         { integer sizes < 32 bit have to be sign/zero extended to 32 bit on
@@ -827,10 +820,10 @@ unit cpupara;
         { Return in FPU register? -> don't use classify_argument(), because
         { Return in FPU register? -> don't use classify_argument(), because
           currency and comp need special treatment here (they are integer class
           currency and comp need special treatment here (they are integer class
           when passing as parameter, but LOC_FPUREGISTER as function result) }
           when passing as parameter, but LOC_FPUREGISTER as function result) }
-        if def.typ=floatdef then
+        if result.def.typ=floatdef then
           begin
           begin
             paraloc:=result.add_location;
             paraloc:=result.add_location;
-            case tfloatdef(def).floattype of
+            case tfloatdef(result.def).floattype of
               s32real:
               s32real:
                 begin
                 begin
                   paraloc^.loc:=LOC_MMREGISTER;
                   paraloc^.loc:=LOC_MMREGISTER;
@@ -861,7 +854,7 @@ unit cpupara;
         else
         else
          { Return in register }
          { Return in register }
           begin
           begin
-            numclasses:=classify_argument(def,vs_value,def.size,classes,0);
+            numclasses:=classify_argument(result.def,vs_value,result.def.size,classes,0);
             { this would mean a memory return }
             { this would mean a memory return }
             if (numclasses=0) then
             if (numclasses=0) then
               internalerror(2010021502);
               internalerror(2010021502);