소스 검색

* ensure that an expression that involves an overloaded generic in mode Delphi isn't handled as a specialization if it shouldn't be
+ added tests

Sven/Sarah Barth 3 년 전
부모
커밋
5ce96de0f2
6개의 변경된 파일118개의 추가작업 그리고 0개의 파일을 삭제
  1. 36 0
      compiler/pexpr.pas
  2. 14 0
      tests/test/tgenconst31.pp
  3. 19 0
      tests/test/tgenconst32.pp
  4. 21 0
      tests/test/tgenconst33.pp
  5. 13 0
      tests/test/ugenconst31a.pp
  6. 15 0
      tests/test/ugenconst31b.pp

+ 36 - 0
compiler/pexpr.pas

@@ -4431,6 +4431,9 @@ implementation
         filepos : tfileposinfo;
         filepos : tfileposinfo;
         gendef,parseddef : tdef;
         gendef,parseddef : tdef;
         gensym : tsym;
         gensym : tsym;
+        genlist : tfpobjectlist;
+        dummyagain : boolean;
+        dummyspezctxt : tspecializationcontext;
       begin
       begin
         SubExprStart:
         SubExprStart:
         if pred_level=highest_precedence then
         if pred_level=highest_precedence then
@@ -4520,6 +4523,39 @@ implementation
 
 
                        { potential generic types that are followed by a "<": }
                        { potential generic types that are followed by a "<": }
 
 
+                       if p1.nodetype=specializen then
+                         begin
+                           genlist:=tfpobjectlist(current_module.genericdummysyms.find(tspecializenode(p1).sym.name));
+                           if assigned(genlist) and (genlist.count>0) then
+                             begin
+                               gensym:=tgenericdummyentry(genlist.last).resolvedsym;
+                               check_hints(gensym,gensym.symoptions,gensym.deprecatedmsg,p1.fileinfo);
+
+                               dummyagain:=false;
+                               dummyspezctxt:=nil;
+
+                               ptmp:=factor_handle_sym(gensym,
+                                                       gensym.owner,
+                                                       dummyagain,
+                                                       tspecializenode(p1).getaddr,
+                                                       false,
+                                                       flags,
+                                                       dummyspezctxt);
+
+                               if dummyagain then
+                                 internalerror(2022012201);
+
+                               p1.free;
+                               p1:=ptmp;
+                             end
+                           else
+                             begin
+                               identifier_not_found(tspecializenode(p1).sym.realname);
+                               p1.free;
+                               p1:=cerrornode.create;
+                             end;
+                         end;
+
                        { a) might not have their resultdef set }
                        { a) might not have their resultdef set }
                        if not assigned(p1.resultdef) then
                        if not assigned(p1.resultdef) then
                          do_typecheckpass(p1);
                          do_typecheckpass(p1);

+ 14 - 0
tests/test/tgenconst31.pp

@@ -0,0 +1,14 @@
+program tgenconst31;
+
+{$mode delphi}
+
+uses
+  ugenconst31a, ugenconst31b;
+
+const
+  N = 42;
+
+begin
+  if Test<N then
+    Writeln('Foo');
+end.

+ 19 - 0
tests/test/tgenconst32.pp

@@ -0,0 +1,19 @@
+program tgenconst32;
+
+{$mode delphi}
+
+var
+  Test: LongInt = 42;
+
+type
+  Test<const N: LongInt> = class
+
+  end;
+
+const
+  N = 42;
+
+begin
+  if Test<N then
+    Writeln('Foo');
+end.

+ 21 - 0
tests/test/tgenconst33.pp

@@ -0,0 +1,21 @@
+{ %FAIL }
+
+program tgenconst33;
+
+{$mode delphi}
+
+{var
+  Test: LongInt = 42;}
+
+type
+  Test<const N: LongInt> = class
+
+  end;
+
+const
+  N = 42;
+
+begin
+  if Test<N then
+    Writeln('Foo');
+end.

+ 13 - 0
tests/test/ugenconst31a.pp

@@ -0,0 +1,13 @@
+unit ugenconst31a;
+
+{$mode objfpc}{$H+}
+
+interface
+
+var
+  Test: LongInt = 42;
+
+implementation
+
+end.
+

+ 15 - 0
tests/test/ugenconst31b.pp

@@ -0,0 +1,15 @@
+unit ugenconst31b;
+
+{$mode delphi}{$H+}
+
+interface
+
+type
+  Test<const N: LongInt> = class
+
+  end;
+
+implementation
+
+end.
+