From b38fb606cc0afd0a1dd6ca17f98c735d1a570d86 Mon Sep 17 00:00:00 2001 From: svenbarth Date: Sun, 21 Dec 2014 14:01:32 +0000 Subject: [PATCH] Fix for Mantis #27185. ngenutil.pas: * AddToStructInits: also process the class constructors/destructors of nested types + added test git-svn-id: trunk@29308 - --- .gitattributes | 1 + compiler/ngenutil.pas | 11 +++-- tests/webtbs/tw27185.pp | 99 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 108 insertions(+), 3 deletions(-) create mode 100644 tests/webtbs/tw27185.pp diff --git a/.gitattributes b/.gitattributes index 5a4214d212..f76a9a7eac 100644 --- a/.gitattributes +++ b/.gitattributes @@ -14172,6 +14172,7 @@ tests/webtbs/tw2710.pp svneol=native#text/plain tests/webtbs/tw27120.pp svneol=native#text/pascal tests/webtbs/tw2713.pp svneol=native#text/plain tests/webtbs/tw27153.pp svneol=native#text/pascal +tests/webtbs/tw27185.pp svneol=native#text/pascal tests/webtbs/tw2721.pp svneol=native#text/plain tests/webtbs/tw2723.pp svneol=native#text/plain tests/webtbs/tw2725.pp svneol=native#text/plain diff --git a/compiler/ngenutil.pas b/compiler/ngenutil.pas index 1811029fb1..b5ade1e119 100644 --- a/compiler/ngenutil.pas +++ b/compiler/ngenutil.pas @@ -605,9 +605,14 @@ implementation StructList: TFPList absolute arg; begin if (tdef(p).typ in [objectdef,recorddef]) and - not (df_generic in tdef(p).defoptions) and - ([oo_has_class_constructor,oo_has_class_destructor] * tabstractrecorddef(p).objectoptions <> []) then - StructList.Add(p); + not (df_generic in tdef(p).defoptions) then + begin + { first add the class... } + if ([oo_has_class_constructor,oo_has_class_destructor] * tabstractrecorddef(p).objectoptions <> []) then + StructList.Add(p); + { ... and then also add all subclasses } + tabstractrecorddef(p).symtable.deflist.foreachcall(@AddToStructInits,arg); + end; end; diff --git a/tests/webtbs/tw27185.pp b/tests/webtbs/tw27185.pp new file mode 100644 index 0000000000..d90ef66c48 --- /dev/null +++ b/tests/webtbs/tw27185.pp @@ -0,0 +1,99 @@ +program tw27185; + +{$mode objfpc}{$H+} + +uses + {$IFDEF UNIX}{$IFDEF UseCThreads} + cthreads, + {$ENDIF}{$ENDIF} + Classes + { you can add units after this }; + +var + NormalClassInit: Boolean = False; + NormalClassDone: Boolean = False; + NestedTypeClassInit: Boolean = False; + NestedTypeClassDone: Boolean = False; + NestedTypeClassNestedClassInit: Boolean = False; + NestedTypeClassNestedClassDone: Boolean = False; + +Type + + { TNormalClass } + + TNormalClass = class + public + class constructor Create; + class destructor Destroy; + end; + + { TNestedTypeClass } + + TNestedTypeClass = class + private + type + + { TNestedClass } + + TNestedClass = class + public + class constructor Create; + class destructor Destroy; + end; + + public + class constructor Create; + class destructor Destroy; + end; + +{ TNestedTypeClass } + +class constructor TNestedTypeClass.Create; +begin + NestedTypeClassInit := True; + //WriteLn('class constructor TNestedTypeClass.Create'); +end; + +class destructor TNestedTypeClass.Destroy; +begin + NestedTypeClassDone := True; + //WriteLn('class destructor TNestedTypeClass.Destroy'); +end; + +{ TNormalClass } + +class constructor TNormalClass.Create; +begin + NormalClassInit := True; + //WriteLn('class constructor TNormalClass.Create'); +end; + +class destructor TNormalClass.Destroy; +begin + NormalClassDone := False; + //WriteLn('class destructor TNormalClass.Destroy'); +end; + +{ TNestedTypeClass.TNestedClass } + +class constructor TNestedTypeClass.TNestedClass.Create; +begin + NestedTypeClassNestedClassInit := True; + //WriteLn('class constructor TNestedTypeClass.TNestedClass.Create'); +end; + +class destructor TNestedTypeClass.TNestedClass.Destroy; +begin + NestedTypeClassNestedClassDone := True; + //WriteLn('class destructor TNestedTypeClass.TNestedClass.Destroy'); +end; + +begin + if not NormalClassInit then + Halt(1); + if not NestedTypeClassInit then + Halt(2); + if not NestedTypeClassNestedClassInit then + Halt(3); +end. +