[fpc-devel] Unexpected "Range check error while evaluating constants" when compiling for Win64
Bart
bartjunk64 at gmail.com
Sun Feb 12 22:49:10 CET 2023
On Sun, Feb 12, 2023 at 10:43 PM Yuriy Sydorov via fpc-devel
<fpc-devel at lists.freepascal.org> wrote:
> Declarations like this have been made on purpose:
> HKEY_CURRENT_USER = HKEY(longint($80000001));
>
> On Win64 HKEY_CURRENT_USER must be $FFFFFFFF80000001, but on Win32 it must remain $80000001.
>
> See commit 2012220aec67494ac34329dabe8b6a05dacbb9c1 for details.
Found this piece of info:
(https://rt.cpan.org/Public/Bug/Display.html?id=108950)
The Windows SDK defines the HKEY values for the predefined keys by
first casting an original literal value (>= 0x80000000) to LONG
(signed 32-bit), then to ULONG_PTR (unsigned 32- or 64-bit, depending
on architecture), then to HKEY, such as in the following macro
definition for HKEY_CLASSES_ROOT in winreg.h:
#define HKEY_CLASSES_ROOT ((HKEY) (ULONG_PTR)((LONG)0x80000000))
For 32-bit builds this results in the final HKEY value being identical
to the original literal value, but for 64-bit builds, because of the
intermediate signed LONG cast which is then cast to the larger
unsigned ULONG_PTR type, the original value is effectively
sign-extended to 64-bits, resulting in the most significant 32 bits
being set. So in 64-bit architectures HKEY_CLASSES_ROOT is
0xFFFFFFFF80000000, HKEY_CURRENT_USER is 0xFFFFFFFF80000001, and so
on.
It seems that most of the Windows Reg* API functions (perhaps all of
the ones exposed by Win32API::Registry) compensate for being passed
32-bit versions of those predefined key handles, which apparently is
why Win32API::Registry isn't completely broken on 64-bit Perl builds.
I only noticed the problem when trying to pass the
Win32API::Registry::HKEY_* values to RegOverridePredefKey (used via
Win32::API), which seems to be an exception and fails with error code
6 (ERROR_INVALID_HANDLE) when passed 32-bit versions of those handles.
>
> Error "Range check error while evaluating constants (18446744071562067969 must be between -2147483648 and 4294967295)"
> is wrong here:
>
> property RootKey: HKey read FRootKey write FRootKey default HKEY_CURRENT_USER;
>
> Since HKEY = THandle = QWord on Win64, the reported range for it is incorrect.
If the reported range is incorrect, then the error is incorrect: the
value is perfectly inside the range of a QWord...
So, the question remains: is the compilation error a bug?
--
Bart
More information about the fpc-devel
mailing list