From cc65ac20c5150e9ce5a30b4d375f93397c202052 Mon Sep 17 00:00:00 2001 From: svenbarth <pascaldragon@googlemail.com> Date: Sun, 24 Jun 2012 10:35:21 +0000 Subject: [PATCH] Fix for Mantis #22220 ptype.pas: * read_named_type: allow specializations for pointers in Delphi modes * single_type: correctly handle forwarddefs; as we can only specialize generics if they are completely defined (srsym<>nil) we don't need to return a forward def, but instead return the specialized def itself + added tests to "test" instead of "webtbs" as no explicit tests were given in the report git-svn-id: trunk@21689 - --- .gitattributes | 4 ++++ compiler/ptype.pas | 22 ++++++++++++++++++++-- tests/test/tgeneric87.pp | 18 ++++++++++++++++++ tests/test/tgeneric88.pp | 17 +++++++++++++++++ tests/test/tgeneric89.pp | 17 +++++++++++++++++ tests/test/tgeneric90.pp | 26 ++++++++++++++++++++++++++ 6 files changed, 102 insertions(+), 2 deletions(-) create mode 100644 tests/test/tgeneric87.pp create mode 100644 tests/test/tgeneric88.pp create mode 100644 tests/test/tgeneric89.pp create mode 100644 tests/test/tgeneric90.pp diff --git a/.gitattributes b/.gitattributes index bb9602aec3..e3ed8e9d2e 100644 --- a/.gitattributes +++ b/.gitattributes @@ -10727,7 +10727,11 @@ tests/test/tgeneric83.pp svneol=native#text/pascal tests/test/tgeneric84.pp svneol=native#text/pascal tests/test/tgeneric85.pp svneol=native#text/pascal tests/test/tgeneric86.pp svneol=native#text/pascal +tests/test/tgeneric87.pp svneol=native#text/pascal +tests/test/tgeneric88.pp svneol=native#text/pascal +tests/test/tgeneric89.pp svneol=native#text/pascal tests/test/tgeneric9.pp svneol=native#text/plain +tests/test/tgeneric90.pp svneol=native#text/pascal tests/test/tgoto.pp svneol=native#text/plain tests/test/theap.pp svneol=native#text/plain tests/test/theapthread.pp svneol=native#text/plain diff --git a/compiler/ptype.pas b/compiler/ptype.pas index d0972f94c6..cf2d8a0af8 100644 --- a/compiler/ptype.pas +++ b/compiler/ptype.pas @@ -439,8 +439,22 @@ implementation if ([stoAllowSpecialization,stoAllowTypeDef] * options <> []) and (m_delphi in current_settings.modeswitches) then dospecialize:=token in [_LSHARPBRACKET,_LT]; + if dospecialize and + (def.typ=forwarddef) then + begin + if not assigned(srsym) or not (srsym.typ=typesym) then + begin + Message(type_e_type_is_not_completly_defined); + def:=generrordef; + dospecialize:=false; + end; + end; if dospecialize then - generate_specialization(def,stoParseClassParent in options,'',nil,'') + begin + if def.typ=forwarddef then + def:=ttypesym(srsym).typedef; + generate_specialization(def,stoParseClassParent in options,'',nil,''); + end else begin if assigned(current_specializedef) and (def=current_specializedef.genericdef) then @@ -1330,6 +1344,7 @@ implementation const SingleTypeOptionsInTypeBlock:array[Boolean] of TSingleTypeOptions = ([],[stoIsForwardDef]); + SingleTypeOptionsIsDelphi:array[Boolean] of TSingleTypeOptions = ([],[stoAllowSpecialization]); var p : tnode; hdef : tdef; @@ -1459,7 +1474,10 @@ implementation _CARET: begin consume(_CARET); - single_type(tt2,SingleTypeOptionsInTypeBlock[block_type=bt_type]); + single_type(tt2, + SingleTypeOptionsInTypeBlock[block_type=bt_type]+ + SingleTypeOptionsIsDelphi[m_delphi in current_settings.modeswitches] + ); { in case of e.g. var or const sections we need to especially check that we don't use a generic dummy symbol } if (block_type<>bt_type) and diff --git a/tests/test/tgeneric87.pp b/tests/test/tgeneric87.pp new file mode 100644 index 0000000000..33e2afc92c --- /dev/null +++ b/tests/test/tgeneric87.pp @@ -0,0 +1,18 @@ +{ %FAIL } + +program tgeneric87; + +{$mode objfpc} + +type + generic TTest<T> = record + + end; + +const + TestLongIntNil: ^specialize TTest<LongInt> = Nil; + TestBooleanNil: ^specialize TTest<Boolean> = Nil; + +begin + +end. diff --git a/tests/test/tgeneric88.pp b/tests/test/tgeneric88.pp new file mode 100644 index 0000000000..c8233ee7e2 --- /dev/null +++ b/tests/test/tgeneric88.pp @@ -0,0 +1,17 @@ +{ %FAIL } + +program tgeneric88; + +{$mode objfpc} + +type + generic TTest<T> = record + + end; + + PTestLongInt = ^specialize TTest<LongInt>; + PTestBoolean = ^specialize TTest<Boolean>; + +begin + +end. diff --git a/tests/test/tgeneric89.pp b/tests/test/tgeneric89.pp new file mode 100644 index 0000000000..5e50ef1549 --- /dev/null +++ b/tests/test/tgeneric89.pp @@ -0,0 +1,17 @@ +{ %NORUN } + +program tgeneric89; + +{$mode delphi} + +type + TTest<T> = record + + end; + + PTestLongInt = ^TTest<LongInt>; + PTestBoolean = ^TTest<Boolean>; + +begin + +end. diff --git a/tests/test/tgeneric90.pp b/tests/test/tgeneric90.pp new file mode 100644 index 0000000000..0c9ae3c4cb --- /dev/null +++ b/tests/test/tgeneric90.pp @@ -0,0 +1,26 @@ +{ %NORUN } + +program tgeneric90; + +{$mode delphi} + +type + TTest = record + + end; + + TTest<T> = record + + end; + + TTest<T, S> = record + + end; + + PTestLongInt = ^TTest<LongInt>; + PTestLongIntLongInt = ^TTest<LongInt, LongInt>; + PTest = ^TTest; + +begin + +end.