Pārlūkot izejas kodu

Fix for Mantis #22219

ptype.pas:
  * read_named_type: 
      after reading the type we're pointing to we need to make sure that
      we didn't get a generic dummy symbol; this can happen when parsing
      a pointer declaration as the type in a constant or variable 
      declaration
  * resolve_forward_types:
      when resolving forward types we need to make sure that we weren't
      given a generic dummy to which no non-generic definition was
      given (possible in Delphi mode); for non-Delphi modes we can not
      rely on the generic dummy flag as the typedef of the symbol will
      the generic def
+ added test from the bug reports as well as three additional ones to
  make sure that nothing breaks regarding to forward pointer 
  declarations
      

git-svn-id: trunk@21687 -
svenbarth 13 gadi atpakaļ
vecāks
revīzija
8c95ea039f

+ 4 - 0
.gitattributes

@@ -10720,6 +10720,9 @@ tests/test/tgeneric77.pp svneol=native#text/pascal
 tests/test/tgeneric78.pp svneol=native#text/pascal
 tests/test/tgeneric79.pp svneol=native#text/pascal
 tests/test/tgeneric8.pp svneol=native#text/plain
+tests/test/tgeneric80.pp svneol=native#text/pascal
+tests/test/tgeneric81.pp svneol=native#text/pascal
+tests/test/tgeneric82.pp svneol=native#text/pascal
 tests/test/tgeneric9.pp svneol=native#text/plain
 tests/test/tgoto.pp svneol=native#text/plain
 tests/test/theap.pp svneol=native#text/plain
@@ -11656,6 +11659,7 @@ tests/webtbf/tw21566.pp svneol=native#text/pascal
 tests/webtbf/tw2174.pp svneol=native#text/plain
 tests/webtbf/tw21873.pp svneol=native#text/plain
 tests/webtbf/tw2209.pp svneol=native#text/plain
+tests/webtbf/tw22219.pp svneol=native#text/pascal
 tests/webtbf/tw2242.pp svneol=native#text/plain
 tests/webtbf/tw2273.pp svneol=native#text/plain
 tests/webtbf/tw2281.pp svneol=native#text/plain

+ 21 - 0
compiler/ptype.pas

@@ -151,6 +151,20 @@ implementation
                            not(is_objcclass(ttypesym(srsym).typedef)) and
                            not(is_javaclass(ttypesym(srsym).typedef)) then
                           MessagePos1(def.typesym.fileinfo,type_e_class_type_expected,ttypesym(srsym).typedef.typename);
+                        { this could also be a generic dummy that was not
+                          overridden with a specific type }
+                        if (sp_generic_dummy in srsym.symoptions) and
+                            (
+                              (ttypesym(srsym).typedef.typ=undefineddef) or
+                              (
+                                { or an unspecialized generic symbol, which is
+                                  the case for generics defined in non-Delphi
+                                  modes }
+                                (df_generic in ttypesym(srsym).typedef.defoptions) and
+                                not parse_generic
+                              )
+                            ) then
+                          MessagePos(def.typesym.fileinfo,parser_e_no_generics_as_types);
                       end
                      else
                       begin
@@ -1446,6 +1460,13 @@ implementation
               begin
                 consume(_CARET);
                 single_type(tt2,SingleTypeOptionsInTypeBlock[block_type=bt_type]);
+                { 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
+                    (tt2.typ=undefineddef) and
+                    assigned(tt2.typesym) and
+                    (sp_generic_dummy in tt2.typesym.symoptions) then
+                  Message(parser_e_no_generics_as_types);
                 { don't use getpointerdef() here, since this is a type
                   declaration (-> must create new typedef) }
                 def:=tpointerdef.create(tt2);

+ 18 - 0
tests/test/tgeneric80.pp

@@ -0,0 +1,18 @@
+{ %NORUN }
+
+program tgeneric80;
+
+{$mode delphi}
+
+type
+  TTest<T, S> = record
+  end;
+  TTest<T> = record
+  end;
+  PTest = ^TTest;
+  TTest = record
+  end;
+
+begin
+
+end.

+ 18 - 0
tests/test/tgeneric81.pp

@@ -0,0 +1,18 @@
+{ %NORUN }
+
+program tgeneric81;
+
+{$mode delphi}
+
+type
+  PTest = ^TTest;
+  TTest<T, S> = record
+  end;
+  TTest<T> = record
+  end;
+  TTest = record
+  end;
+
+begin
+
+end.

+ 18 - 0
tests/test/tgeneric82.pp

@@ -0,0 +1,18 @@
+{ %NORUN }
+
+program tgeneric82;
+
+{$mode delphi}
+
+type
+  TTest = record
+  end;
+  TTest<T, S> = record
+  end;
+  TTest<T> = record
+  end;
+  PTest = ^TTest;
+
+begin
+
+end.

+ 16 - 0
tests/webtbf/tw22219.pp

@@ -0,0 +1,16 @@
+{ %FAIL }
+
+program tw22219;
+{$MODE DELPHI}
+
+type
+  TWrapper<P, Q> = record end;
+  TWrapper<R> = record end;
+  AmbiguousPointer = ^TWrapper;
+
+var
+  Z: AmbiguousPointer;
+
+begin
+
+end.