From 4625592adaeac9b865456d521892c030858a083c Mon Sep 17 00:00:00 2001 From: Tony Cook Date: Thu, 7 Mar 2024 10:43:58 +1100 Subject: [PATCH 1/2] win32.c: suppress -Wcast-function-type warnings This appears to be the only place these warnings are produced even though win32/win32.c contains several other function type casts. None of the non-warning casts use the "void (*)(void)" type that is documented to suppress the warning, and adding such a cast to the lines warning seems less safe to me, cast from a stdcall function pointer to a cdecl function pointer and back. So, just suppress the warning where I saw it. --- win32/win32.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/win32/win32.c b/win32/win32.c index ba694a86d408..f50c34dc8312 100644 --- a/win32/win32.c +++ b/win32/win32.c @@ -3733,8 +3733,10 @@ win32_symlink(const char *oldfile, const char *newfile) { dTHX; size_t oldfile_len = strlen(oldfile); + GCC_DIAG_IGNORE_DECL(-Wcast-function-type); pCreateSymbolicLinkA_t pCreateSymbolicLinkA = (pCreateSymbolicLinkA_t)GetProcAddress(GetModuleHandle("kernel32.dll"), "CreateSymbolicLinkA"); + GCC_DIAG_RESTORE_DECL; DWORD create_flags = 0; /* this flag can be used only on Windows 10 1703 or newer */ @@ -5043,7 +5045,9 @@ Perl_init_os_extras(void) HMODULE module = (HMODULE)((w32_perldll_handle == INVALID_HANDLE_VALUE) ? GetModuleHandle(NULL) : w32_perldll_handle); + GCC_DIAG_IGNORE_DECL(-Wcast-function-type); pfn_init = (void (*)(pTHX))GetProcAddress(module, "init_Win32CORE"); + GCC_DIAG_RESTORE_DECL; aTHXa(PERL_GET_THX); if (pfn_init) pfn_init(aTHX); From eb7f8974f5d39d21db28862604539f8d87237327 Mon Sep 17 00:00:00 2001 From: Tony Cook Date: Thu, 7 Mar 2024 11:25:49 +1100 Subject: [PATCH 2/2] win32.c: don't call wcscpy() with in == out Since both the input and output parameters are restrict qualified, this would be invalid, and it is possibe for PerlDir_mapW() to return its parameter. This warned on gcc: win32.c: In function 'win32_link': win32.c:3712:40: warning: passing argument 1 to 'restrict'-qualified parameter aliases with argument 2 [-Wrestrict] 3712 | ((aTHXa(PERL_GET_THX)), wcscpy(wOldName, PerlDir_mapW(wOldName)), | ^~~~~~~~ --- win32/win32.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/win32/win32.c b/win32/win32.c index f50c34dc8312..7ed2707afbc0 100644 --- a/win32/win32.c +++ b/win32/win32.c @@ -3700,6 +3700,17 @@ win32_pclose(PerlIO *pf) #endif /* USE_RTL_POPEN */ } +/* wcscpy() arguments are restrict qualified, but if they're equal + we don't need to do the copy +*/ +static inline WCHAR * +cond_wcsncpy(WCHAR *out, const WCHAR *in, size_t n) { + assert(wcslen(in) < n); + if (out != in) + wcsncpy(out, in, n); + return out; +} + DllExport int win32_link(const char *oldname, const char *newname) { @@ -3709,7 +3720,8 @@ win32_link(const char *oldname, const char *newname) if (MultiByteToWideChar(CP_ACP, 0, oldname, -1, wOldName, MAX_PATH+1) && MultiByteToWideChar(CP_ACP, 0, newname, -1, wNewName, MAX_PATH+1) && - ((aTHXa(PERL_GET_THX)), wcscpy(wOldName, PerlDir_mapW(wOldName)), + ((aTHXa(PERL_GET_THX)), + cond_wcsncpy(wOldName, PerlDir_mapW(wOldName), C_ARRAY_LENGTH(wOldName)), CreateHardLinkW(PerlDir_mapW(wNewName), wOldName, NULL))) { return 0;