فهرست منبع

* 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;
           function create_paraloc_info(p : tabstractprocdef; side: tcallercallee):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
           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;
             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;
 
   implementation
@@ -576,23 +575,17 @@ unit cpupara;
       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
         paraloc : pcgparalocation;
         retcgsize  : tcgsize;
       begin
-         if set_common_funcretloc_info(p,def,retcgsize,result) then
+         if set_common_funcretloc_info(p,forcetempdef,retcgsize,result) then
            exit;
 
         paraloc:=result.add_location;
         { Return in FPU register? }
-        if def.typ=floatdef then
+        if result.def.typ=floatdef then
           begin
             if target_info.abi = abi_eabihf then 
               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;
           function create_paraloc_info(p : tabstractprocdef; side: tcallercallee):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
           procedure init_values(var curintreg, curfloatreg, curmmreg: tsuperregister; var cur_stack_offset: aword);
           function create_paraloc_info_intern(p : tabstractprocdef; side: tcallercallee; paras: tparalist;
             var curintreg, curfloatreg, curmmreg: tsuperregister; var cur_stack_offset: aword):longint;
-          procedure create_funcretloc_info(p : tabstractprocdef; side: tcallercallee);
        end;
 
   implementation
@@ -403,24 +402,18 @@ unit cpupara;
      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 }
-    function  tavrparamanager.get_funcretloc(p : tabstractprocdef; side: tcallercallee; def: tdef): tcgpara;
+    function  tavrparamanager.get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): tcgpara;
       var
         retcgsize : tcgsize;
         paraloc : pcgparalocation;
       begin
-         if set_common_funcretloc_info(p,def,retcgsize,result) then
+         if set_common_funcretloc_info(p,forcetempdef,retcgsize,result) then
            exit;
 
         paraloc:=result.add_location;
         { Return in FPU register? }
-        if def.typ=floatdef then
+        if result.def.typ=floatdef then
           begin
             if (p.proccalloption in [pocall_softfloat]) or (cs_fp_emulation in current_settings.moduleswitches) then
               begin

+ 1 - 0
compiler/hlcgobj.pas

@@ -3310,6 +3310,7 @@ implementation
       cgpara3.done;
       cgpara2.done;
       cgpara1.done;
+      getmemres.resetiftemp;
     end;
 
   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_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;
-          function get_funcretloc(p : tabstractprocdef; side: tcallercallee; def: tdef): TCGPara;override;
+          function get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): TCGPara;override;
        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_register_paraloc_info(p : tabstractprocdef; side: tcallercallee;paras:tparalist;var parareg,parasize:longint);
        end;
@@ -310,29 +309,35 @@ unit cpupara;
       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
         retcgsize  : tcgsize;
         paraloc : pcgparalocation;
         sym: tfieldvarsym;
+        usedef: tdef;
+        handled: boolean;
       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
           single or double, it has to be returned like a single/double }
         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
            (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;
 
         { darwin/x86 requires that results < sizeof(aint) are sign/zero
@@ -349,7 +354,7 @@ unit cpupara;
           end;
 
         { Return in FPU register? }
-        if def.typ=floatdef then
+        if result.def.typ=floatdef then
           begin
             paraloc:=result.add_location;
             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;
         function  create_paraloc_info(p : TAbstractProcDef; side: tcallercallee):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 ret_in_param(def: tdef; calloption: tproccalloption): boolean; override;
         function is_stack_paraloc(paraloc: pcgparalocation): boolean;override;
       private
-        procedure create_funcretloc_info(p : tabstractprocdef; side: tcallercallee);
         procedure create_paraloc_info_intern(p : tabstractprocdef; side: tcallercallee; paras: tparalist;
                                              var parasize:longint);
       end;
@@ -111,23 +110,23 @@ implementation
       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
         paraloc : pcgparalocation;
         retcgsize  : tcgsize;
       begin
-        def:=get_para_push_size(def);
         result.init;
         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 }
-        if is_void(def) then
+        if is_void(result.def) then
           begin
             paraloc:=result.add_location;
             result.size:=OS_NO;
@@ -144,8 +143,8 @@ implementation
           end
         else
           begin
-            retcgsize:=def_cgsize(def);
-            result.intsize:=def.size;
+            retcgsize:=def_cgsize(result.def);
+            result.intsize:=result.def.size;
           end;
         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;
           function create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;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 create_funcretloc_info(p : tabstractprocdef; side: tcallercallee);
           function create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargsparalist):longint;override;
           function parseparaloc(p : tparavarsym;const s : string) : boolean;override;
           function parsefuncretloc(p : tabstractprocdef; const s : string) : boolean;override;
@@ -187,23 +186,17 @@ unit cpupara;
         curfloatreg:=RS_FP0;
       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
         paraloc : pcgparalocation;
         retcgsize  : tcgsize;
       begin
-        if set_common_funcretloc_info(p,def,retcgsize,result) then
+        if set_common_funcretloc_info(p,forcetempdef,retcgsize,result) then
           exit;
 
         paraloc:=result.add_location;
         { 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
             paraloc^.loc:=LOC_FPUREGISTER;
             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;
         function  create_paraloc_info(p : TAbstractProcDef; side: tcallercallee):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
         intparareg,
         intparasize : longint;
-        procedure create_funcretloc_info(p : tabstractprocdef; side: tcallercallee);
         procedure create_paraloc_info_intern(p : tabstractprocdef; side: tcallercallee; paras: tparalist);
       end;
 
@@ -181,22 +180,16 @@ implementation
       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
         paraloc : pcgparalocation;
         retcgsize  : tcgsize;
       begin
-        if set_common_funcretloc_info(p,def,retcgsize,result) then
+        if set_common_funcretloc_info(p,forcetempdef,retcgsize,result) then
           begin
             { Return is passed as var parameter,
               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
                 if intparareg=0 then
                   inc(intparareg);
@@ -222,14 +215,14 @@ implementation
                   begin
                     getIntParaLoc(p.proccalloption,1,result.def,result);
                   end;
-                result.def:=getpointerdef(def);
+                result.def:=getpointerdef(result.def);
               end;
             exit;
           end;
 
         paraloc:=result.add_location;
         { Return in FPU register? }
-        if p.returndef.typ=floatdef then
+        if result.def.typ=floatdef then
           begin
             paraloc^.loc:=LOC_FPUREGISTER;
             paraloc^.register:=NR_FPU_RESULT_REG;

+ 3 - 4
compiler/ncgcal.pas

@@ -872,9 +872,9 @@ implementation
                         if cnf_inherited in callnodeflags then
                           hlcg.a_call_name_inherited(current_asmdata.CurrAsmList,tprocdef(procdefinition),tprocdef(procdefinition).mangledname)
                         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
-                        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;
                     end;
                end;
@@ -1019,8 +1019,7 @@ implementation
 
     destructor tcgcallnode.destroy;
       begin
-        if assigned(typedef) then
-          retloc.done;
+        retloc.resetiftemp;
         inherited destroy;
       end;
 

+ 11 - 2
compiler/parabase.pas

@@ -73,18 +73,20 @@ unit parabase;
        end;
 
        TCGPara = object
+          Def       : tdef; { Type of the parameter }
           Location  : PCGParalocation;
           IntSize   : tcgint; { size of the total location in bytes }
+          DefDeref  : tderef;
           Alignment : ShortInt;
           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}
           composite: boolean; { under the AIX abi, how certain parameters are passed depends on whether they are composite or not }
 {$endif powerpc}
           constructor init;
           destructor  done;
           procedure   reset;
+          procedure   resetiftemp; { reset if Temporary }
           function    getcopy:tcgpara;
           procedure   check_simple_location;
           function    add_location:pcgparalocation;
@@ -132,6 +134,7 @@ implementation
         intsize:=0;
         location:=nil;
         def:=nil;
+        temporary:=false;
 {$ifdef powerpc}
         composite:=false;
 {$endif powerpc}
@@ -162,6 +165,12 @@ implementation
 {$endif powerpc}
       end;
 
+    procedure TCGPara.resetiftemp;
+      begin
+        if temporary then
+          reset;
+      end;
+
 
     function tcgpara.getcopy:tcgpara;
       var

+ 22 - 9
compiler/paramgr.pas

@@ -114,7 +114,8 @@ unit paramgr;
             function result instead of its actual result. Used if the compiler
             forces the function result to something different than the real
             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
             for the routine when it is being inlined. It returns
@@ -143,7 +144,7 @@ unit paramgr;
          strict protected
           { common part of get_funcretloc; returns true if retloc is completely
             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;
 
 
@@ -453,6 +454,12 @@ implementation
       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;
       begin
         { We need to return the size allocated }
@@ -497,16 +504,22 @@ implementation
       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
         paraloc : pcgparalocation;
       begin
         result:=true;
         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);
         { void has no location }
-        if is_void(def) then
+        if is_void(retloc.def) then
           begin
             paraloc:=retloc.add_location;
             retloc.size:=OS_NO;
@@ -528,14 +541,14 @@ implementation
           end
         else
           begin
-            retcgsize:=def_cgsize(def);
-            retloc.intsize:=def.size;
+            retcgsize:=def_cgsize(retloc.def);
+            retloc.intsize:=retloc.def.size;
           end;
         retloc.size:=retcgsize;
         { Return is passed as var parameter }
-        if ret_in_param(def,p.proccalloption) then
+        if ret_in_param(retloc.def,p.proccalloption) then
           begin
-            retloc.def:=getpointerdef(def);
+            retloc.def:=getpointerdef(retloc.def);
             paraloc:=retloc.add_location;
             paraloc^.loc:=LOC_REFERENCE;
             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;
           function create_paraloc_info(p : tabstractprocdef; side: tcallercallee):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
           procedure init_values(var curintreg, curfloatreg, curmmreg: tsuperregister; var cur_stack_offset: aword);
           function create_paraloc_info_intern(p : tabstractprocdef; side: tcallercallee; paras:tparalist;
@@ -246,23 +245,17 @@ unit cpupara;
       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
         paraloc : pcgparalocation;
         retcgsize  : tcgsize;
       begin
-        if set_common_funcretloc_info(p,def,retcgsize,result) then
+        if set_common_funcretloc_info(p,forcetempdef,retcgsize,result) then
           exit;
 
         paraloc:=result.add_location;
         { Return in FPU register? }
-        if def.typ=floatdef then
+        if result.def.typ=floatdef then
           begin
             paraloc^.loc:=LOC_FPUREGISTER;
             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_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
     procedure init_values(var curintreg, curfloatreg, curmmreg: tsuperregister;
@@ -202,24 +201,18 @@ begin
   curmmreg := RS_M2;
 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;
+  tcallercallee; forcetempdef: tdef): tcgpara;
 var
   paraloc : pcgparalocation;
   retcgsize  : tcgsize;
 begin
-  if set_common_funcretloc_info(p,def,retcgsize,result) then
+  if set_common_funcretloc_info(p,forcetempdef,retcgsize,result) then
     exit;
 
   paraloc:=result.add_location;
   { Return in FPU register? }
-  if def.typ=floatdef then
+  if result.def.typ=floatdef then
     begin
       paraloc^.loc:=LOC_FPUREGISTER;
       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;
         function  create_paraloc_info(p : TAbstractProcDef; side: tcallercallee):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
-        procedure create_funcretloc_info(p : tabstractprocdef; side: tcallercallee);
         procedure create_paraloc_info_intern(p : tabstractprocdef; side: tcallercallee; paras: tparalist;
                                              var intparareg,parasize:longint);
       end;
@@ -140,23 +139,17 @@ implementation
       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
         paraloc : pcgparalocation;
         retcgsize  : tcgsize;
       begin
-        if set_common_funcretloc_info(p,def,retcgsize,result) then
+        if set_common_funcretloc_info(p,forcetempdef,retcgsize,result) then
           exit;
 
         paraloc:=result.add_location;
         { Return in FPU register? }
-        if def.typ=floatdef then
+        if result.def.typ=floatdef then
           begin
             paraloc^.loc:=LOC_FPUREGISTER;
             paraloc^.register:=NR_FPU_RESULT_REG;

+ 1 - 3
compiler/x86/cgx86.pas

@@ -515,9 +515,7 @@ unit cgx86;
              end
           end
         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
             reference_reset_symbol(href,ref.symbol,0,sizeof(pint));
             href.base:=current_procinfo.got;

+ 6 - 13
compiler/x86_64/cpupara.pas

@@ -35,7 +35,6 @@ unit cpupara;
     type
        tx86_64paramanager = class(tparamanager)
        private
-          procedure create_funcretloc_info(p : tabstractprocdef; side: tcallercallee);
           procedure create_paraloc_info_intern(p : tabstractprocdef; side: tcallercallee;paras:tparalist;
                                                var intparareg,mmparareg,parasize:longint;varargsparas: boolean);
        public
@@ -48,7 +47,7 @@ unit cpupara;
           function get_volatile_registers_fpu(calloption : tproccalloption):tcpuregisterset;override;
           function create_paraloc_info(p : tabstractprocdef; side: tcallercallee):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;
 
   implementation
@@ -791,13 +790,7 @@ unit cpupara;
       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
         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);
@@ -810,7 +803,7 @@ unit cpupara;
         retcgsize : tcgsize;
         paraloc : pcgparalocation;
       begin
-        if set_common_funcretloc_info(p,def,retcgsize,result) then
+        if set_common_funcretloc_info(p,forcetempdef,retcgsize,result) then
           exit;
 
         { 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
           currency and comp need special treatment here (they are integer class
           when passing as parameter, but LOC_FPUREGISTER as function result) }
-        if def.typ=floatdef then
+        if result.def.typ=floatdef then
           begin
             paraloc:=result.add_location;
-            case tfloatdef(def).floattype of
+            case tfloatdef(result.def).floattype of
               s32real:
                 begin
                   paraloc^.loc:=LOC_MMREGISTER;
@@ -861,7 +854,7 @@ unit cpupara;
         else
          { Return in register }
           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 }
             if (numclasses=0) then
               internalerror(2010021502);