Browse Source

* adapted ranges of native types to int64 (e.g. high cardinal is no
longer longint($ffffffff), but just $fffffff in psystem)
* small additional fix in 64bit rangecheck code generation for 32 bit
processors
* adaption of ranges required the matching talgorithm used for selecting
which overloaded procedure to call to be adapted. It should now always
select the closest match for ordinal parameters.
+ inttostr(qword) in sysstr.inc/sysstrh.inc
+ abs(int64), sqr(int64), sqr(qword) in systemh.inc/generic.inc (previous
fixes were required to be able to add them)
* is_in_limit() moved from ncal to types unit, should always be used
instead of direct comparisons of low/high values of orddefs because
qword is a special case

Jonas Maebe 23 years ago
parent
commit
2b3898aeff
8 changed files with 244 additions and 34 deletions
  1. 22 3
      compiler/cg64f32.pas
  2. 47 18
      compiler/ncal.pas
  3. 22 6
      compiler/psystem.pas
  4. 47 2
      compiler/types.pas
  5. 48 1
      rtl/inc/generic.inc
  6. 20 2
      rtl/inc/systemh.inc
  7. 21 1
      rtl/objpas/sysstr.inc
  8. 17 1
      rtl/objpas/sysstrh.inc

+ 22 - 3
compiler/cg64f32.pas

@@ -247,7 +247,7 @@ unit cg64f32;
              { if the high dword = 0, the low dword can be considered a }
              { simple cardinal                                          }
              a_label(list,poslabel);
-             hdef:=torddef.create(u32bit,0,longint($ffffffff));
+             hdef:=torddef.create(u32bit,0,cardinal($ffffffff));
              { the real p.resulttype.def is already saved in fromdef }
              p.resulttype.def := hdef;
              { no use in calling just "g_rangecheck" since that one will }
@@ -358,8 +358,27 @@ begin
 end.
 {
   $Log$
-  Revision 1.2  2001-12-30 17:24:48  jonas
-    * range checking is now processor independent (part in cgobj, part in
    cg64f32) and should work correctly again (it needed some changes after
    the changes of the low and high of tordef's to int64)
  * maketojumpbool() is now processor independent (in ncgutil)
  * getregister32 is now called getregisterint
+  Revision 1.3  2002-01-24 12:33:52  jonas
+    * adapted ranges of native types to int64 (e.g. high cardinal is no
+      longer longint($ffffffff), but just $fffffff in psystem)
+    * small additional fix in 64bit rangecheck code generation for 32 bit
+      processors
+    * adaption of ranges required the matching talgorithm used for selecting
+      which overloaded procedure to call to be adapted. It should now always
+      select the closest match for ordinal parameters.
+    + inttostr(qword) in sysstr.inc/sysstrh.inc
+    + abs(int64), sqr(int64), sqr(qword) in systemh.inc/generic.inc (previous
+      fixes were required to be able to add them)
+    * is_in_limit() moved from ncal to types unit, should always be used
+      instead of direct comparisons of low/high values of orddefs because
+      qword is a special case
+
+  Revision 1.2  2001/12/30 17:24:48  jonas
+    * range checking is now processor independent (part in cgobj, part in
+    cg64f32) and should work correctly again (it needed some changes after
+    the changes of the low and high of tordef's to int64)
+  * maketojumpbool() is now processor independent (in ncgutil)
+  * getregister32 is now called getregisterint
 
   Revision 1.1  2001/12/29 15:29:58  jonas
     * powerpc/cgcpu.pas compiles :)

+ 47 - 18
compiler/ncal.pas

@@ -777,14 +777,6 @@ implementation
              ;
         end;
 
-      function is_in_limit(def_from,def_to : tdef) : boolean;
-
-        begin
-           is_in_limit:=(def_from.deftype = orddef) and
-                        (def_to.deftype = orddef) and
-                        (torddef(def_from).low>torddef(def_to).low) and
-                        (torddef(def_from).high<torddef(def_to).high);
-        end;
 
       var
         i : longint;
@@ -1114,6 +1106,9 @@ implementation
                                          begin
                                             exactmatch:=true;
                                             conv_to:=def_to;
+                                            { there's no use in continuing the search, it will }
+                                            { only result in conv_to being overwritten         }
+                                            break;
                                          end;
                                     end;
                                   hp:=hp^.next;
@@ -1133,7 +1128,8 @@ implementation
                                   hp:=procs;
                                   while (assigned(hp)) and assigned(hp^.next) do
                                     begin
-                                       if not(is_in_limit(def_from,hp^.next^.nextPara.paratype.def)) then
+                                       def_to:=hp^.next^.nextPara.paratype.def;
+                                       if not(is_in_limit(def_from,def_to)) then
                                          begin
                                             hp2:=hp^.next^.next;
                                             dispose(hp^.next);
@@ -1141,18 +1137,36 @@ implementation
                                          end
                                        else
                                          begin
-                                           def_to:=hp^.next^.nextPara.paratype.def;
+                                           { did we possibly find a better match? }
                                            if (conv_to.size>def_to.size) or
-                                              ((torddef(conv_to).low<torddef(def_to).low) and
-                                              (torddef(conv_to).high>torddef(def_to).high)) then
+                                              is_in_limit(def_to,conv_to) then
                                              begin
-                                                hp2:=procs;
-                                                procs:=hp;
-                                                conv_to:=def_to;
-                                                dispose(hp2);
+                                                { is it the same as the previous best? }
+                                                if not types.is_equal(def_to,conv_to) then
+                                                  begin
+                                                    { no -> remove all previous best matches }
+                                                    hp := hp^.next;
+                                                    while procs <> hp do
+                                                      begin
+                                                        hp2 := procs;
+                                                        procs := procs^.next;
+                                                        dispose(hp2);
+                                                      end;
+                                                    { set new match type }
+                                                    conv_to:=def_to;
+                                                  end
+                                                { the new one matches just as well as the }
+                                                { old one -> keep both                    }
+                                                else
+                                                  hp := hp^.next;
                                              end
+                                           { not a better match -> remove }
                                            else
-                                             hp:=hp^.next;
+                                             begin
+                                               hp2 := hp^.next^.next;
+                                               dispose(hp^.next);
+                                               hp^.next:=hp2;
+                                             end;
                                          end;
                                     end;
                                end;
@@ -1782,7 +1796,22 @@ begin
 end.
 {
   $Log$
-  Revision 1.62  2002-01-19 11:57:05  peter
+  Revision 1.63  2002-01-24 12:33:52  jonas
+    * adapted ranges of native types to int64 (e.g. high cardinal is no
+      longer longint($ffffffff), but just $fffffff in psystem)
+    * small additional fix in 64bit rangecheck code generation for 32 bit
+      processors
+    * adaption of ranges required the matching talgorithm used for selecting
+      which overloaded procedure to call to be adapted. It should now always
+      select the closest match for ordinal parameters.
+    + inttostr(qword) in sysstr.inc/sysstrh.inc
+    + abs(int64), sqr(int64), sqr(qword) in systemh.inc/generic.inc (previous
+      fixes were required to be able to add them)
+    * is_in_limit() moved from ncal to types unit, should always be used
+      instead of direct comparisons of low/high values of orddefs because
+      qword is a special case
+
+  Revision 1.62  2002/01/19 11:57:05  peter
     * fixed path appending for lib
 
   Revision 1.61  2001/12/31 16:59:41  peter

+ 22 - 6
compiler/psystem.pas

@@ -40,7 +40,8 @@ implementation
 uses
   globals,
   symconst,symtype,symsym,symdef,symtable,
-  ninl;
+  ninl,
+  cpuinfo;
 
 procedure insertinternsyms(p : tsymtable);
 {
@@ -229,10 +230,10 @@ begin
   voidtype.setdef(torddef.create(uvoid,0,0));
   u8bittype.setdef(torddef.create(u8bit,0,255));
   u16bittype.setdef(torddef.create(u16bit,0,65535));
-  u32bittype.setdef(torddef.create(u32bit,0,longint($ffffffff)));
-  s32bittype.setdef(torddef.create(s32bit,longint($80000000),$7fffffff));
-  cu64bittype.setdef(torddef.create(u64bit,0,0));
-  cs64bittype.setdef(torddef.create(s64bit,0,0));
+  u32bittype.setdef(torddef.create(u32bit,0,high(cardinal)));
+  s32bittype.setdef(torddef.create(s32bit,low(longint),high(longint)));
+  cu64bittype.setdef(torddef.create(u64bit,low(qword),TConstExprInt(high(qword))));
+  cs64bittype.setdef(torddef.create(s64bit,low(int64),high(int64)));
   booltype.setdef(torddef.create(bool8bit,0,1));
   cchartype.setdef(torddef.create(uchar,0,255));
   cwidechartype.setdef(torddef.create(uwidechar,0,65535));
@@ -276,7 +277,22 @@ end;
 end.
 {
   $Log$
-  Revision 1.21  2001-11-18 18:43:14  peter
+  Revision 1.22  2002-01-24 12:33:53  jonas
+    * adapted ranges of native types to int64 (e.g. high cardinal is no
+      longer longint($ffffffff), but just $fffffff in psystem)
+    * small additional fix in 64bit rangecheck code generation for 32 bit
+      processors
+    * adaption of ranges required the matching talgorithm used for selecting
+      which overloaded procedure to call to be adapted. It should now always
+      select the closest match for ordinal parameters.
+    + inttostr(qword) in sysstr.inc/sysstrh.inc
+    + abs(int64), sqr(int64), sqr(qword) in systemh.inc/generic.inc (previous
+      fixes were required to be able to add them)
+    * is_in_limit() moved from ncal to types unit, should always be used
+      instead of direct comparisons of low/high values of orddefs because
+      qword is a special case
+
+  Revision 1.21  2001/11/18 18:43:14  peter
     * overloading supported in child classes
     * fixed parsing of classes with private and virtual and overloaded
       so it is compatible with delphi

+ 47 - 2
compiler/types.pas

@@ -74,6 +74,10 @@ interface
     { returns true, if def defines a signed data type (only for ordinal types) }
     function is_signed(def : tdef) : boolean;
 
+    { returns whether def_from's range is comprised in def_to's if both are }
+    { orddefs, false otherwise                                              }
+    function is_in_limit(def_from,def_to : tdef) : boolean;
+
 {*****************************************************************************
                               Array helper functions
  *****************************************************************************}
@@ -631,6 +635,27 @@ implementation
       end;
 
 
+    function is_in_limit(def_from,def_to : tdef) : boolean;
+
+      var
+        fromqword, toqword: boolean;
+
+      begin
+         if (def_from.deftype <> orddef) or
+            (def_to.deftype <> orddef) then
+           begin
+             is_in_limit := false;
+             exit;
+           end;
+         fromqword := torddef(def_from).typ = u64bit;
+         toqword := torddef(def_to).typ = u64bit;
+         is_in_limit:=((not(fromqword xor toqword) and
+                        (torddef(def_from).low>=torddef(def_to).low) and
+                        (torddef(def_from).high<=torddef(def_to).high)) or
+                       (toqword and not is_signed(def_from)));
+      end;
+
+
     { true, if p points to an open array def }
     function is_open_string(p : tdef) : boolean;
       begin
@@ -1407,7 +1432,12 @@ implementation
                         ((doconv=tc_bool_2_int) and
                          (not explicit) and
                          (not is_boolean(def_to))) then
-                       b:=0;
+                       b:=0
+                     else
+                       { "punish" bad type conversions :) (JM) }
+                       if not is_in_limit(def_from,def_to) and
+                          (def_from.size > def_to.size) then
+                         b := 2;
                    end;
                  enumdef :
                    begin
@@ -1923,7 +1953,22 @@ implementation
 end.
 {
   $Log$
-  Revision 1.62  2002-01-06 21:50:44  peter
+  Revision 1.63  2002-01-24 12:33:53  jonas
+    * adapted ranges of native types to int64 (e.g. high cardinal is no
+      longer longint($ffffffff), but just $fffffff in psystem)
+    * small additional fix in 64bit rangecheck code generation for 32 bit
+      processors
+    * adaption of ranges required the matching talgorithm used for selecting
+      which overloaded procedure to call to be adapted. It should now always
+      select the closest match for ordinal parameters.
+    + inttostr(qword) in sysstr.inc/sysstrh.inc
+    + abs(int64), sqr(int64), sqr(qword) in systemh.inc/generic.inc (previous
+      fixes were required to be able to add them)
+    * is_in_limit() moved from ncal to types unit, should always be used
+      instead of direct comparisons of low/high values of orddefs because
+      qword is a special case
+
+  Revision 1.62  2002/01/06 21:50:44  peter
     * proc_to_procvar_equal fixed for procvar-procvar
 
   Revision 1.61  2002/01/06 12:08:16  peter

+ 48 - 1
rtl/inc/generic.inc

@@ -795,6 +795,38 @@ end;
 {$endif ndef FPC_SYSTEM_HAS_SQR_LONGINT}
 
 
+{$ifndef FPC_SYSTEM_HAS_ABS_INT64}
+
+function abs(l: Int64): Int64;
+begin
+  if l < 0 then
+    abs := -l
+  else
+    abs := l;
+end;
+
+{$endif ndef FPC_SYSTEM_HAS_ABS_INT64}
+
+
+{$ifndef FPC_SYSTEM_HAS_SQR_INT64}
+
+function sqr(l: Int64): Int64;
+begin
+  sqr := l*l;
+end;
+
+{$endif ndef FPC_SYSTEM_HAS_SQR_INT64}
+
+
+{$ifndef FPC_SYSTEM_HAS_SQR_QWORD}
+
+function sqr(l: QWord): QWord;
+begin
+  sqr := l*l;
+end;
+
+{$endif ndef FPC_SYSTEM_HAS_SQR_INT64}
+
 {$ifndef FPC_SYSTEM_HAS_SPTR}
 {$error Sptr must be defined for each processor }
 {$endif ndef FPC_SYSTEM_HAS_SPTR}
@@ -891,7 +923,22 @@ end;
 
 {
   $Log$
-  Revision 1.21  2001-09-03 13:27:43  jonas
+  Revision 1.22  2002-01-24 12:33:53  jonas
+    * adapted ranges of native types to int64 (e.g. high cardinal is no
+      longer longint($ffffffff), but just $fffffff in psystem)
+    * small additional fix in 64bit rangecheck code generation for 32 bit
+      processors
+    * adaption of ranges required the matching talgorithm used for selecting
+      which overloaded procedure to call to be adapted. It should now always
+      select the closest match for ordinal parameters.
+    + inttostr(qword) in sysstr.inc/sysstrh.inc
+    + abs(int64), sqr(int64), sqr(qword) in systemh.inc/generic.inc (previous
+      fixes were required to be able to add them)
+    * is_in_limit() moved from ncal to types unit, should always be used
+      instead of direct comparisons of low/high values of orddefs because
+      qword is a special case
+
+  Revision 1.21  2001/09/03 13:27:43  jonas
     * compilerproc implementation of set addition/substraction/...
     * changed the declaration of some set helpers somewhat to accomodate the
       above change

+ 20 - 2
rtl/inc/systemh.inc

@@ -289,7 +289,10 @@ Function  Random: extended;
 Procedure Randomize;
 
 Function abs(l:Longint):Longint;
+Function abs(l:Int64):Int64;
 Function sqr(l:Longint):Longint;
+Function sqr(l:Int64):Int64;
+Function sqr(l:QWord):QWord;
 Function odd(l:Longint):Boolean;
 Function odd(l:Cardinal):Boolean;
 Function odd(l:Int64):Boolean;
@@ -555,7 +558,22 @@ const
 
 {
   $Log$
-  Revision 1.39  2001-11-14 22:59:11  michael
+  Revision 1.40  2002-01-24 12:33:53  jonas
+    * adapted ranges of native types to int64 (e.g. high cardinal is no
+      longer longint($ffffffff), but just $fffffff in psystem)
+    * small additional fix in 64bit rangecheck code generation for 32 bit
+      processors
+    * adaption of ranges required the matching talgorithm used for selecting
+      which overloaded procedure to call to be adapted. It should now always
+      select the closest match for ordinal parameters.
+    + inttostr(qword) in sysstr.inc/sysstrh.inc
+    + abs(int64), sqr(int64), sqr(qword) in systemh.inc/generic.inc (previous
+      fixes were required to be able to add them)
+    * is_in_limit() moved from ncal to types unit, should always be used
+      instead of direct comparisons of low/high values of orddefs because
+      qword is a special case
+
+  Revision 1.39  2001/11/14 22:59:11  michael
   + Initial variant support
 
   Revision 1.38  2001/11/07 14:59:20  michael
@@ -693,4 +711,4 @@ const
   Revision 1.2  2000/07/13 11:33:45  michael
   + removed logs
 
-}
+}

+ 21 - 1
rtl/objpas/sysstr.inc

@@ -528,6 +528,11 @@ begin
  System.Str(Value, result);
 end ;
 
+function IntToStr(Value: QWord): string;
+begin
+ System.Str(Value, result);
+end ;
+
 
 {   IntToHex returns a string representing the hexadecimal value of Value   }
 
@@ -1324,7 +1329,22 @@ const
 
 {
   $Log$
-  Revision 1.13  2001-09-20 14:38:41  michael
+  Revision 1.14  2002-01-24 12:33:53  jonas
+    * adapted ranges of native types to int64 (e.g. high cardinal is no
+      longer longint($ffffffff), but just $fffffff in psystem)
+    * small additional fix in 64bit rangecheck code generation for 32 bit
+      processors
+    * adaption of ranges required the matching talgorithm used for selecting
+      which overloaded procedure to call to be adapted. It should now always
+      select the closest match for ordinal parameters.
+    + inttostr(qword) in sysstr.inc/sysstrh.inc
+    + abs(int64), sqr(int64), sqr(qword) in systemh.inc/generic.inc (previous
+      fixes were required to be able to add them)
+    * is_in_limit() moved from ncal to types unit, should always be used
+      instead of direct comparisons of low/high values of orddefs because
+      qword is a special case
+
+  Revision 1.13  2001/09/20 14:38:41  michael
    Implemented missing StringReplace function
 
   Revision 1.12  2001/08/01 21:44:20  peter

+ 17 - 1
rtl/objpas/sysstrh.inc

@@ -73,6 +73,7 @@ function AdjustLineBreaks(const S: string): string;
 function IsValidIdent(const Ident: string): boolean;
 function IntToStr(Value: integer): string;
 function IntToStr(Value: Int64): string;
+function IntToStr(Value: QWord): string;
 function IntToHex(Value: integer; Digits: integer): string;
 function IntToHex(Value: Int64; Digits: integer): string;
 function StrToInt(const s: string): integer;
@@ -109,7 +110,22 @@ function BCDToInt(Value: integer): integer;
 
 {
   $Log$
-  Revision 1.9  2001-09-20 14:42:34  michael
+  Revision 1.10  2002-01-24 12:33:54  jonas
+    * adapted ranges of native types to int64 (e.g. high cardinal is no
+      longer longint($ffffffff), but just $fffffff in psystem)
+    * small additional fix in 64bit rangecheck code generation for 32 bit
+      processors
+    * adaption of ranges required the matching talgorithm used for selecting
+      which overloaded procedure to call to be adapted. It should now always
+      select the closest match for ordinal parameters.
+    + inttostr(qword) in sysstr.inc/sysstrh.inc
+    + abs(int64), sqr(int64), sqr(qword) in systemh.inc/generic.inc (previous
+      fixes were required to be able to add them)
+    * is_in_limit() moved from ncal to types unit, should always be used
+      instead of direct comparisons of low/high values of orddefs because
+      qword is a special case
+
+  Revision 1.9  2001/09/20 14:42:34  michael
   + Implemented missing StringReplace function
 
   Revision 1.6  2000/12/09 10:39:50  florian