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