From 1070d4902c825d68809f4dfb2c8f2e6fa9a87da4 Mon Sep 17 00:00:00 2001 From: Matthew Johnson Date: Wed, 17 Jun 2026 11:31:23 +0100 Subject: [PATCH] Fix MSVC C4864 warning and testlib message_impl link error corealloc.h: `small_refill` and `small_alloc` are member templates invoked through an `Allocator*` of dependent type. MSVC's conformance mode requires the `template` disambiguator, otherwise it emits C4864 ("expected 'template' keyword before dependent template name"). Add the keyword to the three affected call sites. snmalloc_testlib.cc: `message_impl` is declared non-inline in defines.h but defined inline in pal.h. On MSVC its COMDAT was never emitted into the test library (nothing referenced it), so testlib-only tests that see only the declaration (redblack, seqset) failed to link with LNK2019. Force-emit the COMDAT via a non-elidable odr-use, keeping the symbol inline everywhere so it stays ODR-safe with the copies other tests compile from snmalloc.h. Signed-off-by: Matthew Johnson --- src/snmalloc/mem/corealloc.h | 7 ++++--- src/test/snmalloc_testlib.cc | 6 ++++++ 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/snmalloc/mem/corealloc.h b/src/snmalloc/mem/corealloc.h index 127abc76a..b9d63c957 100644 --- a/src/snmalloc/mem/corealloc.h +++ b/src/snmalloc/mem/corealloc.h @@ -656,7 +656,8 @@ namespace snmalloc smallsizeclass_t sizeclass, freelist::Iter<>* fl, size_t size) SNMALLOC_FAST_PATH_LAMBDA { - return alloc->small_refill(sizeclass, *fl, size); + return alloc->template small_refill( + sizeclass, *fl, size); }, this, sizeclass, @@ -693,7 +694,7 @@ namespace snmalloc // Deal with alloc zero of with a small object here. // Alternative semantics giving nullptr is also allowed by the // standard. - return self->small_alloc(1); + return self->template small_alloc(1); } return self->template handle_message_queue( @@ -891,7 +892,7 @@ namespace snmalloc return ticker.check_tick(r); }, [](Allocator* a, size_t size) SNMALLOC_FAST_PATH_LAMBDA { - return a->small_alloc(size); + return a->template small_alloc(size); }, size); } diff --git a/src/test/snmalloc_testlib.cc b/src/test/snmalloc_testlib.cc index c99f0e569..f57334e3c 100644 --- a/src/test/snmalloc_testlib.cc +++ b/src/test/snmalloc_testlib.cc @@ -174,6 +174,12 @@ namespace snmalloc { Aal::pause(); } + + // Force-emit message_impl's COMDAT here so testlib-only tests (redblack, + // seqset) that see only its non-inline declaration can link. volatile keeps + // the odr-use non-elidable. + [[maybe_unused]] static void (*volatile force_message_impl)( + const char* const) = &message_impl; } // namespace snmalloc // -- override/malloc.cc symbols with testlib_ prefix -----------------------