From a936eb40055ade9b94b6c682fe057ce21aacb348 Mon Sep 17 00:00:00 2001 From: noctrex Date: Thu, 4 Jun 2026 20:14:48 +0300 Subject: [PATCH] Add memmem shim for Windows to Kotlin LSP resolver memmem() is a GNU libc extension and is not provided by any Windows C runtime -- not by msvcrt.dll (MINGW64) nor by ucrtbase.dll (UCRT64), and not declared by MinGW-w64 under any feature-test macro. GCC 16.1.0 promoted implicit function declarations from warning to hard error, so the 27 memmem() calls introduced with the Kotlin hybrid LSP resolver break the Windows build at the operator-detection block in `kotlin_eval_expr_type()` (internal/cbm/lsp/kotlin_lsp.c). Add a static inline memmem() at TU scope, guarded by `#if defined(_WIN32)` so it is active only on Windows (where it is needed) and a no-op everywhere else -- including macOS and the BSDs, whose already declares memmem() as a BSD-origin function. The shim covers all 27 call sites in the file -- 26 in kotlin_eval_expr_type (binary and unary operator detection on bounded source-text slices) and one in kt_apply_smart_cast (type-narrowing check for `is`). Verified: build/c/prod_lsp_all.o now compiles cleanly on UCRT64 MSYS2. --- internal/cbm/lsp/kotlin_lsp.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/internal/cbm/lsp/kotlin_lsp.c b/internal/cbm/lsp/kotlin_lsp.c index f2c6b214..414e470d 100644 --- a/internal/cbm/lsp/kotlin_lsp.c +++ b/internal/cbm/lsp/kotlin_lsp.c @@ -42,6 +42,33 @@ #include #include +/* --- BEGIN PORTABILITY SHIM --- + * + * memmem() is a GNU libc extension that is also present in BSD-derived libcs + * (macOS, FreeBSD, OpenBSD, NetBSD, Illumos) and in Cygwin/MSYS2 newlib. It is + * NOT declared by MinGW-w64 (any flavor) or MSVC, and is not exported by any + * Windows C runtime (neither msvcrt.dll nor ucrtbase.dll). See Gnulib's + * portability note for memmem. + * + * Guard with _WIN32 (defined by every Windows-targeting compiler and only by + * them) so the shim is a no-op on every platform whose already + * declares memmem(). This avoids `static declaration follows non-static + * declaration` errors on macOS/BSD where memmem is already in scope. + */ +#if defined(_WIN32) +static inline void *memmem(const void *haystack, size_t hl, + const void *needle, size_t nl) { + if (!nl) return (void*)haystack; + const unsigned char *h = (const unsigned char*)haystack; + const unsigned char *n = (const unsigned char*)needle; + for (size_t i = 0; i + nl <= hl; i++) + if (h[i] == n[0] && memcmp(h + i, n, nl) == 0) + return (void*)(h + i); + return NULL; +} +#endif +/* --- END PORTABILITY SHIM --- */ + #define KT_EVAL_MAX_DEPTH 32 #define KT_IMPORT_INITIAL_CAP 16