summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjonas <jonas@3ad0048d-3df7-0310-abae-a5850022a9f2>2019-05-14 19:19:14 +0000
committerjonas <jonas@3ad0048d-3df7-0310-abae-a5850022a9f2>2019-05-14 19:19:14 +0000
commita8c295bd5b3105bef41c9b7985aa9a3fe3f55cda (patch)
tree6a4694e9853576bf9d4df89488d81ac3d4225599
parent1788e703b04e80da6dde2704f59c841c7a25dab3 (diff)
downloadfpc-a8c295bd5b3105bef41c9b7985aa9a3fe3f55cda.tar.gz
* 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: https://svn.freepascal.org/svn/fpc/trunk@42063 3ad0048d-3df7-0310-abae-a5850022a9f2
-rw-r--r--compiler/ncgnstld.pas4
-rw-r--r--compiler/ncgnstmm.pas25
-rw-r--r--compiler/symdef.pas8
3 files changed, 27 insertions, 10 deletions
diff --git a/compiler/ncgnstld.pas b/compiler/ncgnstld.pas
index 7c7b55ed49..2aa1e76f3a 100644
--- a/compiler/ncgnstld.pas
+++ b/compiler/ncgnstld.pas
@@ -91,7 +91,9 @@ implementation
nestedvars: tsym;
begin
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;
case symtableentry.typ of
paravarsym,
diff --git a/compiler/ncgnstmm.pas b/compiler/ncgnstmm.pas
index 6e4ec655f4..b9688281b1 100644
--- a/compiler/ncgnstmm.pas
+++ b/compiler/ncgnstmm.pas
@@ -60,10 +60,15 @@ implementation
nextpi : tprocinfo;
begin
result:=inherited;
- if assigned(result) then
+ if assigned(result) or
+ (assigned(current_procinfo) and
+ (df_generic in current_procinfo.procdef.defoptions)) then
exit;
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
if not assigned(currpi.procdef.parentfpstruct) then
build_parentfpstruct(currpi.procdef);
@@ -72,13 +77,17 @@ implementation
{ mark all parent parentfp parameters for inclusion in the struct that
holds all locals accessed from nested routines }
currpi:=current_procinfo.parent;
- nextpi:=currpi.parent;
- while (currpi.procdef.parast.symtablelevel>parentpd.parast.symtablelevel) do
+ if assigned(currpi) then
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;
diff --git a/compiler/symdef.pas b/compiler/symdef.pas
index 14e5dba45b..ab02eb7db7 100644
--- a/compiler/symdef.pas
+++ b/compiler/symdef.pas
@@ -3402,7 +3402,13 @@ implementation
begin
inherited create(pointerdef,def);
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);
end;