Browse Source

Loosen the restriction regarding operator overloads by applying a (modified) patch from JC Chu. This fixes Mantis #22359.

The changes are built up in a way that all operators on two given types are not allowed if a default implementation for that operator exists. This implies that there is a possibility to have a overload work for (in this order) type A and B, but not for B and A. This is for example the case for Set + Enum (which seems to have a default implementation) where Enum + Set is allowed. The added tests try to detect as many default implementations as feasible, but can't cover everything...

git-svn-id: trunk@21975 -
svenbarth 13 years ago
parent
commit
b0458b55a3
77 changed files with 1247 additions and 78 deletions
  1. 74 0
      .gitattributes
  2. 31 0
      compiler/defutil.pas
  3. 230 78
      compiler/htypechk.pas
  4. 11 0
      tests/test/toperator13.pp
  5. 11 0
      tests/test/toperator14.pp
  6. 11 0
      tests/test/toperator15.pp
  7. 11 0
      tests/test/toperator16.pp
  8. 11 0
      tests/test/toperator17.pp
  9. 11 0
      tests/test/toperator18.pp
  10. 11 0
      tests/test/toperator19.pp
  11. 11 0
      tests/test/toperator20.pp
  12. 11 0
      tests/test/toperator21.pp
  13. 11 0
      tests/test/toperator22.pp
  14. 11 0
      tests/test/toperator23.pp
  15. 11 0
      tests/test/toperator24.pp
  16. 15 0
      tests/test/toperator25.pp
  17. 15 0
      tests/test/toperator26.pp
  18. 15 0
      tests/test/toperator27.pp
  19. 15 0
      tests/test/toperator28.pp
  20. 15 0
      tests/test/toperator29.pp
  21. 15 0
      tests/test/toperator30.pp
  22. 15 0
      tests/test/toperator31.pp
  23. 15 0
      tests/test/toperator32.pp
  24. 15 0
      tests/test/toperator33.pp
  25. 15 0
      tests/test/toperator34.pp
  26. 15 0
      tests/test/toperator35.pp
  27. 11 0
      tests/test/toperator36.pp
  28. 11 0
      tests/test/toperator37.pp
  29. 11 0
      tests/test/toperator38.pp
  30. 11 0
      tests/test/toperator39.pp
  31. 11 0
      tests/test/toperator40.pp
  32. 11 0
      tests/test/toperator41.pp
  33. 11 0
      tests/test/toperator42.pp
  34. 11 0
      tests/test/toperator43.pp
  35. 11 0
      tests/test/toperator44.pp
  36. 11 0
      tests/test/toperator45.pp
  37. 11 0
      tests/test/toperator46.pp
  38. 11 0
      tests/test/toperator47.pp
  39. 11 0
      tests/test/toperator48.pp
  40. 11 0
      tests/test/toperator49.pp
  41. 11 0
      tests/test/toperator50.pp
  42. 11 0
      tests/test/toperator51.pp
  43. 11 0
      tests/test/toperator52.pp
  44. 11 0
      tests/test/toperator53.pp
  45. 11 0
      tests/test/toperator54.pp
  46. 11 0
      tests/test/toperator55.pp
  47. 11 0
      tests/test/toperator56.pp
  48. 11 0
      tests/test/toperator57.pp
  49. 11 0
      tests/test/toperator58.pp
  50. 11 0
      tests/test/toperator59.pp
  51. 11 0
      tests/test/toperator60.pp
  52. 11 0
      tests/test/toperator61.pp
  53. 11 0
      tests/test/toperator62.pp
  54. 11 0
      tests/test/toperator63.pp
  55. 11 0
      tests/test/toperator64.pp
  56. 11 0
      tests/test/toperator65.pp
  57. 11 0
      tests/test/toperator66.pp
  58. 11 0
      tests/test/toperator67.pp
  59. 11 0
      tests/test/toperator68.pp
  60. 11 0
      tests/test/toperator69.pp
  61. 11 0
      tests/test/toperator70.pp
  62. 11 0
      tests/test/toperator71.pp
  63. 11 0
      tests/test/toperator72.pp
  64. 11 0
      tests/test/toperator73.pp
  65. 11 0
      tests/test/toperator74.pp
  66. 11 0
      tests/test/toperator75.pp
  67. 11 0
      tests/test/toperator76.pp
  68. 11 0
      tests/test/toperator77.pp
  69. 65 0
      tests/test/toperator78.pp
  70. 11 0
      tests/test/toperator79.pp
  71. 11 0
      tests/test/toperator80.pp
  72. 11 0
      tests/test/toperator81.pp
  73. 11 0
      tests/test/toperator82.pp
  74. 11 0
      tests/test/toperator83.pp
  75. 11 0
      tests/test/toperator84.pp
  76. 11 0
      tests/test/toperator85.pp
  77. 11 0
      tests/test/toperator86.pp

+ 74 - 0
.gitattributes

@@ -10976,13 +10976,87 @@ tests/test/toperator1.pp svneol=native#text/plain
 tests/test/toperator10.pp svneol=native#text/pascal
 tests/test/toperator11.pp svneol=native#text/pascal
 tests/test/toperator12.pp svneol=native#text/pascal
+tests/test/toperator13.pp svneol=native#text/pascal
+tests/test/toperator14.pp svneol=native#text/pascal
+tests/test/toperator15.pp svneol=native#text/pascal
+tests/test/toperator16.pp svneol=native#text/pascal
+tests/test/toperator17.pp svneol=native#text/pascal
+tests/test/toperator18.pp svneol=native#text/pascal
+tests/test/toperator19.pp svneol=native#text/pascal
 tests/test/toperator2.pp svneol=native#text/plain
+tests/test/toperator20.pp svneol=native#text/pascal
+tests/test/toperator21.pp svneol=native#text/pascal
+tests/test/toperator22.pp svneol=native#text/pascal
+tests/test/toperator23.pp svneol=native#text/pascal
+tests/test/toperator24.pp svneol=native#text/pascal
+tests/test/toperator25.pp svneol=native#text/pascal
+tests/test/toperator26.pp svneol=native#text/pascal
+tests/test/toperator27.pp svneol=native#text/pascal
+tests/test/toperator28.pp svneol=native#text/pascal
+tests/test/toperator29.pp svneol=native#text/pascal
 tests/test/toperator3.pp svneol=native#text/plain
+tests/test/toperator30.pp svneol=native#text/pascal
+tests/test/toperator31.pp svneol=native#text/pascal
+tests/test/toperator32.pp svneol=native#text/pascal
+tests/test/toperator33.pp svneol=native#text/pascal
+tests/test/toperator34.pp svneol=native#text/pascal
+tests/test/toperator35.pp svneol=native#text/pascal
+tests/test/toperator36.pp svneol=native#text/pascal
+tests/test/toperator37.pp svneol=native#text/pascal
+tests/test/toperator38.pp svneol=native#text/pascal
+tests/test/toperator39.pp svneol=native#text/pascal
 tests/test/toperator4.pp svneol=native#text/plain
+tests/test/toperator40.pp svneol=native#text/pascal
+tests/test/toperator41.pp svneol=native#text/pascal
+tests/test/toperator42.pp svneol=native#text/pascal
+tests/test/toperator43.pp svneol=native#text/pascal
+tests/test/toperator44.pp svneol=native#text/pascal
+tests/test/toperator45.pp svneol=native#text/pascal
+tests/test/toperator46.pp svneol=native#text/pascal
+tests/test/toperator47.pp svneol=native#text/pascal
+tests/test/toperator48.pp svneol=native#text/pascal
+tests/test/toperator49.pp svneol=native#text/pascal
 tests/test/toperator5.pp svneol=native#text/plain
+tests/test/toperator50.pp svneol=native#text/pascal
+tests/test/toperator51.pp svneol=native#text/pascal
+tests/test/toperator52.pp svneol=native#text/pascal
+tests/test/toperator53.pp svneol=native#text/pascal
+tests/test/toperator54.pp svneol=native#text/pascal
+tests/test/toperator55.pp svneol=native#text/pascal
+tests/test/toperator56.pp svneol=native#text/pascal
+tests/test/toperator57.pp svneol=native#text/pascal
+tests/test/toperator58.pp svneol=native#text/pascal
+tests/test/toperator59.pp svneol=native#text/pascal
 tests/test/toperator6.pp svneol=native#text/plain
+tests/test/toperator60.pp svneol=native#text/pascal
+tests/test/toperator61.pp svneol=native#text/pascal
+tests/test/toperator62.pp svneol=native#text/pascal
+tests/test/toperator63.pp svneol=native#text/pascal
+tests/test/toperator64.pp svneol=native#text/pascal
+tests/test/toperator65.pp svneol=native#text/pascal
+tests/test/toperator66.pp svneol=native#text/pascal
+tests/test/toperator67.pp svneol=native#text/pascal
+tests/test/toperator68.pp svneol=native#text/pascal
+tests/test/toperator69.pp svneol=native#text/pascal
 tests/test/toperator7.pp svneol=native#text/plain
+tests/test/toperator70.pp svneol=native#text/pascal
+tests/test/toperator71.pp svneol=native#text/pascal
+tests/test/toperator72.pp svneol=native#text/pascal
+tests/test/toperator73.pp svneol=native#text/pascal
+tests/test/toperator74.pp svneol=native#text/pascal
+tests/test/toperator75.pp svneol=native#text/pascal
+tests/test/toperator76.pp svneol=native#text/pascal
+tests/test/toperator77.pp svneol=native#text/pascal
+tests/test/toperator78.pp svneol=native#text/pascal
+tests/test/toperator79.pp svneol=native#text/pascal
 tests/test/toperator8.pp svneol=native#text/pascal
+tests/test/toperator80.pp svneol=native#text/pascal
+tests/test/toperator81.pp svneol=native#text/pascal
+tests/test/toperator82.pp svneol=native#text/pascal
+tests/test/toperator83.pp svneol=native#text/pascal
+tests/test/toperator84.pp svneol=native#text/pascal
+tests/test/toperator85.pp svneol=native#text/pascal
+tests/test/toperator86.pp svneol=native#text/pascal
 tests/test/toperator9.pp svneol=native#text/pascal
 tests/test/tover1.pp svneol=native#text/plain
 tests/test/tover2.pp svneol=native#text/plain

+ 31 - 0
compiler/defutil.pas

@@ -46,6 +46,16 @@ interface
     {# Returns true, if definition defines a string type }
     function is_string(def : tdef): boolean;
 
+    {# Returns True, if definition defines a type that behaves like a string,
+       namely that can be joined and compared with another string-like type }
+    function is_stringlike(def : tdef) : boolean;
+
+    {# Returns True, if definition defines an enumeration type }
+    function is_enum(def : tdef) : boolean;
+
+    {# Returns True, if definition defines a set type }
+    function is_set(def : tdef) : boolean;
+
     {# Returns the minimal integer value of the type }
     function get_min_value(def : tdef) : TConstExprInt;
 
@@ -405,6 +415,27 @@ implementation
         is_string := (assigned(def) and (def.typ = stringdef));
       end;
 
+    function is_stringlike(def : tdef) : boolean;
+      begin
+        result := is_string(def) or
+                  is_anychar(def) or
+                  is_pchar(def) or
+                  is_pwidechar(def) or
+                  is_chararray(def) or
+                  is_widechararray(def) or
+                  is_open_chararray(def) or
+                  is_open_widechararray(def);
+      end;
+
+    function is_enum(def : tdef) : boolean;
+      begin
+        result:=def.typ=enumdef;
+      end;
+
+    function is_set(def : tdef) : boolean;
+      begin
+        result:=def.typ=setdef;
+      end;
 
     { returns the min. value of the type }
     function get_min_value(def : tdef) : TConstExprInt;

+ 230 - 78
compiler/htypechk.pas

@@ -212,8 +212,26 @@ implementation
     function isbinaryoperatoroverloadable(treetyp:tnodetype;ld:tdef;lt:tnodetype;rd:tdef;rt:tnodetype) : boolean;
 
         function internal_check(treetyp:tnodetype;ld:tdef;lt:tnodetype;rd:tdef;rt:tnodetype;var allowed:boolean):boolean;
+        const
+          identity_operators = [equaln, unequaln];
+          order_theoretic_operators = identity_operators + [ltn, lten, gtn, gten];
+          arithmetic_operators = [addn, subn, muln, divn, modn];
+          rational_operators = [addn, subn, muln, slashn];
+          numerical_operators = arithmetic_operators + [slashn];
+          pointer_arithmetic_operators = [addn, subn];
+          logical_operators = [andn, orn, xorn];
+          bit_manipulation_operators = logical_operators + [shln, shrn];
+          set_set_operators = identity_operators + [addn, subn, muln, symdifn] +
+            order_theoretic_operators;
+          element_set_operators = [inn];
+          string_comparison_operators = order_theoretic_operators;
+          string_manipulation_operators = [addn];
+          string_operators =
+            string_comparison_operators + string_manipulation_operators;
         begin
           internal_check:=true;
+
+          { Reject the cases permitted by the default interpretation (DI). }
           case ld.typ of
             formaldef,
             recorddef,
@@ -221,6 +239,117 @@ implementation
               begin
                 allowed:=true;
               end;
+            enumdef:
+              begin
+                allowed:=not (
+                           (
+                             is_set(rd) and
+                             (treetyp in element_set_operators)
+                           ) or
+                           (
+                             is_enum(rd) and
+                             (treetyp in (order_theoretic_operators + [addn, subn]))
+                           )
+                         );
+              end;
+            setdef:
+              begin
+                allowed:=not (
+                           (
+                             is_set(rd) and
+                             (treetyp in (set_set_operators + identity_operators))
+                           ) or
+                           (
+                             { This clause is a hack but it’s due to a hack somewhere
+                               else---while set + element is not permitted by DI, it
+                               seems to be used when a set is constructed inline }
+                             (rd.typ in [enumdef, orddef]) and
+                             (treetyp = addn)
+                           )
+                         );
+              end;
+            orddef, floatdef:
+              begin
+                allowed:=not (
+                           (
+                             (rd.typ in [orddef, floatdef]) and
+                             (treetyp in order_theoretic_operators)
+                           ) or
+                           (
+                             is_stringlike(rd) and
+                             (ld.typ = orddef) and
+                             (treetyp in string_comparison_operators)) or
+                             { c.f. $(source)\tests\tmacpas5.pp }
+                             (
+                               (rd.typ = setdef) and
+                               (ld.typ = orddef) and
+                               (treetyp in element_set_operators)
+                             )
+                            { This clause may be too restrictive---not all types under
+                              orddef have a corresponding set type; despite this the
+                              restriction should be very unlikely to become
+                              a practical obstacle, and can be relaxed by simply
+                              adding an extra check on TOrdDef(rd).ordtype }
+                           );
+
+                { Note that Currency can be under either orddef or floatdef;
+                  when it’s under floatdef, is_currency() implies is_float();
+                  when it’s under orddef, is_currency() does NOT imply
+                  is_integer(). }
+                if allowed then
+                  begin
+                    if is_anychar(ld) then
+                      allowed:=not (
+                                 is_stringlike(rd) and
+                                 (treetyp in string_operators)
+                               )
+                    else if is_boolean(ld) then
+                      allowed:=not (
+                                 is_boolean(rd) and
+                                 (treetyp in logical_operators)
+                               )
+                    else if is_integer(ld) or
+                        (
+                          (ld.typ = orddef) and
+                          is_currency(ld)
+                        { Here ld is Currency but behaves like an integer }
+                        ) then
+                      allowed:=not (
+                                 (
+                                   (
+                                     is_integer(rd) or
+                                     (
+                                       (rd.typ = orddef) and
+                                       is_currency(rd)
+                                     )
+                                   ) and
+                                   (treetyp in (bit_manipulation_operators + numerical_operators))
+                                 ) or
+                                 (
+                                   is_fpu(rd) and
+                                   (treetyp in rational_operators)
+                                 ) or
+                                 (
+                                   { When an integer type is used as the first operand in
+                                     pointer arithmetic, DI doesn’t accept minus as the
+                                     operator (Currency can’t be used in pointer
+                                     arithmetic even if it’s under orddef)  }
+                                   is_integer(ld) and
+                                   (rd.typ = pointerdef) and
+                                   (treetyp in pointer_arithmetic_operators - [subn])
+                                 )
+                               )
+                    else  { is_fpu(ld) = True }
+                      allowed:=not (
+                                 (
+                                   is_fpu(rd) or
+                                   is_integer(rd) or
+                                   is_currency(rd)
+                                 ) and
+                                 (treetyp in rational_operators)
+                               );
+                  end;
+              end;
             procvardef :
               begin
                 if (rd.typ in [pointerdef,procdef,procvardef]) then
@@ -232,25 +361,50 @@ implementation
               end;
             pointerdef :
               begin
-                if ((rd.typ in [orddef,enumdef,pointerdef,classrefdef,procvardef]) or
-                    is_implicit_pointer_object_type(rd)) then
-                 begin
-                   allowed:=false;
-                   exit;
-                 end;
-
-                { don't allow pchar+string }
-                if (is_pchar(ld) or is_pwidechar(ld)) and
-                   ((rd.typ=stringdef) or
-                    is_pchar(rd) or
-                    is_pwidechar(rd) or
-                    is_chararray(rd) or
-                    is_widechararray(rd)) then
-                 begin
-                   allowed:=false;
-                   exit;
-                 end;
-                allowed:=true;
+                { DI permits pointer arithmetic for pointer + pointer, pointer -
+                  integer, pointer - pointer, but not for pointer + pointer.
+                  The last case is only valid in DI when both sides are
+                  stringlike. }
+
+                if is_stringlike(ld) then
+                  if is_stringlike(rd) then
+                    { DI in this case permits string operations and pointer
+                      arithmetic. }
+                    allowed:=not (treetyp in (string_operators + pointer_arithmetic_operators))
+                  else if rd.typ = pointerdef then
+                    { DI in this case permits minus for pointer arithmetic and
+                      order-theoretic operators for pointer comparison. }
+                    allowed:=not (
+                               treetyp in (
+                                 pointer_arithmetic_operators - [addn] +
+                                 order_theoretic_operators
+                               )
+                             )
+                  else if is_integer(rd) then
+                    { DI in this case permits pointer arithmetic. }
+                    allowed:=not (treetyp in pointer_arithmetic_operators)
+                  else
+                    allowed:=true
+                else
+                  allowed:=not (
+                             (
+                               is_integer(rd) and
+                               (treetyp in pointer_arithmetic_operators)
+                             ) or
+                             (
+                               (rd.typ = pointerdef) and
+                               (
+                                 treetyp in (
+                                   pointer_arithmetic_operators - [addn] +
+                                   order_theoretic_operators
+                                 )
+                               )
+                             ) or
+                             (
+                               (lt = niln) and
+                               (rd.typ in [procvardef, procdef]) and
+                               (treetyp in identity_operators))
+                             );
               end;
             arraydef :
               begin
@@ -263,80 +417,79 @@ implementation
                    allowed:=false;
                    exit;
                  end;
-                { not chararray+[(wide)char,(wide)string,(wide)chararray] }
-                if (is_chararray(ld) or is_widechararray(ld) or
-                    is_open_chararray(ld) or is_open_widechararray(ld))
-                   and
-                   ((rd.typ in [stringdef,orddef,enumdef]) or
-                    is_pchar(rd) or
-                    is_pwidechar(rd) or
-                    is_chararray(rd) or
-                    is_widechararray(rd) or
-                    is_open_chararray(rd) or
-                    is_open_widechararray(rd) or
-                    (rt=niln)) then
-                 begin
-                   allowed:=false;
-                   exit;
-                 end;
+
+                if is_stringlike(ld) and
+                    (
+                      (
+                        (
+                          is_stringlike(rd) or
+                          (rt = niln)
+                        ) and
+                        (treetyp in string_operators)
+                      ) or
+                      (
+                        is_integer(rd) and
+                        (treetyp in pointer_arithmetic_operators)
+                      ) or
+                      (
+                        (
+                          is_pchar(rd) or
+                          is_pwidechar(rd)) and
+                          (treetyp in pointer_arithmetic_operators) and
+                          (tpointerdef(rd).pointeddef=tarraydef(ld).elementdef
+                        )
+                      )
+                    ) then
+                  begin
+                    allowed:=false;
+                    exit;
+                  end;
+
                 { dynamic array compare with niln }
-                if ((is_dynamic_array(ld) and
-                   (rt=niln)) or
-                   (is_dynamic_array(ld) and is_dynamic_array(rd)))
-                   and
-                   (treetyp in [equaln,unequaln]) then
-                 begin
-                   allowed:=false;
-                   exit;
-                 end;
+                if is_dynamic_array(ld) and
+                    (treetyp in identity_operators) then
+                  if is_dynamic_array(rd) or
+                      (rt = niln) then
+                    begin
+                      allowed:=false;
+                      exit;
+                    end;
+
                 allowed:=true;
               end;
             objectdef :
               begin
                 { <> and = are defined for implicit pointer object types }
-                if (treetyp in [equaln,unequaln]) and
-                   is_implicit_pointer_object_type(ld) then
-                 begin
-                   allowed:=false;
-                   exit;
-                 end;
-                allowed:=true;
+                allowed:=not (
+                           is_implicit_pointer_object_type(ld) and
+                           (
+                             (
+                               is_implicit_pointer_object_type(rd) or
+                               (rd.typ = pointerdef) or
+                               (rt = niln)
+                             )
+                           ) and
+                           (treetyp in identity_operators)
+                         );
               end;
             stringdef :
               begin
-                if (rd.typ in [orddef,enumdef,stringdef]) or
-                   is_pchar(rd) or
-                   is_pwidechar(rd) or
-                   is_chararray(rd) or
-                   is_widechararray(rd) or
-                   is_open_chararray(rd) or
-                   is_open_widechararray(rd) then
-                 begin
-                   allowed:=false;
-                   exit;
-                 end;
-                allowed:=true;
+                allowed:=not (
+                           is_stringlike(rd) and
+                           (treetyp in string_operators)
+                         );
               end;
             else
               internal_check:=false;
           end;
         end;
 
-      var
-        allowed : boolean;
       begin
         { power ** is always possible }
-        if (treetyp=starstarn) then
-         begin
-           isbinaryoperatoroverloadable:=true;
-           exit;
-         end;
-        { order of arguments does not matter so we have to check also
-          the reversed order }
-        allowed:=false;
-        if not internal_check(treetyp,ld,lt,rd,rt,allowed) then
-          internal_check(treetyp,rd,rt,ld,lt,allowed);
-        isbinaryoperatoroverloadable:=allowed;
+        result:=treetyp=starstarn;
+        if not result then
+          if not internal_check(treetyp,ld,lt,rd,rt,result) then
+            result:=false;
       end;
 
 
@@ -366,8 +519,7 @@ implementation
 
           notn :
             begin
-              if (ld.typ in [orddef,enumdef,floatdef]) then
-                exit;
+              if ld.typ = orddef then exit;
 
 {$ifdef SUPPORT_MMX}
               if (cs_mmx in current_settings.localswitches) and

+ 11 - 0
tests/test/toperator13.pp

@@ -0,0 +1,11 @@
+{ %FAIL }
+program toperator13;
+
+operator + (left, right: LongInt) res : LongInt;
+begin
+
+end;
+
+begin
+
+end.

+ 11 - 0
tests/test/toperator14.pp

@@ -0,0 +1,11 @@
+{ %FAIL }
+program toperator14;
+
+operator - (left, right: LongInt) res : LongInt;
+begin
+
+end;
+
+begin
+
+end.

+ 11 - 0
tests/test/toperator15.pp

@@ -0,0 +1,11 @@
+{ %FAIL }
+program toperator15;
+
+operator * (left, right: LongInt) res : LongInt;
+begin
+
+end;
+
+begin
+
+end.

+ 11 - 0
tests/test/toperator16.pp

@@ -0,0 +1,11 @@
+{ %FAIL }
+program toperator16;
+
+operator / (left, right: LongInt) res : LongInt;
+begin
+
+end;
+
+begin
+
+end.

+ 11 - 0
tests/test/toperator17.pp

@@ -0,0 +1,11 @@
+{ %FAIL }
+program toperator17;
+
+operator mod (left, right: LongInt) res : LongInt;
+begin
+
+end;
+
+begin
+
+end.

+ 11 - 0
tests/test/toperator18.pp

@@ -0,0 +1,11 @@
+{ %FAIL }
+program toperator18;
+
+operator div (left, right: LongInt) res : LongInt;
+begin
+
+end;
+
+begin
+
+end.

+ 11 - 0
tests/test/toperator19.pp

@@ -0,0 +1,11 @@
+{ %FAIL }
+program toperator19;
+
+operator and (left, right: LongInt) res : LongInt;
+begin
+
+end;
+
+begin
+
+end.

+ 11 - 0
tests/test/toperator20.pp

@@ -0,0 +1,11 @@
+{ %FAIL }
+program toperator20;
+
+operator or (left, right: LongInt) res : LongInt;
+begin
+
+end;
+
+begin
+
+end.

+ 11 - 0
tests/test/toperator21.pp

@@ -0,0 +1,11 @@
+{ %FAIL }
+program toperator21;
+
+operator xor (left, right: LongInt) res : LongInt;
+begin
+
+end;
+
+begin
+
+end.

+ 11 - 0
tests/test/toperator22.pp

@@ -0,0 +1,11 @@
+{ %FAIL }
+program toperator22;
+
+operator not (right: LongInt) res : LongInt;
+begin
+
+end;
+
+begin
+
+end.

+ 11 - 0
tests/test/toperator23.pp

@@ -0,0 +1,11 @@
+{ %FAIL }
+program toperator23;
+
+operator + (left: Pointer; right: LongInt) res : Pointer;
+begin
+
+end;
+
+begin
+
+end.

+ 11 - 0
tests/test/toperator24.pp

@@ -0,0 +1,11 @@
+{ %FAIL }
+program toperator24;
+
+operator - (left: Pointer; right: LongInt) res : Pointer;
+begin
+
+end;
+
+begin
+
+end.

+ 15 - 0
tests/test/toperator25.pp

@@ -0,0 +1,15 @@
+{ %FAIL }
+program toperator25;
+
+type
+  TTest = (One, Two, Three);
+  TTests = set of TTest;
+
+operator + (left: TTests; right: TTests) res : TTests;
+begin
+
+end;
+
+begin
+
+end.

+ 15 - 0
tests/test/toperator26.pp

@@ -0,0 +1,15 @@
+{ %FAIL }
+program toperator26;
+
+type
+  TTest = (One, Two, Three);
+  TTests = set of TTest;
+
+operator - (left: TTests; right: TTests) res : TTests;
+begin
+
+end;
+
+begin
+
+end.

+ 15 - 0
tests/test/toperator27.pp

@@ -0,0 +1,15 @@
+{ %FAIL }
+program toperator27;
+
+type
+  TTest = (One, Two, Three);
+  TTests = set of TTest;
+
+operator * (left: TTests; right: TTests) res : TTests;
+begin
+
+end;
+
+begin
+
+end.

+ 15 - 0
tests/test/toperator28.pp

@@ -0,0 +1,15 @@
+{ %FAIL }
+program toperator28;
+
+type
+  TTest = (One, Two, Three);
+  TTests = set of TTest;
+
+operator >< (left: TTests; right: TTests) res : TTests;
+begin
+
+end;
+
+begin
+
+end.

+ 15 - 0
tests/test/toperator29.pp

@@ -0,0 +1,15 @@
+{ %FAIL }
+program toperator29;
+
+type
+  TTest = (One, Two, Three);
+  TTests = set of TTest;
+
+operator < (left: TTests; right: TTests) res : Boolean;
+begin
+
+end;
+
+begin
+
+end.

+ 15 - 0
tests/test/toperator30.pp

@@ -0,0 +1,15 @@
+{ %FAIL }
+program toperator30;
+
+type
+  TTest = (One, Two, Three);
+  TTests = set of TTest;
+
+operator <= (left: TTests; right: TTests) res : Boolean;
+begin
+
+end;
+
+begin
+
+end.

+ 15 - 0
tests/test/toperator31.pp

@@ -0,0 +1,15 @@
+{ %FAIL }
+program toperator31;
+
+type
+  TTest = (One, Two, Three);
+  TTests = set of TTest;
+
+operator > (left: TTests; right: TTests) res : Boolean;
+begin
+
+end;
+
+begin
+
+end.

+ 15 - 0
tests/test/toperator32.pp

@@ -0,0 +1,15 @@
+{ %FAIL }
+program toperator32;
+
+type
+  TTest = (One, Two, Three);
+  TTests = set of TTest;
+
+operator >= (left: TTests; right: TTests) res : Boolean;
+begin
+
+end;
+
+begin
+
+end.

+ 15 - 0
tests/test/toperator33.pp

@@ -0,0 +1,15 @@
+{ %FAIL }
+program toperator33;
+
+type
+  TTest = (One, Two, Three);
+  TTests = set of TTest;
+
+operator = (left: TTests; right: TTests) res : Boolean;
+begin
+
+end;
+
+begin
+
+end.

+ 15 - 0
tests/test/toperator34.pp

@@ -0,0 +1,15 @@
+{ %FAIL }
+program toperator34;
+
+type
+  TTest = (One, Two, Three);
+  TTests = set of TTest;
+
+operator <> (left: TTests; right: TTests) res : Boolean;
+begin
+
+end;
+
+begin
+
+end.

+ 15 - 0
tests/test/toperator35.pp

@@ -0,0 +1,15 @@
+{ %FAIL }
+program toperator35;
+
+type
+  TTest = (One, Two, Three);
+  TTests = set of TTest;
+
+operator in (left: TTest; right: TTests) res : Boolean;
+begin
+
+end;
+
+begin
+
+end.

+ 11 - 0
tests/test/toperator36.pp

@@ -0,0 +1,11 @@
+{ %FAIL }
+program toperator36;
+
+operator = (left: Pointer; right: Pointer) res : Boolean;
+begin
+
+end;
+
+begin
+
+end.

+ 11 - 0
tests/test/toperator37.pp

@@ -0,0 +1,11 @@
+{ %FAIL }
+program toperator37;
+
+operator <> (left: Pointer; right: Pointer) res : Boolean;
+begin
+
+end;
+
+begin
+
+end.

+ 11 - 0
tests/test/toperator38.pp

@@ -0,0 +1,11 @@
+{ %FAIL }
+program toperator38;
+
+operator > (left, right: LongInt) res : Boolean;
+begin
+
+end;
+
+begin
+
+end.

+ 11 - 0
tests/test/toperator39.pp

@@ -0,0 +1,11 @@
+{ %FAIL }
+program toperator39;
+
+operator >= (left, right: LongInt) res : Boolean;
+begin
+
+end;
+
+begin
+
+end.

+ 11 - 0
tests/test/toperator40.pp

@@ -0,0 +1,11 @@
+{ %FAIL }
+program toperator40;
+
+operator < (left, right: LongInt) res : Boolean;
+begin
+
+end;
+
+begin
+
+end.

+ 11 - 0
tests/test/toperator41.pp

@@ -0,0 +1,11 @@
+{ %FAIL }
+program toperator41;
+
+operator <= (left, right: LongInt) res : Boolean;
+begin
+
+end;
+
+begin
+
+end.

+ 11 - 0
tests/test/toperator42.pp

@@ -0,0 +1,11 @@
+{ %FAIL }
+program toperator42;
+
+operator = (left, right: LongInt) res : Boolean;
+begin
+
+end;
+
+begin
+
+end.

+ 11 - 0
tests/test/toperator43.pp

@@ -0,0 +1,11 @@
+{ %FAIL }
+program toperator43;
+
+operator <> (left, right: LongInt) res : Boolean;
+begin
+
+end;
+
+begin
+
+end.

+ 11 - 0
tests/test/toperator44.pp

@@ -0,0 +1,11 @@
+{ %FAIL }
+program toperator44;
+
+operator = (left, right: ShortString) res : Boolean;
+begin
+
+end;
+
+begin
+
+end.

+ 11 - 0
tests/test/toperator45.pp

@@ -0,0 +1,11 @@
+{ %FAIL }
+program toperator45;
+
+operator <> (left, right: ShortString) res : Boolean;
+begin
+
+end;
+
+begin
+
+end.

+ 11 - 0
tests/test/toperator46.pp

@@ -0,0 +1,11 @@
+{ %FAIL }
+program toperator46;
+
+operator > (left, right: ShortString) res : Boolean;
+begin
+
+end;
+
+begin
+
+end.

+ 11 - 0
tests/test/toperator47.pp

@@ -0,0 +1,11 @@
+{ %FAIL }
+program toperator47;
+
+operator < (left, right: ShortString) res : Boolean;
+begin
+
+end;
+
+begin
+
+end.

+ 11 - 0
tests/test/toperator48.pp

@@ -0,0 +1,11 @@
+{ %FAIL }
+program toperator48;
+
+operator + (left, right: ShortString) res : ShortString;
+begin
+
+end;
+
+begin
+
+end.

+ 11 - 0
tests/test/toperator49.pp

@@ -0,0 +1,11 @@
+{ %FAIL }
+program toperator49;
+
+operator + (left, right: AnsiString) res : AnsiString;
+begin
+
+end;
+
+begin
+
+end.

+ 11 - 0
tests/test/toperator50.pp

@@ -0,0 +1,11 @@
+{ %FAIL }
+program toperator50;
+
+operator + (left, right: WideString) res : WideString;
+begin
+
+end;
+
+begin
+
+end.

+ 11 - 0
tests/test/toperator51.pp

@@ -0,0 +1,11 @@
+{ %FAIL }
+program toperator51;
+
+operator + (left, right: UnicodeString) res : UnicodeString;
+begin
+
+end;
+
+begin
+
+end.

+ 11 - 0
tests/test/toperator52.pp

@@ -0,0 +1,11 @@
+{ %FAIL }
+program toperator52;
+
+operator + (left: ShortString; right: AnsiChar) res : ShortString;
+begin
+
+end;
+
+begin
+
+end.

+ 11 - 0
tests/test/toperator53.pp

@@ -0,0 +1,11 @@
+{ %FAIL }
+program toperator53;
+
+operator + (left: AnsiString; right: AnsiChar) res : AnsiString;
+begin
+
+end;
+
+begin
+
+end.

+ 11 - 0
tests/test/toperator54.pp

@@ -0,0 +1,11 @@
+{ %FAIL }
+program toperator54;
+
+operator + (left: WideString; right: WideChar) res : WideString;
+begin
+
+end;
+
+begin
+
+end.

+ 11 - 0
tests/test/toperator55.pp

@@ -0,0 +1,11 @@
+{ %FAIL }
+program toperator55;
+
+operator + (left: UnicodeString; right: UnicodeChar) res : UnicodeString;
+begin
+
+end;
+
+begin
+
+end.

+ 11 - 0
tests/test/toperator56.pp

@@ -0,0 +1,11 @@
+{ %FAIL }
+program toperator56;
+
+operator + (left: AnsiChar; right: ShortString) res : ShortString;
+begin
+
+end;
+
+begin
+
+end.

+ 11 - 0
tests/test/toperator57.pp

@@ -0,0 +1,11 @@
+{ %FAIL }
+program toperator57;
+
+operator + (left: AnsiChar; right: AnsiString) res : AnsiString;
+begin
+
+end;
+
+begin
+
+end.

+ 11 - 0
tests/test/toperator58.pp

@@ -0,0 +1,11 @@
+{ %FAIL }
+program toperator58;
+
+operator + (left: WideChar; right: WideString) res : WideString;
+begin
+
+end;
+
+begin
+
+end.

+ 11 - 0
tests/test/toperator59.pp

@@ -0,0 +1,11 @@
+{ %FAIL }
+program toperator59;
+
+operator + (left: UnicodeChar; right: UnicodeString) res : UnicodeString;
+begin
+
+end;
+
+begin
+
+end.

+ 11 - 0
tests/test/toperator60.pp

@@ -0,0 +1,11 @@
+{ %FAIL }
+program toperator60;
+
+operator + (left: AnsiString; right: PAnsiChar) res : AnsiString;
+begin
+
+end;
+
+begin
+
+end.

+ 11 - 0
tests/test/toperator61.pp

@@ -0,0 +1,11 @@
+{ %FAIL }
+program toperator61;
+
+operator + (left: UnicodeString; right: PUnicodeChar) res : UnicodeString;
+begin
+
+end;
+
+begin
+
+end.

+ 11 - 0
tests/test/toperator62.pp

@@ -0,0 +1,11 @@
+{ %FAIL }
+program toperator62;
+
+operator + (left: WideString; right: PWideChar) res : WideString;
+begin
+
+end;
+
+begin
+
+end.

+ 11 - 0
tests/test/toperator63.pp

@@ -0,0 +1,11 @@
+{ %FAIL }
+program toperator63;
+
+operator < (left, right: ShortString) res : Boolean;
+begin
+
+end;
+
+begin
+
+end.

+ 11 - 0
tests/test/toperator64.pp

@@ -0,0 +1,11 @@
+{ %FAIL }
+program toperator64;
+
+operator < (left, right: AnsiString) res : Boolean;
+begin
+
+end;
+
+begin
+
+end.

+ 11 - 0
tests/test/toperator65.pp

@@ -0,0 +1,11 @@
+{ %FAIL }
+program toperator65;
+
+operator < (left, right: WideString) res : Boolean;
+begin
+
+end;
+
+begin
+
+end.

+ 11 - 0
tests/test/toperator66.pp

@@ -0,0 +1,11 @@
+{ %FAIL }
+program toperator66;
+
+operator < (left, right: UnicodeString) res : Boolean;
+begin
+
+end;
+
+begin
+
+end.

+ 11 - 0
tests/test/toperator67.pp

@@ -0,0 +1,11 @@
+{ %FAIL }
+program toperator67;
+
+operator = (left, right: ShortString) res : Boolean;
+begin
+
+end;
+
+begin
+
+end.

+ 11 - 0
tests/test/toperator68.pp

@@ -0,0 +1,11 @@
+{ %FAIL }
+program toperator68;
+
+operator = (left, right: AnsiString) res : Boolean;
+begin
+
+end;
+
+begin
+
+end.

+ 11 - 0
tests/test/toperator69.pp

@@ -0,0 +1,11 @@
+{ %FAIL }
+program toperator69;
+
+operator = (left, right: WideString) res : Boolean;
+begin
+
+end;
+
+begin
+
+end.

+ 11 - 0
tests/test/toperator70.pp

@@ -0,0 +1,11 @@
+{ %FAIL }
+program toperator70;
+
+operator = (left, right: UnicodeString) res : Boolean;
+begin
+
+end;
+
+begin
+
+end.

+ 11 - 0
tests/test/toperator71.pp

@@ -0,0 +1,11 @@
+{ %FAIL }
+program toperator71;
+
+operator = (left, right: TObject) res : Boolean;
+begin
+
+end;
+
+begin
+
+end.

+ 11 - 0
tests/test/toperator72.pp

@@ -0,0 +1,11 @@
+{ %FAIL }
+program toperator72;
+
+operator = (left, right: Single) res : Boolean;
+begin
+
+end;
+
+begin
+
+end.

+ 11 - 0
tests/test/toperator73.pp

@@ -0,0 +1,11 @@
+{ %FAIL }
+program toperator73;
+
+operator < (left, right: Single) res : Boolean;
+begin
+
+end;
+
+begin
+
+end.

+ 11 - 0
tests/test/toperator74.pp

@@ -0,0 +1,11 @@
+{ %FAIL }
+program toperator74;
+
+operator * (left, right: Single) res : Single;
+begin
+
+end;
+
+begin
+
+end.

+ 11 - 0
tests/test/toperator75.pp

@@ -0,0 +1,11 @@
+{ %FAIL }
+program toperator75;
+
+operator / (left, right: Single) res : Single;
+begin
+
+end;
+
+begin
+
+end.

+ 11 - 0
tests/test/toperator76.pp

@@ -0,0 +1,11 @@
+{ %FAIL }
+program toperator76;
+
+operator = (left: Single; right: Currency) res : Boolean;
+begin
+
+end;
+
+begin
+
+end.

+ 11 - 0
tests/test/toperator77.pp

@@ -0,0 +1,11 @@
+{ %FAIL }
+program toperator77;
+
+operator = (left: Currency; right: LongInt) res : Boolean;
+begin
+
+end;
+
+begin
+
+end.

+ 65 - 0
tests/test/toperator78.pp

@@ -0,0 +1,65 @@
+{ %NORUN }
+program toperator78;
+
+operator ** (left, right: LongInt) res : LongInt;
+begin
+
+end;
+
+operator >< (left, right: LongInt) res : LongInt;
+begin
+
+end;
+
+operator + (left: LongInt; right: AnsiString) res : AnsiString;
+begin
+
+end;
+
+operator - (left, right: AnsiString) res : AnsiString;
+begin
+
+end;
+
+operator div (left, right: Single) res : Single;
+begin
+
+end;
+
+operator mod (left, right: Double) res : Double;
+begin
+
+end;
+
+type
+  TTest = (One, Two, Three);
+  TTests = set of TTest;
+
+operator and (left, right: TTests) res : TTests;
+begin
+
+end;
+
+operator < (left, right: TObject) res : Boolean;
+begin
+
+end;
+
+operator + (left: Pointer; right: ShortString) res : ShortString;
+begin
+
+end;
+
+operator and (left: array of Char; right: AnsiString) res : AnsiString;
+begin
+
+end;
+
+operator + (left: array of Char; right: TTest) res : ShortString;
+begin
+
+end;
+
+begin
+
+end.

+ 11 - 0
tests/test/toperator79.pp

@@ -0,0 +1,11 @@
+{ %FAIL }
+program toperator79;
+
+operator + (left, right: array of AnsiChar) res : PAnsiChar;
+begin
+
+end;
+
+begin
+
+end.

+ 11 - 0
tests/test/toperator80.pp

@@ -0,0 +1,11 @@
+{ %FAIL }
+program toperator80;
+
+operator = (left, right: array of AnsiChar) res : Boolean;
+begin
+
+end;
+
+begin
+
+end.

+ 11 - 0
tests/test/toperator81.pp

@@ -0,0 +1,11 @@
+{ %FAIL }
+program toperator81;
+
+operator + (left: array of AnsiChar; right: AnsiString) res : AnsiString;
+begin
+
+end;
+
+begin
+
+end.

+ 11 - 0
tests/test/toperator82.pp

@@ -0,0 +1,11 @@
+{ %FAIL }
+program toperator82;
+
+operator + (left: array of WideChar; right: WideString) res : WideString;
+begin
+
+end;
+
+begin
+
+end.

+ 11 - 0
tests/test/toperator83.pp

@@ -0,0 +1,11 @@
+{ %FAIL }
+program toperator83;
+
+operator + (left: array of UnicodeChar; right: UnicodeString) res : UnicodeString;
+begin
+
+end;
+
+begin
+
+end.

+ 11 - 0
tests/test/toperator84.pp

@@ -0,0 +1,11 @@
+{ %FAIL }
+program toperator84;
+
+operator + (left: array of AnsiChar; right: PAnsiChar) res : PAnsiChar;
+begin
+
+end;
+
+begin
+
+end.

+ 11 - 0
tests/test/toperator85.pp

@@ -0,0 +1,11 @@
+{ %FAIL }
+program toperator85;
+
+operator + (left: array of UnicodeChar; right: PUnicodeChar) res : PUnicodeChar;
+begin
+
+end;
+
+begin
+
+end.

+ 11 - 0
tests/test/toperator86.pp

@@ -0,0 +1,11 @@
+{ %FAIL }
+program toperator86;
+
+operator + (left: array of WideChar; right: PWideChar) res : PWideChar;
+begin
+
+end;
+
+begin
+
+end.