Pārlūkot izejas kodu

* fixed crashes on platforms using parentfpstructs with generic routines
that contain nested functions (when specialised, procedures don't have
the main function of the unit/program as parent procinfo)

git-svn-id: trunk@42063 -

Jonas Maebe 6 gadi atpakaļ
vecāks
revīzija
cf9596421b
3 mainītis faili ar 27 papildinājumiem un 10 dzēšanām
  1. 3 1
      compiler/ncgnstld.pas
  2. 17 8
      compiler/ncgnstmm.pas
  3. 7 1
      compiler/symdef.pas

+ 3 - 1
compiler/ncgnstld.pas

@@ -91,7 +91,9 @@ implementation
         nestedvars: tsym;
         nestedvars: tsym;
       begin
       begin
         result:=inherited pass_typecheck;
         result:=inherited pass_typecheck;
-        if assigned(result) then
+        if assigned(result) or
+           (assigned(current_procinfo) and
+            (df_generic in current_procinfo.procdef.defoptions)) then
           exit;
           exit;
         case symtableentry.typ of
         case symtableentry.typ of
           paravarsym,
           paravarsym,

+ 17 - 8
compiler/ncgnstmm.pas

@@ -60,10 +60,15 @@ implementation
         nextpi      : tprocinfo;
         nextpi      : tprocinfo;
       begin
       begin
         result:=inherited;
         result:=inherited;
-        if assigned(result) then
+        if assigned(result) or
+           (assigned(current_procinfo) and
+            (df_generic in current_procinfo.procdef.defoptions)) then
           exit;
           exit;
         currpi:=current_procinfo.parent;
         currpi:=current_procinfo.parent;
-        while (currpi.procdef.parast.symtablelevel>=parentpd.parast.symtablelevel) do
+        { current_procinfo.parent is not assigned for specialised generic routines in the
+          top-level scope }
+        while assigned(currpi) and
+              (currpi.procdef.parast.symtablelevel>=parentpd.parast.symtablelevel) do
           begin
           begin
             if not assigned(currpi.procdef.parentfpstruct) then
             if not assigned(currpi.procdef.parentfpstruct) then
               build_parentfpstruct(currpi.procdef);
               build_parentfpstruct(currpi.procdef);
@@ -72,13 +77,17 @@ implementation
         { mark all parent parentfp parameters for inclusion in the struct that
         { mark all parent parentfp parameters for inclusion in the struct that
           holds all locals accessed from nested routines }
           holds all locals accessed from nested routines }
         currpi:=current_procinfo.parent;
         currpi:=current_procinfo.parent;
-        nextpi:=currpi.parent;
-        while (currpi.procdef.parast.symtablelevel>parentpd.parast.symtablelevel) do
+        if assigned(currpi) then
           begin
           begin
-            hsym:=tparavarsym(currpi.procdef.parast.Find('parentfp'));
-            maybe_add_sym_to_parentfpstruct(currpi.procdef,hsym,nextpi.procdef.parentfpstructptrtype,false);
-            currpi:=nextpi;
-            nextpi:=nextpi.parent;
+            nextpi:=currpi.parent;
+            while assigned(currpi) and
+                  (currpi.procdef.parast.symtablelevel>parentpd.parast.symtablelevel) do
+              begin
+                hsym:=tparavarsym(currpi.procdef.parast.Find('parentfp'));
+                maybe_add_sym_to_parentfpstruct(currpi.procdef,hsym,nextpi.procdef.parentfpstructptrtype,false);
+                currpi:=nextpi;
+                nextpi:=nextpi.parent;
+              end;
           end;
           end;
       end;
       end;
 
 

+ 7 - 1
compiler/symdef.pas

@@ -3402,7 +3402,13 @@ implementation
       begin
       begin
         inherited create(pointerdef,def);
         inherited create(pointerdef,def);
         has_pointer_math:=cs_pointermath in current_settings.localswitches;
         has_pointer_math:=cs_pointermath in current_settings.localswitches;
-        if df_specialization in tstoreddef(def).defoptions then
+        if (df_specialization in tstoreddef(def).defoptions)
+{$ifndef genericdef_for_nested}
+           { currently, nested procdefs of generic routines get df_specialisation,
+             but no genericdef }
+           and assigned(tstoreddef(def).genericdef)
+{$endif}
+           then
           genericdef:=cpointerdef.getreusable(tstoreddef(def).genericdef);
           genericdef:=cpointerdef.getreusable(tstoreddef(def).genericdef);
       end;
       end;