Kaynağa Gözat

+ in_generic for testing if currently a generic declaration/definition is parsed/record
* omit several error messages when in_generic is true because the error can be checked only during specialisation, resolves the issue reported in #21592

git-svn-id: trunk@20699 -

florian 13 yıl önce
ebeveyn
işleme
79a77ae7d6
5 değiştirilmiş dosya ile 61 ekleme ve 19 silme
  1. 1 0
      .gitattributes
  2. 30 15
      compiler/htypechk.pas
  3. 3 1
      compiler/pdecl.pas
  4. 4 3
      compiler/ptconst.pas
  5. 23 0
      tests/webtbs/tw21593.pp

+ 1 - 0
.gitattributes

@@ -12304,6 +12304,7 @@ tests/webtbs/tw21472.pp svneol=native#text/pascal
 tests/webtbs/tw21551.pp svneol=native#text/plain
 tests/webtbs/tw2158.pp svneol=native#text/plain
 tests/webtbs/tw2159.pp svneol=native#text/plain
+tests/webtbs/tw21593.pp svneol=native#text/pascal
 tests/webtbs/tw2163.pp svneol=native#text/plain
 tests/webtbs/tw2176.pp svneol=native#text/plain
 tests/webtbs/tw2177.pp svneol=native#text/plain

+ 30 - 15
compiler/htypechk.pas

@@ -178,6 +178,10 @@ interface
       arrays, records and objects are checked recursively }
     function is_valid_for_default(def:tdef):boolean;
 
+    { returns true if currently a generic declaration or definition is parsed/compiled,
+      regardless if it's a subroutine or type }
+    function in_generic : boolean;
+
 implementation
 
     uses
@@ -992,34 +996,38 @@ implementation
                        begin
                          { Give warning/note for uninitialized locals }
                          if assigned(hsym.owner) and
-                           not(cs_opt_nodedfa in current_settings.optimizerswitches) and
                             not(vo_is_external in hsym.varoptions) and
                             (hsym.owner.symtabletype in [parasymtable,localsymtable,staticsymtable]) and
                             ((hsym.owner=current_procinfo.procdef.localst) or
                              (hsym.owner=current_procinfo.procdef.parast)) then
                            begin
-                             if (vo_is_funcret in hsym.varoptions) then
-                               begin
-                                 if (vsf_use_hints in varstateflags) then
-                                   CGMessagePos(p.fileinfo,sym_h_function_result_uninitialized)
-                                 else
-                                   CGMessagePos(p.fileinfo,sym_w_function_result_uninitialized)
-                               end
-                             else
+                             if vsf_use_hints in varstateflags then
+                               include(tloadnode(p).loadnodeflags,loadnf_only_uninitialized_hint);
+                             if not(cs_opt_nodedfa in current_settings.optimizerswitches) then
                                begin
-                                 if tloadnode(p).symtable.symtabletype=localsymtable then
+                                 if (vo_is_funcret in hsym.varoptions) then
                                    begin
                                      if (vsf_use_hints in varstateflags) then
-                                       CGMessagePos1(p.fileinfo,sym_h_uninitialized_local_variable,hsym.realname)
+                                       CGMessagePos(p.fileinfo,sym_h_function_result_uninitialized)
                                      else
-                                       CGMessagePos1(p.fileinfo,sym_w_uninitialized_local_variable,hsym.realname);
+                                       CGMessagePos(p.fileinfo,sym_w_function_result_uninitialized)
                                    end
                                  else
                                    begin
-                                     if (vsf_use_hints in varstateflags) then
-                                       CGMessagePos1(p.fileinfo,sym_h_uninitialized_variable,hsym.realname)
+                                     if tloadnode(p).symtable.symtabletype=localsymtable then
+                                       begin
+                                         if (vsf_use_hints in varstateflags) then
+                                           CGMessagePos1(p.fileinfo,sym_h_uninitialized_local_variable,hsym.realname)
+                                         else
+                                           CGMessagePos1(p.fileinfo,sym_w_uninitialized_local_variable,hsym.realname);
+                                       end
                                      else
-                                       CGMessagePos1(p.fileinfo,sym_w_uninitialized_variable,hsym.realname);
+                                       begin
+                                         if (vsf_use_hints in varstateflags) then
+                                           CGMessagePos1(p.fileinfo,sym_h_uninitialized_variable,hsym.realname)
+                                         else
+                                           CGMessagePos1(p.fileinfo,sym_w_uninitialized_variable,hsym.realname);
+                                       end;
                                    end;
                                end;
                            end
@@ -3010,4 +3018,11 @@ implementation
       end;
 
 
+    function in_generic: boolean;
+      begin
+        result:=(assigned(current_structdef) and (df_generic in current_structdef.defoptions)) or
+          (assigned(current_procinfo) and (df_generic in current_procinfo.procdef.defoptions));
+      end;
+
+
 end.

+ 3 - 1
compiler/pdecl.pas

@@ -61,6 +61,7 @@ implementation
        { symtable }
        symconst,symbase,symtype,symtable,paramgr,defutil,
        { pass 1 }
+       htypechk,
        nmat,nadd,ncal,nset,ncnv,ninl,ncon,nld,nflw,nobj,
        { codegen }
        ncgutil,
@@ -150,7 +151,8 @@ implementation
                 Message(parser_e_illegal_expression);
              end;
            else
-             Message(parser_e_illegal_expression);
+             if not(in_generic) then
+               Message(parser_e_illegal_expression);
         end;
         current_tokenpos:=storetokenpos;
         p.free;

+ 4 - 3
compiler/ptconst.pas

@@ -173,7 +173,8 @@ implementation
             if is_constnode(n) then
               IncompatibleTypes(n.resultdef, def)
             else
-              Message(parser_e_illegal_expression);
+             if not(in_generic) then
+                Message(parser_e_illegal_expression);
           end;
 
         begin
@@ -216,8 +217,8 @@ implementation
                 end;
               uchar :
                 begin
-                   if is_constwidecharnode(n) then 
-                     inserttypeconv(n,cchartype); 
+                   if is_constwidecharnode(n) then
+                     inserttypeconv(n,cchartype);
                    if is_constcharnode(n) or
                      ((m_delphi in current_settings.modeswitches) and
                       is_constwidecharnode(n) and

+ 23 - 0
tests/webtbs/tw21593.pp

@@ -0,0 +1,23 @@
+{$MODE DELPHI}
+
+type
+  TWrapper<T> = record
+    strict private
+      const Size1 = SizeOf(T);  { Error: Illegal expression }
+    class procedure Test; static;
+  end;
+
+class procedure TWrapper<T>.Test;
+const
+  Size2 = SizeOf(T);  { Error: Illegal expression }
+var
+  size3: SizeInt = SizeOf(T);  { Error: Illegal expression }
+begin
+  Writeln(Size3);
+end;
+
+var
+  Wrapper : TWrapper<Byte>;
+
+begin
+end.