View Issue Details

IDProjectCategoryView StatusLast Update
0029460FPCCompilerpublic2019-07-12 11:40
ReporterOndrej PokornyAssigned To 
PrioritynormalSeverityminorReproducibilityalways
Status newResolutionopen 
Product Version3.1.1Product Build 
Target VersionFixed in Version 
Summary0029460: Cannot declare "LongInt = AnsiString" comparison operator
DescriptionWhen I want to declare "LongInt = AnsiString" comparison operator, the compiler tells me "Impossible operator overload" although it is documented to work.

http://lazarus-ccr.sourceforge.net/fpcdoc/ref/refse67.html#x156-16300012.5 :
The comparision operator can be overloaded to compare two different types or to compare two equal types that are not basic types.
Steps To ReproduceCompile the following program:

program project1;

{$mode objfpc}{$H+}
{$modeswitch advancedrecords}

operator = (z1: LongInt; z2 : ansistring) b : boolean;
begin
  b := false;
end;

var
  i: longint;
  s: string;
begin
  writeln(i = s);
  readln;
end.
TagsNo tags attached.
Fixed in Revision
FPCOldBugId
FPCTarget
Attached Files
  • longint.equals.string.operator.overload.diff (590 bytes)
    Index: compiler/htypechk.pas
    ===================================================================
    --- compiler/htypechk.pas	(revision 41788)
    +++ compiler/htypechk.pas	(working copy)
    @@ -330,6 +330,7 @@
                                  (treetyp in order_theoretic_operators)
                                ) or
                                (
    +                             (m_mac in current_settings.modeswitches) and
                                  is_stringlike(rd) and
                                  (ld.typ=orddef) and
                                  (treetyp in string_comparison_operators)) or
    

Activities

Thaddy de Koning

2016-01-21 08:12

reporter   ~0089142

Last edited: 2016-01-21 09:02

View 2 revisions

Yes, confirmed. For trunk and also for 3.0
Funny is that the operator with reversed parameter overload does work:

operator = (z1: ansistring; z2 : longint) b : boolean;
begin
  b := false;
end;

The operator in question is not already in use somewhere, because then the code would work w/o the declaration.

Bart Broersma

2019-04-03 18:22

reporter   ~0115197

The operator (left=integer, right=string) fails in
IsOperatorAcceptable:
  optoken=_EQ, count=2
  tok2node[5].tok=optoken
  ld.gettypename=LongInt, rd.gettypename=AnsiString
  tok2node[5].nod=equaln
  isbinaryoperatoroverloadable(tok2node[5].nod,ld,nothingn,rd,nothingn)=FALSE

Bart Broersma

2019-04-03 19:02

reporter   ~0115198

Last edited: 2019-04-03 19:05

View 2 revisions

in function isbinaryoperatoroverloadable
in the nested function internal_check
this block of code:

          case ld.typ of (ld.typ=orddef in this case)
....

            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 }
                           );
 
will set Allowed to False.

Bart Broersma

2019-04-03 23:33

reporter   ~0115209

Last edited: 2019-04-03 23:33

View 2 revisions

It seems that in MacPas mode you are allowed to do:
  if WordVariable = StringVariable
but not the other way around.
This seems to be the reason you cannot overload the operator this way (but you can the other way around).

A check for compilermode should maybe be added?

Bart Broersma

2019-04-03 23:46

reporter  

longint.equals.string.operator.overload.diff (590 bytes)
Index: compiler/htypechk.pas
===================================================================
--- compiler/htypechk.pas	(revision 41788)
+++ compiler/htypechk.pas	(working copy)
@@ -330,6 +330,7 @@
                              (treetyp in order_theoretic_operators)
                            ) or
                            (
+                             (m_mac in current_settings.modeswitches) and
                              is_stringlike(rd) and
                              (ld.typ=orddef) and
                              (treetyp in string_comparison_operators)) or

Bart Broersma

2019-04-03 23:46

reporter   ~0115210

Possible patch attached in longint.equals.string.operator.overload.diff

Bart Broersma

2019-04-07 23:23

reporter   ~0115313

Last edited: 2019-07-12 11:40

View 2 revisions

Is it even possible to do operator overloading in MacPas mode?
ETA: No.

Issue History

Date Modified Username Field Change
2016-01-21 02:18 Ondrej Pokorny New Issue
2016-01-21 08:12 Thaddy de Koning Note Added: 0089142
2016-01-21 09:02 Thaddy de Koning Note Edited: 0089142 View Revisions
2019-04-03 18:22 Bart Broersma Note Added: 0115197
2019-04-03 19:02 Bart Broersma Note Added: 0115198
2019-04-03 19:05 Bart Broersma Note Edited: 0115198 View Revisions
2019-04-03 23:33 Bart Broersma Note Added: 0115209
2019-04-03 23:33 Bart Broersma Note Edited: 0115209 View Revisions
2019-04-03 23:46 Bart Broersma File Added: longint.equals.string.operator.overload.diff
2019-04-03 23:46 Bart Broersma Note Added: 0115210
2019-04-07 23:23 Bart Broersma Note Added: 0115313
2019-07-12 11:40 Bart Broersma Note Edited: 0115313 View Revisions