From cad76c5b089d44dd0a0e17cc67de9da93c5655af Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 6 Oct 2019 01:47:06 +0200 Subject: 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 --- libtiff/tif_win32.c | 50 +++++++++++++++++++++++++++----------------------- 1 file changed, 27 insertions(+), 23 deletions(-) diff --git a/libtiff/tif_win32.c b/libtiff/tif_win32.c index 088880e7..bf5fbfb3 100644 --- a/libtiff/tif_win32.c +++ b/libtiff/tif_win32.c @@ -27,33 +27,37 @@ * Scott Wagner (wagner@itek.com), Itek Graphix, Rochester, NY USA */ -/* - CreateFileA/CreateFileW return type 'HANDLE'. - - thandle_t is declared like - - DECLARE_HANDLE(thandle_t); +#include "tiffiop.h" - in tiffio.h. +#include - Windows (from winnt.h) DECLARE_HANDLE logic looks like +/* + 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. - #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 + 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 - See http://bugzilla.maptools.org/show_bug.cgi?id=1941 for problems in WIN64 - builds resulting from this. Unfortunately, the proposed patch was lost. + 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. */ - -#include "tiffiop.h" -#include +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 _tiffReadProc(thandle_t fd, void* buf, tmsize_t size) @@ -237,7 +241,7 @@ TIFFFdOpen(int ifd, const char* name, const char* mode) break; } } - tif = TIFFClientOpen(name, mode, (thandle_t)ifd, /* FIXME: WIN64 cast to pointer warning */ + tif = TIFFClientOpen(name, mode, thandle_from_int(ifd), _tiffReadProc, _tiffWriteProc, _tiffSeekProc, _tiffCloseProc, _tiffSizeProc, fSuppressMap ? _tiffDummyMapProc : _tiffMapProc, @@ -282,7 +286,7 @@ TIFFOpen(const char* name, const char* mode) 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) CloseHandle(fd); return tif; @@ -337,7 +341,7 @@ TIFFOpenW(const wchar_t* name, const char* mode) NULL, NULL); } - tif = TIFFFdOpen((int)fd, /* FIXME: WIN64 cast from pointer to int warning */ + tif = TIFFFdOpen(thandle_to_int(fd), (mbname != NULL) ? mbname : "", mode); if(!tif) CloseHandle(fd); -- cgit v1.2.1