Răsfoiți Sursa

* fix for Mantis #37426: don't allow an instance function of a type helper to be used on the type instead of a concrete value
+ added test

git-svn-id: trunk@49102 -

svenbarth 4 ani în urmă
părinte
comite
2885d3ab56
3 a modificat fișierele cu 39 adăugiri și 3 ștergeri
  1. 1 0
      .gitattributes
  2. 13 3
      compiler/pexpr.pas
  3. 25 0
      tests/webtbf/tw37426.pp

+ 1 - 0
.gitattributes

@@ -16786,6 +16786,7 @@ tests/webtbf/tw37272b.pp svneol=native#text/pascal
 tests/webtbf/tw37303.pp -text svneol=native#text/pascal
 tests/webtbf/tw3738.pp svneol=native#text/plain
 tests/webtbf/tw3740.pp svneol=native#text/plain
+tests/webtbf/tw37426.pp svneol=native#text/pascal
 tests/webtbf/tw37459.pp svneol=native#text/pascal
 tests/webtbf/tw37460.pp svneol=native#text/pascal
 tests/webtbf/tw37462.pp svneol=native#text/pascal

+ 13 - 3
compiler/pexpr.pas

@@ -1319,6 +1319,7 @@ implementation
         isclassref:boolean;
         isrecordtype:boolean;
         isobjecttype:boolean;
+        ishelpertype:boolean;
       begin
          if sym=nil then
            begin
@@ -1340,12 +1341,18 @@ implementation
                  isclassref:=(p1.resultdef.typ=classrefdef);
                  isrecordtype:=(p1.nodetype=typen) and (p1.resultdef.typ=recorddef);
                  isobjecttype:=(p1.nodetype=typen) and is_object(p1.resultdef);
+                 ishelpertype:=is_objectpascal_helper(tdef(sym.owner.defowner)) and
+                               (p1.nodetype=typen) and
+                               not is_objectpascal_helper(p1.resultdef)
+                                {and
+                               not (cnf_inherited in callflags)};
                end
               else
                 begin
                   isclassref:=false;
                   isrecordtype:=false;
                   isobjecttype:=false;
+                  ishelpertype:=false;
                 end;
 
               if assigned(spezcontext) and not (sym.typ=procsym) then
@@ -1366,7 +1373,8 @@ implementation
                             isclassref or
                             (
                               (isobjecttype or
-                               isrecordtype) and
+                               isrecordtype or
+                               ishelpertype) and
                               not (cnf_inherited in callflags)
                             )
                           ) and
@@ -1422,8 +1430,10 @@ implementation
                             abstract class using the type name of that class. We
                             must not provide a warning if we use a "class of"
                             variable of that type though as we don't know the
-                            type of the class }
-                          if (tcallnode(p1).procdefinition.proctypeoption=potype_constructor) and
+                            type of the class
+                            Note: structh might be Nil in case of a type helper }
+                          if assigned(structh) and
+                              (tcallnode(p1).procdefinition.proctypeoption=potype_constructor) and
                               (oo_is_abstract in structh.objectoptions) and
                               assigned(tcallnode(p1).methodpointer) and
                               (tcallnode(p1).methodpointer.nodetype=loadvmtaddrn) then

+ 25 - 0
tests/webtbf/tw37426.pp

@@ -0,0 +1,25 @@
+{ %FAIL }
+
+{$mode objfpc}
+uses
+  SysUtils, Classes;
+type
+
+  { TFoo }
+
+  TFoo = class
+    procedure Bar;
+  end;
+
+var
+  AByte: Byte;
+
+{ TFoo }
+
+procedure TFoo.Bar;
+begin
+  AByte := Byte.SetBit(1);
+end;
+
+begin
+end.