Browse Source

Fix for Mantis #26483. This regression was introduced by famous revision 27861 which introduced partial specializations (and thus that specializations can be part of local- and parasymtables as well).

symtable.pas, is_visible_for_object:
  * if the symtable belongs to a specialization we need to ignore any owning local- or parasymtable as well to determine which unit it belongs to

+ added test

git-svn-id: trunk@29482 -
svenbarth 10 years ago
parent
commit
5fd47d5e00
3 changed files with 37 additions and 6 deletions
  1. 1 0
      .gitattributes
  2. 12 6
      compiler/symtable.pas
  3. 24 0
      tests/webtbs/tw26483.pp

+ 1 - 0
.gitattributes

@@ -14149,6 +14149,7 @@ tests/webtbs/tw2645.pp svneol=native#text/plain
 tests/webtbs/tw26467.pp svneol=native#text/pascal
 tests/webtbs/tw26467.pp svneol=native#text/pascal
 tests/webtbs/tw2647.pp svneol=native#text/plain
 tests/webtbs/tw2647.pp svneol=native#text/plain
 tests/webtbs/tw26482.pp svneol=native#text/pascal
 tests/webtbs/tw26482.pp svneol=native#text/pascal
+tests/webtbs/tw26483.pp svneol=native#text/pascal
 tests/webtbs/tw2649.pp svneol=native#text/plain
 tests/webtbs/tw2649.pp svneol=native#text/plain
 tests/webtbs/tw2651.pp svneol=native#text/plain
 tests/webtbs/tw2651.pp svneol=native#text/plain
 tests/webtbs/tw26536.pp svneol=native#text/plain
 tests/webtbs/tw26536.pp svneol=native#text/plain

+ 12 - 6
compiler/symtable.pas

@@ -2211,6 +2211,7 @@ implementation
     function is_visible_for_object(symst:tsymtable;symvisibility:tvisibility;contextobjdef:tabstractrecorddef):boolean;
     function is_visible_for_object(symst:tsymtable;symvisibility:tvisibility;contextobjdef:tabstractrecorddef):boolean;
       var
       var
         symownerdef : tabstractrecorddef;
         symownerdef : tabstractrecorddef;
+        nonlocalst : tsymtable;
       begin
       begin
         result:=false;
         result:=false;
 
 
@@ -2219,17 +2220,22 @@ implementation
            not (symst.symtabletype in [objectsymtable,recordsymtable]) then
            not (symst.symtabletype in [objectsymtable,recordsymtable]) then
           internalerror(200810285);
           internalerror(200810285);
         symownerdef:=tabstractrecorddef(symst.defowner);
         symownerdef:=tabstractrecorddef(symst.defowner);
+        { specializations might belong to a localsymtable or parasymtable }
+        nonlocalst:=symownerdef.owner;
+        if tstoreddef(symst.defowner).is_specialization then
+          while nonlocalst.symtabletype in [localsymtable,parasymtable] do
+            nonlocalst:=nonlocalst.defowner.owner;
         case symvisibility of
         case symvisibility of
           vis_private :
           vis_private :
             begin
             begin
               { private symbols are allowed when we are in the same
               { private symbols are allowed when we are in the same
                 module as they are defined }
                 module as they are defined }
               result:=(
               result:=(
-                       (symownerdef.owner.symtabletype in [globalsymtable,staticsymtable]) and
-                       (symownerdef.owner.iscurrentunit)
+                       (nonlocalst.symtabletype in [globalsymtable,staticsymtable]) and
+                       (nonlocalst.iscurrentunit)
                       ) or
                       ) or
                       ( // the case of specialize inside the generic declaration and nested types
                       ( // the case of specialize inside the generic declaration and nested types
-                       (symownerdef.owner.symtabletype in [objectsymtable,recordsymtable]) and
+                       (nonlocalst.symtabletype in [objectsymtable,recordsymtable]) and
                        (
                        (
                          assigned(current_structdef) and
                          assigned(current_structdef) and
                          (
                          (
@@ -2281,8 +2287,8 @@ implementation
                 in the current module }
                 in the current module }
               result:=(
               result:=(
                        (
                        (
-                        (symownerdef.owner.symtabletype in [globalsymtable,staticsymtable]) and
-                        (symownerdef.owner.iscurrentunit)
+                        (nonlocalst.symtabletype in [globalsymtable,staticsymtable]) and
+                        (nonlocalst.iscurrentunit)
                        ) or
                        ) or
                        (
                        (
                         assigned(contextobjdef) and
                         assigned(contextobjdef) and
@@ -2291,7 +2297,7 @@ implementation
                         def_is_related(contextobjdef,symownerdef)
                         def_is_related(contextobjdef,symownerdef)
                        ) or
                        ) or
                        ( // the case of specialize inside the generic declaration and nested types
                        ( // the case of specialize inside the generic declaration and nested types
-                        (symownerdef.owner.symtabletype in [objectsymtable,recordsymtable]) and
+                        (nonlocalst.symtabletype in [objectsymtable,recordsymtable]) and
                         (
                         (
                           assigned(current_structdef) and
                           assigned(current_structdef) and
                           (
                           (

+ 24 - 0
tests/webtbs/tw26483.pp

@@ -0,0 +1,24 @@
+{ %NORUN }
+
+program tw26483;
+
+{$MODE DELPHI}
+
+type
+  TA<T> = class
+  private
+    F: Integer;
+  end;
+
+  TB<T> = class
+    procedure Foo(A: TObject);
+  end;
+
+procedure TB<T>.Foo(A: TObject);
+begin
+  WriteLn(TA<T>(A).F); // p004.Error: identifier idents no member "F"
+end;
+
+begin
+end.
+