Browse Source

* Delphi allows comparisons (>, >=, < and <=, but not = or <>) for different pointer types if POINTERMATH is enabled either for the involved code or for both involved pointer types
+ added tests

Sven/Sarah Barth 4 days ago
parent
commit
4a1af9eb69
4 changed files with 115 additions and 1 deletions
  1. 16 1
      compiler/nadd.pas
  2. 57 0
      tests/test/tpointermath4.pp
  3. 27 0
      tests/test/tpointermath5.pp
  4. 15 0
      tests/test/tpointermath6.pp

+ 16 - 1
compiler/nadd.pas

@@ -2874,7 +2874,22 @@ const
                         inserttypeconv(right,left.resultdef)
                        else if is_voidpointer(left.resultdef) then
                         inserttypeconv(left,right.resultdef)
-                       else if not(equal_defs(ld,rd)) then
+                       else if not (
+                           { in Delphi two different pointer types can be compared
+                             if either $POINTERMATH is currently enabled or if
+                             both pointer defs were declared with $POINTERMATH
+                             enabled }
+                           (m_delphi in current_settings.modeswitches) and
+                           (ld.typ=pointerdef) and
+                           (rd.typ=pointerdef) and
+                           (
+                             (cs_pointermath in current_settings.localswitches) or
+                             (
+                               tpointerdef(ld).has_pointer_math and
+                               tpointerdef(rd).has_pointer_math
+                             )
+                           )
+                         ) and not(equal_defs(ld,rd)) then
                         IncompatibleTypes(ld,rd);
                      end
                     else

+ 57 - 0
tests/test/tpointermath4.pp

@@ -0,0 +1,57 @@
+{ %NORUN }
+
+program tpointermath4;
+
+{$mode delphi}
+
+type
+{$POINTERMATH ON}
+  PMyCardinal = ^Cardinal;
+  PMyByte = ^Byte;
+  PMyString = ^String;
+{$POINTERMATH OFF}
+
+procedure Test;
+var
+  pc: PMyCardinal;
+  pb: PMyByte;
+  ps: PMyString;
+  b: Boolean;
+begin
+  b := pc > pb;
+  b := pc < pb;
+  b := ps < pb;
+  b := ps > pb;
+  b := pc < ps;
+  b := pc > ps;
+
+  b := pc >= pb;
+  b := pc <= pb;
+  b := ps <= pb;
+  b := ps >= pb;
+  b := pc <= ps;
+  b := pc >= ps;
+end;
+
+{$pointermath on}
+
+var
+  pc: PCardinal = Nil;
+  pb: PByte = Nil;
+  ps: PString = Nil;
+  b: Boolean;
+begin
+  b := pc > pb;
+  b := pc < pb;
+  b := ps < pb;
+  b := ps > pb;
+  b := pc < ps;
+  b := pc > ps;
+
+  b := pc >= pb;
+  b := pc <= pb;
+  b := ps <= pb;
+  b := ps >= pb;
+  b := pc <= ps;
+  b := pc >= ps;
+end.

+ 27 - 0
tests/test/tpointermath5.pp

@@ -0,0 +1,27 @@
+{ %FAIL }
+
+program tpointermath5;
+
+{$mode delphi}
+
+{ both pointer types need to have POINTERMATH enabled for comparisons to be
+  supported between them }
+
+type
+  PMyCardinal = ^Cardinal;
+{$POINTERMATH ON}
+  PMyByte = ^Byte;
+{$POINTERMATH OFF}
+
+procedure Test;
+var
+  pc: PMyCardinal;
+  pb: PMyByte;
+  b: Boolean;
+begin
+  b := pc > pb;
+  b := pc < pb;
+end;
+
+begin
+end.

+ 15 - 0
tests/test/tpointermath6.pp

@@ -0,0 +1,15 @@
+{ %FAIL }
+
+program tpointermath6;
+
+{$mode objfpc}
+{$pointermath on}
+
+var
+  pc: PCardinal;
+  pb: PByte;
+  b: Boolean;
+begin
+  b := pc < pb;
+end.
+