From 95637dea751a72a02897a8f76743c15038d97b46 Mon Sep 17 00:00:00 2001 From: Jonas Maebe Date: Tue, 29 Apr 2008 22:14:43 +0000 Subject: [PATCH] * fixed swapendian(smallint) (bug found by Joost van der Sluis) * based swap(smallint) and swap(word) on swapendian(smallint/word), since the same bug was already fixed in swap(smallint) in r6752 (so these routines now share the same code) * fixed potential range error in swapendian(word) + added basic test for the above four routines git-svn-id: trunk@10840 - --- .gitattributes | 1 + rtl/inc/generic.inc | 8 ++++++-- rtl/inc/system.inc | 12 ++++-------- tests/tbs/tb0548.pp | 30 ++++++++++++++++++++++++++++++ 4 files changed, 41 insertions(+), 10 deletions(-) create mode 100644 tests/tbs/tb0548.pp diff --git a/.gitattributes b/.gitattributes index 98dd68e3ec..b3bd547b9a 100644 --- a/.gitattributes +++ b/.gitattributes @@ -6834,6 +6834,7 @@ tests/tbs/tb0544.pp svneol=native#text/plain tests/tbs/tb0545.pp svneol=native#text/plain tests/tbs/tb0546.pp svneol=native#text/plain tests/tbs/tb0547.pp svneol=native#text/plain +tests/tbs/tb0548.pp svneol=native#text/plain tests/tbs/tb205.pp svneol=native#text/plain tests/tbs/ub0060.pp svneol=native#text/plain tests/tbs/ub0069.pp svneol=native#text/plain diff --git a/rtl/inc/generic.inc b/rtl/inc/generic.inc index dc9e15d15e..e583e2dcf8 100644 --- a/rtl/inc/generic.inc +++ b/rtl/inc/generic.inc @@ -1707,13 +1707,17 @@ end; {$ifndef FPC_SYSTEM_HAS_SWAPENDIAN} function SwapEndian(const AValue: SmallInt): SmallInt; begin - Result := (AValue shr 8) or (AValue shl 8); + { the extra Word type cast is necessary because the "AValue shr 8" } + { is turned into "longint(AValue) shr 8", so if AValue < 0 then } + { the sign bits from the upper 16 bits are shifted in rather than } + { zeroes. } + Result := SmallInt((Word(AValue) shr 8) or (AValue shl 8)); end; function SwapEndian(const AValue: Word): Word; begin - Result := (AValue shr 8) or (AValue shl 8); + Result := Word((AValue shr 8) or (AValue shl 8)); end; diff --git a/rtl/inc/system.inc b/rtl/inc/system.inc index 0ea21316f6..b3163e1644 100644 --- a/rtl/inc/system.inc +++ b/rtl/inc/system.inc @@ -245,21 +245,17 @@ begin Lo := b and $0f end; -Function swap (X : Word) : Word;{$ifdef SYSTEMINLINE}inline;{$endif} +Function Swap (X : Word) : Word;{$ifdef SYSTEMINLINE}inline;{$endif} Begin - swap:=(X and $ff) shl 8 + (X shr 8) + Swap := SwapEndian(X); End; Function Swap (X : Integer) : Integer;{$ifdef SYSTEMINLINE}inline;{$endif} Begin - { the extra 'and $ff' in the right term is necessary because the } - { 'X shr 8' is turned into "longint(X) shr 8", so if x < 0 then } - { the sign bits from the upper 16 bits are shifted in rather than } - { zeroes. Another bug for TP/Delphi compatibility... } - swap:=(X and $ff) shl 8 + ((X shr 8) and $ff) + Swap := SwapEndian(X); End; -Function swap (X : Longint) : Longint;{$ifdef SYSTEMINLINE}inline;{$endif} +Function Swap (X : Longint) : Longint;{$ifdef SYSTEMINLINE}inline;{$endif} Begin Swap:=(X and $ffff) shl 16 + (X shr 16) End; diff --git a/tests/tbs/tb0548.pp b/tests/tbs/tb0548.pp new file mode 100644 index 0000000000..750442d1a9 --- /dev/null +++ b/tests/tbs/tb0548.pp @@ -0,0 +1,30 @@ +{$r+} +{$q+} + +var + wo: word; + si: smallint; + +begin + wo:=$9876; + if swap(wo)<>$7698 then + halt(1); + if swapendian(wo)<>$7698 then + halt(2); + wo:=$1290; + if swap(wo)<>$9012 then + halt(3); + if swapendian(wo)<>$9012 then + halt(4); + + si:=smallint($9876); + if swap(si)<>$7698 then + halt(5); + if swapendian(si)<>$7698 then + halt(6); + si:=$1290; + if swap(si)<>smallint($9012) then + halt(7); + if swapendian(si)<>smallint($9012) then + halt(8); +end.