Avoid warnings about casts between HANDLE and int in Win64 builds

Add helper thandle_{from,to}_int() functions performing the casts
between (64-bit, under Win64) thandle_t and (32-bit, always) int in a
way that doesn't trigger compiler warnings.

Also explain why suppressing these warnings is the right thing to do.

Closes https://gitlab.com/libtiff/libtiff/issues/2
This commit is contained in:
Vadim Zeitlin 2019-10-06 01:47:06 +02:00
parent 43b0c984f0
commit cad76c5b08

View File

@ -27,34 +27,38 @@
* Scott Wagner (wagner@itek.com), Itek Graphix, Rochester, NY USA * Scott Wagner (wagner@itek.com), Itek Graphix, Rochester, NY USA
*/ */
/*
CreateFileA/CreateFileW return type 'HANDLE'.
thandle_t is declared like
DECLARE_HANDLE(thandle_t);
in tiffio.h.
Windows (from winnt.h) DECLARE_HANDLE logic looks like
#ifdef STRICT
typedef void *HANDLE;
#define DECLARE_HANDLE(name) struct name##__ { int unused; }; typedef struct name##__ *name
#else
typedef PVOID HANDLE;
#define DECLARE_HANDLE(name) typedef HANDLE name
#endif
See http://bugzilla.maptools.org/show_bug.cgi?id=1941 for problems in WIN64
builds resulting from this. Unfortunately, the proposed patch was lost.
*/
#include "tiffiop.h" #include "tiffiop.h"
#include <windows.h> #include <windows.h>
/*
CreateFileA/CreateFileW return type 'HANDLE' while TIFFFdOpen() takes 'int',
which is formally incompatible and can even seemingly be of different size:
HANDLE is 64 bit under Win64, while int is still 32 bits there.
However, only the lower 32 bits of a HANDLE are significant under Win64 as,
for interoperability reasons, they must have the same values in 32- and
64-bit programs running on the same system, see
https://docs.microsoft.com/en-us/windows/win32/winprog64/interprocess-communication
Because of this, it is safe to define the following trivial functions for
casting between ints and HANDLEs, which are only really needed to avoid
compiler warnings (and, perhaps, to make the code slightly more clear).
Note that using the intermediate cast to "intptr_t" is crucial for warning
avoidance, as this integer type has the same size as HANDLE in all builds.
*/
static inline thandle_t thandle_from_int(int ifd)
{
return (thandle_t)(intptr_t)ifd;
}
static inline int thandle_to_int(thandle_t fd)
{
return (int)(intptr_t)fd;
}
static tmsize_t static tmsize_t
_tiffReadProc(thandle_t fd, void* buf, tmsize_t size) _tiffReadProc(thandle_t fd, void* buf, tmsize_t size)
{ {
@ -237,7 +241,7 @@ TIFFFdOpen(int ifd, const char* name, const char* mode)
break; break;
} }
} }
tif = TIFFClientOpen(name, mode, (thandle_t)ifd, /* FIXME: WIN64 cast to pointer warning */ tif = TIFFClientOpen(name, mode, thandle_from_int(ifd),
_tiffReadProc, _tiffWriteProc, _tiffReadProc, _tiffWriteProc,
_tiffSeekProc, _tiffCloseProc, _tiffSizeProc, _tiffSeekProc, _tiffCloseProc, _tiffSizeProc,
fSuppressMap ? _tiffDummyMapProc : _tiffMapProc, fSuppressMap ? _tiffDummyMapProc : _tiffMapProc,
@ -282,7 +286,7 @@ TIFFOpen(const char* name, const char* mode)
return ((TIFF *)0); return ((TIFF *)0);
} }
tif = TIFFFdOpen((int)fd, name, mode); /* FIXME: WIN64 cast from pointer to int warning */ tif = TIFFFdOpen(thandle_to_int(fd), name, mode);
if(!tif) if(!tif)
CloseHandle(fd); CloseHandle(fd);
return tif; return tif;
@ -337,7 +341,7 @@ TIFFOpenW(const wchar_t* name, const char* mode)
NULL, NULL); NULL, NULL);
} }
tif = TIFFFdOpen((int)fd, /* FIXME: WIN64 cast from pointer to int warning */ tif = TIFFFdOpen(thandle_to_int(fd),
(mbname != NULL) ? mbname : "<unknown>", mode); (mbname != NULL) ? mbname : "<unknown>", mode);
if(!tif) if(!tif)
CloseHandle(fd); CloseHandle(fd);