diff --git a/compiler/defcmp.pas b/compiler/defcmp.pas index a905849c65..4916389e64 100644 --- a/compiler/defcmp.pas +++ b/compiler/defcmp.pas @@ -271,21 +271,27 @@ implementation (df_specialization in def_to.defoptions) and (tstoreddef(def_from).genericdef=tstoreddef(def_to).genericdef) then begin - if tstoreddef(def_from).genericparas.count<>tstoreddef(def_to).genericparas.count then - internalerror(2012091301); + if assigned(tstoreddef(def_from).genericparas) xor + assigned(tstoreddef(def_to).genericparas) then + internalerror(2013030901); diff:=false; - for i:=0 to tstoreddef(def_from).genericparas.count-1 do + if assigned(tstoreddef(def_from).genericparas) then begin - if tstoreddef(def_from).genericparas.nameofindex(i)<>tstoreddef(def_to).genericparas.nameofindex(i) then - internalerror(2012091302); - symfrom:=ttypesym(tstoreddef(def_from).genericparas[i]); - symto:=ttypesym(tstoreddef(def_to).genericparas[i]); - if not (symfrom.typ=typesym) or not (symto.typ=typesym) then - internalerror(2012121401); - if not equal_defs(ttypesym(symfrom).typedef,ttypesym(symto).typedef) then - diff:=true; - if diff then - break; + if tstoreddef(def_from).genericparas.count<>tstoreddef(def_to).genericparas.count then + internalerror(2012091301); + for i:=0 to tstoreddef(def_from).genericparas.count-1 do + begin + if tstoreddef(def_from).genericparas.nameofindex(i)<>tstoreddef(def_to).genericparas.nameofindex(i) then + internalerror(2012091302); + symfrom:=ttypesym(tstoreddef(def_from).genericparas[i]); + symto:=ttypesym(tstoreddef(def_to).genericparas[i]); + if not (symfrom.typ=typesym) or not (symto.typ=typesym) then + internalerror(2012121401); + if not equal_defs(ttypesym(symfrom).typedef,ttypesym(symto).typedef) then + diff:=true; + if diff then + break; + end; end; if not diff then begin diff --git a/compiler/pgenutil.pas b/compiler/pgenutil.pas index b36c96e18a..ca8a29dc4e 100644 --- a/compiler/pgenutil.pas +++ b/compiler/pgenutil.pas @@ -112,7 +112,7 @@ uses begin { check whether the given specialization parameters fit to the eventual constraints of the generic } - if genericdef.genericparas.count=0 then + if not assigned(genericdef.genericparas) or (genericdef.genericparas.count=0) then internalerror(2012101001); if genericdef.genericparas.count<>paradeflist.count then internalerror(2012101002); @@ -1039,6 +1039,8 @@ uses internalerror(201101020); end; + if (genericlist.count>0) and not assigned(def.genericparas) then + def.genericparas:=tfphashobjectlist.create(false); for i:=0 to genericlist.count-1 do begin generictype:=ttypesym(genericlist[i]); diff --git a/compiler/symdef.pas b/compiler/symdef.pas index 31ee02e885..c373db2abc 100644 --- a/compiler/symdef.pas +++ b/compiler/symdef.pas @@ -66,7 +66,8 @@ interface genericdefderef : tderef; generictokenbuf : tdynamicarray; { this list contains references to the symbols that make up the - generic parameters; the symbols are not owned by this list } + generic parameters; the symbols are not owned by this list + Note: this list is allocated on demand! } genericparas : tfphashobjectlist; constructor create(dt:tdeftyp); constructor ppuload(dt:tdeftyp;ppufile:tcompilerppufile); @@ -1388,7 +1389,11 @@ implementation begin sym:=tsym(symtable.symlist[i]); if sp_generic_para in sym.symoptions then - genericparas.Add(sym.name,sym); + begin + if not assigned(genericparas) then + genericparas:=tfphashobjectlist.create(false); + genericparas.Add(sym.name,sym); + end; end; end; @@ -1403,7 +1408,6 @@ implementation {$endif} generictokenbuf:=nil; genericdef:=nil; - genericparas:=tfphashobjectlist.create(false); { Don't register forwarddefs, they are disposed at the end of an type block } @@ -1450,7 +1454,6 @@ implementation buf : array[0..255] of byte; begin inherited create(dt); - genericparas:=tfphashobjectlist.create(false); DefId:=ppufile.getlongint; current_module.deflist[DefId]:=self; {$ifdef EXTDEBUG} @@ -1697,13 +1700,17 @@ implementation function tstoreddef.is_generic: boolean; begin - result:=(genericparas.count>0) and (df_generic in defoptions); + result:=assigned(genericparas) and + (genericparas.count>0) and + (df_generic in defoptions); end; function tstoreddef.is_specialization: boolean; begin - result:=(genericparas.count>0) and (df_specialization in defoptions); + result:=assigned(genericparas) and + (genericparas.count>0) and + (df_specialization in defoptions); end;