diff options
author | jonas <jonas@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2019-05-14 19:19:14 +0000 |
---|---|---|
committer | jonas <jonas@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2019-05-14 19:19:14 +0000 |
commit | a8c295bd5b3105bef41c9b7985aa9a3fe3f55cda (patch) | |
tree | 6a4694e9853576bf9d4df89488d81ac3d4225599 | |
parent | 1788e703b04e80da6dde2704f59c841c7a25dab3 (diff) | |
download | fpc-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.pas | 4 | ||||
-rw-r--r-- | compiler/ncgnstmm.pas | 25 | ||||
-rw-r--r-- | compiler/symdef.pas | 8 |
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; |