Browse Source

+ strict protected and strict private support

git-svn-id: trunk@512 -
florian 20 years ago
parent
commit
abbc85bb78

+ 5 - 0
.gitattributes

@@ -4419,6 +4419,10 @@ tests/tbf/tb0170.pp svneol=native#text/plain
 tests/tbf/tb0171.pp svneol=native#text/plain
 tests/tbf/tb0171.pp svneol=native#text/plain
 tests/tbf/tb0172.pp svneol=native#text/plain
 tests/tbf/tb0172.pp svneol=native#text/plain
 tests/tbf/tb0173.pp svneol=native#text/plain
 tests/tbf/tb0173.pp svneol=native#text/plain
+tests/tbf/tb0174a.pp svneol=native#text/plain
+tests/tbf/tb0174b.pp svneol=native#text/plain
+tests/tbf/tb0174c.pp svneol=native#text/plain
+tests/tbf/tb0174d.pp svneol=native#text/plain
 tests/tbf/ub0115.pp svneol=native#text/plain
 tests/tbf/ub0115.pp svneol=native#text/plain
 tests/tbf/ub0149.pp svneol=native#text/plain
 tests/tbf/ub0149.pp svneol=native#text/plain
 tests/tbf/ub0158a.pp svneol=native#text/plain
 tests/tbf/ub0158a.pp svneol=native#text/plain
@@ -4905,6 +4909,7 @@ tests/tbs/tb0489.pp svneol=native#text/plain
 tests/tbs/tb0490.pp svneol=native#text/plain
 tests/tbs/tb0490.pp svneol=native#text/plain
 tests/tbs/tb0491.pp svneol=native#text/plain
 tests/tbs/tb0491.pp svneol=native#text/plain
 tests/tbs/tb0492.pp svneol=native#text/plain
 tests/tbs/tb0492.pp svneol=native#text/plain
+tests/tbs/tb0493.pp svneol=native#text/plain
 tests/tbs/ub0060.pp svneol=native#text/plain
 tests/tbs/ub0060.pp svneol=native#text/plain
 tests/tbs/ub0069.pp svneol=native#text/plain
 tests/tbs/ub0069.pp svneol=native#text/plain
 tests/tbs/ub0119.pp svneol=native#text/plain
 tests/tbs/ub0119.pp svneol=native#text/plain

+ 2 - 0
compiler/msg/errore.msg

@@ -1008,6 +1008,8 @@ parser_e_no_static_method_in_interfaces=03212_E_Class and static methods can't b
 % because all methods of an interfaces must be public.
 % because all methods of an interfaces must be public.
 parser_e_arithmetic_operation_overflow=03213_E_Overflow in arithmetic operation
 parser_e_arithmetic_operation_overflow=03213_E_Overflow in arithmetic operation
 % An operation on two integers values produced an overflow
 % An operation on two integers values produced an overflow
+parser_e_protected_or_private_expected=03214_E_Protected or private expected
+% \var{strict} can be only used together with \var{protected} or \var{private}.
 % \end{description}
 % \end{description}
 #
 #
 # Type Checking
 # Type Checking

+ 34 - 7
compiler/pdecobj.pas

@@ -561,17 +561,44 @@ implementation
                            consume(_PUBLISHED);
                            consume(_PUBLISHED);
                            current_object_option:=[sp_published];
                            current_object_option:=[sp_published];
                          end;
                          end;
-                       else
+                       _STRICT :
                          begin
                          begin
                            if is_interface(aktclass) then
                            if is_interface(aktclass) then
-                             Message(parser_e_no_vars_in_interfaces);
+                              Message(parser_e_no_access_specifier_in_interfaces);
+                            consume(_STRICT);
+                            if token=_ID then
+                              begin
+                                case idtoken of
+                                  _PRIVATE:
+                                    begin
+                                      consume(_PRIVATE);
+                                      current_object_option:=[sp_strictprivate];
+                                      include(aktclass.objectoptions,oo_has_strictprivate);
+                                    end;
+                                  _PROTECTED:
+                                    begin
+                                      consume(_PROTECTED);
+                                      current_object_option:=[sp_strictprotected];
+                                      include(aktclass.objectoptions,oo_has_strictprotected);
+                                    end;
+                                  else
+                                    message(parser_e_protected_or_private_expected);
+                                end;
+                              end
+                            else
+                              message(parser_e_protected_or_private_expected);
+                          end;
+                        else
+                          begin
+                            if is_interface(aktclass) then
+                              Message(parser_e_no_vars_in_interfaces);
 
 
-                           if (sp_published in current_object_option) and
-                             not(oo_can_have_published in aktclass.objectoptions) then
-                             Message(parser_e_cant_have_published);
+                            if (sp_published in current_object_option) and
+                              not(oo_can_have_published in aktclass.objectoptions) then
+                              Message(parser_e_cant_have_published);
 
 
-                           read_var_decs(false,true,false);
-                         end;
+                            read_var_decs(false,true,false);
+                          end;
                     end;
                     end;
                   end;
                   end;
                 _PROPERTY :
                 _PROPERTY :

+ 1 - 1
compiler/pdecvar.pas

@@ -721,7 +721,7 @@ implementation
          { read vars }
          { read vars }
          sc:=tsinglelist.create;
          sc:=tsinglelist.create;
          while (token=_ID) and
          while (token=_ID) and
-               not(is_object and (idtoken in [_PUBLIC,_PRIVATE,_PUBLISHED,_PROTECTED])) do
+               not(is_object and (idtoken in [_PUBLIC,_PRIVATE,_PUBLISHED,_PROTECTED,_STRICT])) do
            begin
            begin
              sorg:=orgpattern;
              sorg:=orgpattern;
              semicoloneaten:=false;
              semicoloneaten:=false;

+ 3 - 3
compiler/ptype.pas

@@ -550,19 +550,19 @@ implementation
                      { don't forget that min can be negativ  PM }
                      { don't forget that min can be negativ  PM }
                      enumdef :
                      enumdef :
                        if tenumdef(tt2.def).min>=0 then
                        if tenumdef(tt2.def).min>=0 then
-                        tt.setdef(tsetdef.create(tt2,tenumdef(tt2.def).max))
+                        tt.setdef(tsetdef.create(tt2,tenumdef(tt2.def).min,tenumdef(tt2.def).max))
                        else
                        else
                         Message(sym_e_ill_type_decl_set);
                         Message(sym_e_ill_type_decl_set);
                      orddef :
                      orddef :
                        begin
                        begin
                          case torddef(tt2.def).typ of
                          case torddef(tt2.def).typ of
                            uchar :
                            uchar :
-                             tt.setdef(tsetdef.create(tt2,255));
+                             tt.setdef(tsetdef.create(tt2,0,255));
                            u8bit,u16bit,u32bit,
                            u8bit,u16bit,u32bit,
                            s8bit,s16bit,s32bit :
                            s8bit,s16bit,s32bit :
                              begin
                              begin
                                if (torddef(tt2.def).low>=0) then
                                if (torddef(tt2.def).low>=0) then
-                                tt.setdef(tsetdef.create(tt2,torddef(tt2.def).high))
+                                tt.setdef(tsetdef.create(tt2,torddef(tt2.def).low,torddef(tt2.def).high))
                                else
                                else
                                 Message(sym_e_ill_type_decl_set);
                                 Message(sym_e_ill_type_decl_set);
                              end;
                              end;

+ 8 - 2
compiler/symconst.pas

@@ -145,7 +145,9 @@ type
     sp_hint_library,
     sp_hint_library,
     sp_hint_unimplemented,
     sp_hint_unimplemented,
     sp_has_overloaded,
     sp_has_overloaded,
-    sp_internal  { internal symbol, not reported as unused }
+    sp_internal,  { internal symbol, not reported as unused }
+    sp_strictprivate,
+    sp_strictprotected
   );
   );
   tsymoptions=set of tsymoption;
   tsymoptions=set of tsymoption;
 
 
@@ -201,7 +203,7 @@ type
 
 
   { set types }
   { set types }
   tsettype = (
   tsettype = (
-    normset,smallset,varset
+    normset,smallset
   );
   );
 
 
   tvarianttype = (
   tvarianttype = (
@@ -283,6 +285,8 @@ type
     oo_has_virtual,        { the object/class has virtual methods }
     oo_has_virtual,        { the object/class has virtual methods }
     oo_has_private,
     oo_has_private,
     oo_has_protected,
     oo_has_protected,
+    oo_has_strictprivate,
+    oo_has_strictprotected,
     oo_has_constructor,    { the object/class has a constructor }
     oo_has_constructor,    { the object/class has a constructor }
     oo_has_destructor,     { the object/class has a destructor }
     oo_has_destructor,     { the object/class has a destructor }
     oo_has_vmt,            { the object/class has a vmt }
     oo_has_vmt,            { the object/class has a vmt }
@@ -410,6 +414,8 @@ const
 
 
 
 
 const
 const
+   inherited_objectoptions : tobjectoptions = [oo_has_virtual,oo_has_private,oo_has_protected,
+                oo_has_strictprotected,oo_has_strictprivate,oo_has_constructor,oo_has_destructor];
    clearstack_pocalls = [
    clearstack_pocalls = [
      pocall_cdecl,pocall_cppdecl,pocall_syscall
      pocall_cdecl,pocall_cppdecl,pocall_syscall
    ];
    ];

+ 30 - 9
compiler/symdef.pas

@@ -705,7 +705,9 @@ interface
        tsetdef = class(tstoreddef)
        tsetdef = class(tstoreddef)
           elementtype : ttype;
           elementtype : ttype;
           settype : tsettype;
           settype : tsettype;
-          constructor create(const t:ttype;high : longint);
+          setbase,
+          setmax : aint;
+          constructor create(const t:ttype;low,high : aint);
           constructor ppuload(ppufile:tcompilerppufile);
           constructor ppuload(ppufile:tcompilerppufile);
           destructor  destroy;override;
           destructor  destroy;override;
           function getcopy : tstoreddef;override;
           function getcopy : tstoreddef;override;
@@ -2714,7 +2716,9 @@ implementation
          inherited create;
          inherited create;
          deftype:=setdef;
          deftype:=setdef;
          elementtype:=t;
          elementtype:=t;
-         if high<32 then
+         setbase:=low;
+         setmax:=high;
+         if (high-low)+1<=32 then
            begin
            begin
             settype:=smallset;
             settype:=smallset;
            {$ifdef testvarsets}
            {$ifdef testvarsets}
@@ -2757,6 +2761,9 @@ implementation
             varset : savesize:=ppufile.getlongint;
             varset : savesize:=ppufile.getlongint;
             smallset : savesize:=Sizeof(longint);
             smallset : savesize:=Sizeof(longint);
          end;
          end;
+          normset : savesize:=ppufile.getaint;
+          smallset : savesize:=Sizeof(longint);
+        end;
       end;
       end;
 
 
 
 
@@ -2786,6 +2793,8 @@ implementation
          ppufile.putbyte(byte(settype));
          ppufile.putbyte(byte(settype));
          if settype=varset then
          if settype=varset then
            ppufile.putlongint(savesize);
            ppufile.putlongint(savesize);
+         if settype=normset then
+           ppufile.putaint(savesize);
          ppufile.writeentry(ibsetdef);
          ppufile.writeentry(ibsetdef);
       end;
       end;
 
 
@@ -3202,9 +3211,9 @@ implementation
         { static variables from objects are like global objects }
         { static variables from objects are like global objects }
         if (Tsym(p).typ=fieldvarsym) and not (sp_static in Tsym(p).symoptions) then
         if (Tsym(p).typ=fieldvarsym) and not (sp_static in Tsym(p).symoptions) then
           begin
           begin
-            if (sp_protected in tsym(p).symoptions) then
+            if ([sp_protected,sp_strictprotected]*tsym(p).symoptions)<>[] then
               spec:='/1'
               spec:='/1'
-            else if (sp_private in tsym(p).symoptions) then
+            else if ([sp_private,sp_strictprivate]*tsym(p).symoptions)<>[] then
               spec:='/0'
               spec:='/0'
             else
             else
               spec:='';
               spec:='';
@@ -4069,7 +4078,20 @@ implementation
            not(owner.defowner.owner.iscurrentunit) then
            not(owner.defowner.owner.iscurrentunit) then
           exit;
           exit;
 
 
-        { protected symbols are vissible in the module that defines them and
+        if (sp_strictprivate in symoptions) then
+          begin
+            result:=currobjdef=tobjectdef(owner.defowner);
+            exit;
+          end;
+
+        if (sp_strictprotected in symoptions) then
+          begin
+             result:=assigned(currobjdef) and
+               currobjdef.is_related(tobjectdef(owner.defowner));
+             exit;
+          end;
+
+        { protected symbols are visible in the module that defines them and
           also visible to related objects. The related object must be defined
           also visible to related objects. The related object must be defined
           in the current module }
           in the current module }
         if (sp_protected in symoptions) and
         if (sp_protected in symoptions) and
@@ -5139,8 +5161,7 @@ implementation
              { only important for classes }
              { only important for classes }
              lastvtableindex:=c.lastvtableindex;
              lastvtableindex:=c.lastvtableindex;
              objectoptions:=objectoptions+(c.objectoptions*
              objectoptions:=objectoptions+(c.objectoptions*
-               [oo_has_virtual,oo_has_private,oo_has_protected,
-                oo_has_constructor,oo_has_destructor]);
+               inherited_objectoptions);
              if not (objecttype in [odt_interfacecom,odt_interfacecorba]) then
              if not (objecttype in [odt_interfacecom,odt_interfacecorba]) then
                begin
                begin
                   { add the data of the anchestor class }
                   { add the data of the anchestor class }
@@ -5387,9 +5408,9 @@ implementation
               end;
               end;
            { here 2A must be changed for private and protected }
            { here 2A must be changed for private and protected }
            { 0 is private 1 protected and 2 public }
            { 0 is private 1 protected and 2 public }
-           if (sp_private in tsym(p).symoptions) then
+           if ([sp_private,sp_strictprivate]*tsym(p).symoptions)<>[] then
              sp:='0'
              sp:='0'
-           else if (sp_protected in tsym(p).symoptions) then
+           else if ([sp_protected,sp_strictprocted*tsym(p).symoptions)<>[] then
              sp:='1'
              sp:='1'
            else
            else
              sp:='2';
              sp:='2';

+ 6 - 2
compiler/symsym.pas

@@ -125,7 +125,11 @@ interface
           function search_procdef_byprocvardef(d:Tprocvardef):Tprocdef;
           function search_procdef_byprocvardef(d:Tprocvardef):Tprocdef;
           function search_procdef_assignment_operator(fromdef,todef:tdef;var besteq:tequaltype):Tprocdef;
           function search_procdef_assignment_operator(fromdef,todef:tdef;var besteq:tequaltype):Tprocdef;
           function  write_references(ppufile:tcompilerppufile;locals:boolean):boolean;override;
           function  write_references(ppufile:tcompilerppufile;locals:boolean):boolean;override;
-          function is_visible_for_object(currobjdef:tdef):boolean;override;
+          { currobjdef is the object def to assume, this is necessary for protected and
+            private,
+            context is the object def we're really in, this is for the strict stuff
+          }
+          function is_visible_for_object(currobjdef:tdef;context:tdef):boolean;override;
 {$ifdef GDB}
 {$ifdef GDB}
           function stabstring : pchar;override;
           function stabstring : pchar;override;
 {$endif GDB}
 {$endif GDB}
@@ -1107,7 +1111,7 @@ implementation
       end;
       end;
 
 
 
 
-    function tprocsym.is_visible_for_object(currobjdef:tdef):boolean;
+    function tprocsym.is_visible_for_object(currobjdef:tdef;context:tdef):boolean;
       var
       var
         p : pprocdeflist;
         p : pprocdeflist;
       begin
       begin

+ 15 - 10
compiler/symtable.pas

@@ -1196,7 +1196,7 @@ implementation
               { but private ids can be reused }
               { but private ids can be reused }
               hsym:=search_class_member(tobjectdef(defowner),sym.name);
               hsym:=search_class_member(tobjectdef(defowner),sym.name);
               if assigned(hsym) and
               if assigned(hsym) and
-                 Tsym(hsym).is_visible_for_object(tobjectdef(defowner)) then
+                 tsym(hsym).is_visible_for_object(tobjectdef(defowner),tobjectdef(defowner)) then
                 DuplicateSym(sym,hsym);
                 DuplicateSym(sym,hsym);
            end;
            end;
          inherited insert(sym);
          inherited insert(sym);
@@ -1282,7 +1282,7 @@ implementation
                hsym:=search_class_member(tobjectdef(next.next.defowner),sym.name);
                hsym:=search_class_member(tobjectdef(next.next.defowner),sym.name);
                if assigned(hsym) and
                if assigned(hsym) and
                  { private ids can be reused }
                  { private ids can be reused }
-                  (hsym.is_visible_for_object(tobjectdef(next.next.defowner)) or
+                  (hsym.is_visible_for_object(tobjectdef(next.next.defowner),tobjectdef(next.next.defowner)) or
                    (hsym.owner.defowner.owner.symtabletype<>globalsymtable)) then
                    (hsym.owner.defowner.owner.symtabletype<>globalsymtable)) then
                 begin
                 begin
                   { delphi allows to reuse the names in a class, but not
                   { delphi allows to reuse the names in a class, but not
@@ -1323,7 +1323,7 @@ implementation
               hsym:=search_class_member(tobjectdef(next.defowner),sym.name);
               hsym:=search_class_member(tobjectdef(next.defowner),sym.name);
               { private ids can be reused }
               { private ids can be reused }
               if assigned(hsym) and
               if assigned(hsym) and
-                 Tsym(hsym).is_visible_for_object(tobjectdef(next.defowner)) then
+                 Tsym(hsym).is_visible_for_object(tobjectdef(next.defowner),tobjectdef(next.defowner)) then
                begin
                begin
                  { delphi allows to reuse the names in a class, but not
                  { delphi allows to reuse the names in a class, but not
                    in object (tp7 compatible) }
                    in object (tp7 compatible) }
@@ -1809,6 +1809,7 @@ implementation
       var
       var
         speedvalue : cardinal;
         speedvalue : cardinal;
         topclass   : tobjectdef;
         topclass   : tobjectdef;
+        context : tobjectdef;
       begin
       begin
          speedvalue:=getspeedvalue(s);
          speedvalue:=getspeedvalue(s);
          srsymtable:=symtablestack;
          srsymtable:=symtablestack;
@@ -1831,7 +1832,11 @@ implementation
                      if assigned(current_procinfo) then
                      if assigned(current_procinfo) then
                        topclass:=current_procinfo.procdef._class;
                        topclass:=current_procinfo.procdef._class;
                    end;
                    end;
-                 if Tsym(srsym).is_visible_for_object(topclass) then
+                 if assigned(current_procinfo) then
+                   context:=current_procinfo.procdef._class
+                 else
+                   context:=nil;
+                 if tsym(srsym).is_visible_for_object(topclass,context) then
                    begin
                    begin
                      { we need to know if a procedure references symbols
                      { we need to know if a procedure references symbols
                        in the static symtable, because then it can't be
                        in the static symtable, because then it can't be
@@ -1868,7 +1873,7 @@ implementation
                   srsym:=tsym(srsymtable.speedsearch(s,speedvalue));
                   srsym:=tsym(srsymtable.speedsearch(s,speedvalue));
                   if assigned(srsym) and
                   if assigned(srsym) and
                      (not assigned(current_procinfo) or
                      (not assigned(current_procinfo) or
-                      Tsym(srsym).is_visible_for_object(current_procinfo.procdef._class)) then
+                      tsym(srsym).is_visible_for_object(current_procinfo.procdef._class,current_procinfo.procdef._class)) then
                     begin
                     begin
                       result:=true;
                       result:=true;
                       exit;
                       exit;
@@ -1909,7 +1914,7 @@ implementation
        end;
        end;
 
 
 
 
-    function  searchsym_in_class(classh:tobjectdef;const s : stringid):tsym;
+    function searchsym_in_class(classh:tobjectdef;const s : stringid):tsym;
       var
       var
         speedvalue : cardinal;
         speedvalue : cardinal;
         topclassh  : tobjectdef;
         topclassh  : tobjectdef;
@@ -1936,7 +1941,7 @@ implementation
           begin
           begin
             sym:=tsym(classh.symtable.speedsearch(s,speedvalue));
             sym:=tsym(classh.symtable.speedsearch(s,speedvalue));
             if assigned(sym) and
             if assigned(sym) and
-               Tsym(sym).is_visible_for_object(topclassh) then
+               Tsym(sym).is_visible_for_object(topclassh,current_procinfo.procdef._class) then
               break;
               break;
             classh:=classh.childof;
             classh:=classh.childof;
           end;
           end;
@@ -1944,7 +1949,7 @@ implementation
       end;
       end;
 
 
 
 
-    function  searchsym_in_class_by_msgint(classh:tobjectdef;i:longint):tsym;
+    function searchsym_in_class_by_msgint(classh:tobjectdef;i:longint):tsym;
       var
       var
         topclassh  : tobjectdef;
         topclassh  : tobjectdef;
         def        : tdef;
         def        : tdef;
@@ -1995,7 +2000,7 @@ implementation
       end;
       end;
 
 
 
 
-    function  searchsym_in_class_by_msgstr(classh:tobjectdef;const s:string):tsym;
+    function searchsym_in_class_by_msgstr(classh:tobjectdef;const s:string):tsym;
       var
       var
         topclassh  : tobjectdef;
         topclassh  : tobjectdef;
         def        : tdef;
         def        : tdef;
@@ -2218,7 +2223,7 @@ implementation
             begin
             begin
               if (srsym.typ<>procsym) then
               if (srsym.typ<>procsym) then
                internalerror(200111022);
                internalerror(200111022);
-              if srsym.is_visible_for_object(tobjectdef(aprocsym.owner.defowner)) then
+              if srsym.is_visible_for_object(tobjectdef(aprocsym.owner.defowner),tobjectdef(aprocsym.owner.defowner)) then
                begin
                begin
                  srsym.add_para_match_to(Aprocsym,[cpo_ignorehidden,cpo_allowdefaults]);
                  srsym.add_para_match_to(Aprocsym,[cpo_ignorehidden,cpo_allowdefaults]);
                  { we can stop if the overloads were already added
                  { we can stop if the overloads were already added

+ 21 - 3
compiler/symtype.pas

@@ -118,7 +118,11 @@ interface
          function  gettypedef:tdef;virtual;
          function  gettypedef:tdef;virtual;
          procedure load_references(ppufile:tcompilerppufile;locals:boolean);virtual;
          procedure load_references(ppufile:tcompilerppufile;locals:boolean);virtual;
          function  write_references(ppufile:tcompilerppufile;locals:boolean):boolean;virtual;
          function  write_references(ppufile:tcompilerppufile;locals:boolean):boolean;virtual;
-         function is_visible_for_object(currobjdef:Tdef):boolean;virtual;
+         { currobjdef is the object def to assume, this is necessary for protected and
+           private,
+           context is the object def we're really in, this is for the strict stuff
+         }
+         function is_visible_for_object(currobjdef:tdef;context : tdef):boolean;virtual;
       end;
       end;
 
 
       tsymarr = array[0..maxlongint div sizeof(pointer)-1] of tsym;
       tsymarr = array[0..maxlongint div sizeof(pointer)-1] of tsym;
@@ -475,7 +479,7 @@ implementation
       end;
       end;
 
 
 
 
-    function Tsym.is_visible_for_object(currobjdef:Tdef):boolean;
+    function Tsym.is_visible_for_object(currobjdef:Tdef;context : tdef):boolean;
       begin
       begin
         is_visible_for_object:=false;
         is_visible_for_object:=false;
 
 
@@ -487,7 +491,21 @@ implementation
            (not owner.defowner.owner.iscurrentunit) then
            (not owner.defowner.owner.iscurrentunit) then
           exit;
           exit;
 
 
-        { protected symbols are vissible in the module that defines them and
+        if (sp_strictprivate in symoptions) then
+          begin
+            result:=assigned(currobjdef) and
+              (context=tdef(owner.defowner));
+            exit;
+          end;
+
+        if (sp_strictprotected in symoptions) then
+          begin
+            result:=assigned(context) and
+              context.is_related(tdef(owner.defowner));
+            exit;
+          end;
+
+        { protected symbols are visible in the module that defines them and
           also visible to related objects }
           also visible to related objects }
         if (sp_protected in symoptions) and
         if (sp_protected in symoptions) and
            (
            (

+ 2 - 0
compiler/tokens.pas

@@ -167,6 +167,7 @@ type
     _RESULT,
     _RESULT,
     _STATIC,
     _STATIC,
     _STORED,
     _STORED,
+    _STRICT,
     _STRING,
     _STRING,
     _SYSTEM,
     _SYSTEM,
     _ASMNAME,
     _ASMNAME,
@@ -406,6 +407,7 @@ const
       (str:'RESULT'        ;special:false;keyword:m_none;op:NOTOKEN),
       (str:'RESULT'        ;special:false;keyword:m_none;op:NOTOKEN),
       (str:'STATIC'        ;special:false;keyword:m_none;op:NOTOKEN),
       (str:'STATIC'        ;special:false;keyword:m_none;op:NOTOKEN),
       (str:'STORED'        ;special:false;keyword:m_none;op:NOTOKEN),
       (str:'STORED'        ;special:false;keyword:m_none;op:NOTOKEN),
+      (str:'STRICT'        ;special:false;keyword:m_none;op:NOTOKEN),
       (str:'STRING'        ;special:false;keyword:m_all;op:NOTOKEN),
       (str:'STRING'        ;special:false;keyword:m_all;op:NOTOKEN),
       (str:'SYSTEM'        ;special:false;keyword:m_none;op:NOTOKEN),
       (str:'SYSTEM'        ;special:false;keyword:m_none;op:NOTOKEN),
       (str:'ASMNAME'       ;special:false;keyword:m_none;op:NOTOKEN),
       (str:'ASMNAME'       ;special:false;keyword:m_none;op:NOTOKEN),

+ 42 - 0
tests/tbf/tb0174a.pp

@@ -0,0 +1,42 @@
+{ %fail }
+{$mode objfpc}
+
+type
+  tobject1 = class
+  strict protected
+    spro : integer;
+  strict private
+    spriv : integer;
+  public
+    procedure p1;
+  end;
+
+
+  tobject2 = class(tobject1)
+    procedure p2;
+  end;
+
+procedure tobject1.p1;
+  begin
+    spro:=1;
+    spriv:=2;
+  end;
+
+procedure tobject2.p2;
+  begin
+    spro:=3;
+    spriv:=1;
+  end;
+
+var
+  o1 : tobject1;
+  o2 : tobject2;
+
+begin
+  o1:=tobject1.create;
+  o2:=tobject2.create;
+  o1.free;
+  o2.free;
+end.
+
+

+ 42 - 0
tests/tbf/tb0174b.pp

@@ -0,0 +1,42 @@
+{ %fail }
+{$mode objfpc}
+
+type
+  tobject1 = class
+  strict protected
+    spro : integer;
+  strict private
+    spriv : integer;
+  public
+    procedure p1;
+  end;
+
+
+  tobject2 = class(tobject1)
+    procedure p2;
+  end;
+
+procedure tobject1.p1;
+  begin
+    spro:=1;
+    spriv:=2;
+  end;
+
+procedure tobject2.p2;
+  begin
+    spro:=3;
+  end;
+
+var
+  o1 : tobject1;
+  o2 : tobject2;
+
+begin
+  o1:=tobject1.create;
+  o2:=tobject2.create;
+  o1.spro:=1;
+  o1.free;
+  o2.free;
+end.
+
+

+ 42 - 0
tests/tbf/tb0174c.pp

@@ -0,0 +1,42 @@
+{ %fail }
+{$mode objfpc}
+
+type
+  tobject1 = class
+  strict protected
+    spro : integer;
+  strict private
+    spriv : integer;
+  public
+    procedure p1;
+  end;
+
+
+  tobject2 = class(tobject1)
+    procedure p2;
+  end;
+
+procedure tobject1.p1;
+  begin
+    spro:=1;
+    spriv:=2;
+  end;
+
+procedure tobject2.p2;
+  begin
+    spro:=3;
+  end;
+
+var
+  o1 : tobject1;
+  o2 : tobject2;
+
+begin
+  o1:=tobject1.create;
+  o2:=tobject2.create;
+  o1.spriv:=1;
+  o1.free;
+  o2.free;
+end.
+
+

+ 39 - 0
tests/tbf/tb0174d.pp

@@ -0,0 +1,39 @@
+{ %fail }
+{$mode objfpc}
+
+type
+  tobject1 = class
+  strict protected
+    spro : integer;
+  strict private
+    spriv : integer;
+  public
+    procedure p1;
+  end;
+
+
+  tobject2 = class(tobject1)
+    procedure p2;
+  end;
+
+procedure tobject1.p1;
+  begin
+  end;
+
+procedure tobject2.p2;
+  begin
+  end;
+
+var
+  o1 : tobject1;
+  o2 : tobject2;
+
+begin
+  o1:=tobject1.create;
+  o2:=tobject2.create;
+  o2.spro:=1;
+  o1.free;
+  o2.free;
+end.
+
+

+ 40 - 0
tests/tbs/tb0493.pp

@@ -0,0 +1,40 @@
+{$mode objfpc}
+
+type
+  tobject1 = class
+  strict protected
+    spro : integer;
+  strict private
+    spriv : integer;
+  public
+    procedure p1;
+  end;
+
+
+  tobject2 = class(tobject1)
+    procedure p2;
+  end;
+
+procedure tobject1.p1;
+  begin
+    spro:=1;
+    spriv:=2;
+  end;
+
+procedure tobject2.p2;
+  begin
+    spro:=3;
+  end;
+
+var
+  o1 : tobject1;
+  o2 : tobject2;
+
+begin
+  o1:=tobject1.create;
+  o2:=tobject2.create;
+  o1.free;
+  o2.free;
+end.
+
+