fpc-2.1.1 r4075
linux-i386

If I understand the purpose of function align 
(rtl/inc/{systemh.inc,generic.inc}) correctly, it gives wrong results 
when used with pointers > $8000000.

Align uses ptrint. Using ptrUint instead works.

I tried using it to align a array to 4k bounds, like this: 
p:=getmem(MyAry,sizeof(MyAry)+4096); p:=align(p,4096);  

IMO align($80000001,$1000) should give $80001000, but gives $80002000.

Attached is a testcase and a patch.
Index: rtl/inc/generic.inc
===================================================================
--- rtl/inc/generic.inc	(Revision 4059)
+++ rtl/inc/generic.inc	(Arbeitskopie)
@@ -990,7 +990,7 @@
 
 
 
-function align(addr : PtrInt;alignment : PtrInt) : PtrInt;{$ifdef SYSTEMINLINE}inline;{$endif}
+function align(addr : PtrUInt;alignment : PtrUInt) : PtrUInt;{$ifdef SYSTEMINLINE}inline;{$endif}
   begin
     if addr mod alignment<>0 then
       result:=addr+(alignment-(addr mod alignment))
@@ -999,10 +999,10 @@
   end;
 
 
-function align(addr : Pointer;alignment : PtrInt) : Pointer;{$ifdef SYSTEMINLINE}inline;{$endif}
+function align(addr : Pointer;alignment : PtrUInt) : Pointer;{$ifdef SYSTEMINLINE}inline;{$endif}
   begin
-    if PtrInt(addr) mod alignment<>0 then
-      result:=pointer(addr+(alignment-(PtrInt(addr) mod alignment)))
+    if PtrUInt(addr) mod alignment<>0 then
+      result:=pointer(addr+(alignment-(PtrUInt(addr) mod alignment)))
     else
       result:=addr;
   end;
Index: rtl/inc/systemh.inc
===================================================================
--- rtl/inc/systemh.inc	(Revision 4059)
+++ rtl/inc/systemh.inc	(Arbeitskopie)
@@ -434,8 +434,8 @@
 Function Swap (X : QWord) : QWord;{$ifdef SYSTEMINLINE}inline;{$endif}[internconst:fpc_in_const_swap_qword];
 Function swap (X : Int64) : Int64;{$ifdef SYSTEMINLINE}inline;{$endif}[internconst:fpc_in_const_swap_qword];
 
-Function Align (Addr : PtrInt; Alignment : PtrInt) : PtrInt;{$ifdef SYSTEMINLINE}inline;{$endif}
-Function Align (Addr : Pointer; Alignment : PtrInt) : Pointer;{$ifdef SYSTEMINLINE}inline;{$endif}
+Function Align (Addr : PtrUInt; Alignment : PtrUInt) : PtrUInt;{$ifdef SYSTEMINLINE}inline;{$endif}
+Function Align (Addr : Pointer; Alignment : PtrUInt) : Pointer;{$ifdef SYSTEMINLINE}inline;{$endif}
 
 Function  Random(l:longint):longint;
 Function  Random(l:int64):int64;
program writeroundtest;

{$mode objfpc}{$H+}

var
    ap1,ap2 : pointer;
    

function UINTalign(addr : Pointer;alignment : PtrUInt) : Pointer;
  begin
    if PtrUInt(addr) mod alignment<>0 then
      result:=pointer(addr+(alignment-(PtrUInt(addr) mod alignment)))
    else
      result:=addr;
  end;


begin
  ap1:=pointer($70000001);
  ap2:=pointer($80000001);
  writeln(hexstr(ap1),' --> ',hexstr(align(ap1,$1000)));
  writeln(hexstr(ap2),' --> ',hexstr(align(ap2,$1000)));
  writeln(hexstr(ap2),' --> ',hexstr(UINTalign(ap2,$1000)));
end.

_______________________________________________
fpc-devel maillist  -  [email protected]
http://lists.freepascal.org/mailman/listinfo/fpc-devel

Reply via email to