From 230132744843045a566f3c76ede5edb1078211d3 Mon Sep 17 00:00:00 2001 From: Aaron Jomy Date: Fri, 28 Aug 2026 17:55:46 +0200 Subject: [PATCH] [cpyrt] Restore support for non-const void*& arguments VoidPtrRefConverter was registered only for "const void*&", so a mutable void*& fell under the general ban on non-const pointer references. Passing an object through an opaque void*& handle is supported by design; the exact-match factory lookup runs before the T*& rejection, which stays in effect for typed pointer references. --- src/cpyrt/Converters.cxx | 6 ++++-- test/test_conversions.py | 16 ++++++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/cpyrt/Converters.cxx b/src/cpyrt/Converters.cxx index c647696..4771e80 100644 --- a/src/cpyrt/Converters.cxx +++ b/src/cpyrt/Converters.cxx @@ -4271,11 +4271,13 @@ static struct InitConvFactories_t { gf["const std::wstring &"] = gf["std::wstring"]; gf["const " WSTRING1 " &"] = gf["std::wstring"]; gf["const " WSTRING2 " &"] = gf["std::wstring"]; - // VoidPtrRefConverter should only be used for const references to pointers - gf["const void*&"] = (cf_t) + [](cdims_t) { + // void*& is exempt from the T*& ban: the callee updates the proxy's + // held pointer through the opaque handle + gf["void*&"] = (cf_t) + [](cdims_t) { static VoidPtrRefConverter c{}; return &c; }; + gf["const void*&"] = gf["void*&"]; gf["void**"] = (cf_t) + [](cdims_t d) { return new VoidPtrPtrConverter{d}; }; gf["void ptr"] = gf["void**"]; diff --git a/test/test_conversions.py b/test/test_conversions.py index 8741534..65b1600 100644 --- a/test/test_conversions.py +++ b/test/test_conversions.py @@ -138,3 +138,19 @@ def test05_bool_conversions(self): assert ns.Test1() assert ns.Test2(True) assert not ns.Test2(False) + + def test07_mutable_voidp_reference(self): + """An object can be passed through a non-const void*& argument""" + + import cppjit + + cppjit.cppdef("""\ + namespace VoidPtrRef { + struct Obj { int v = 5; }; + bool is_same(void*& p, Obj* o) { return p == (void*)o; } + }""") + + ns = cppjit.gbl.VoidPtrRef + o = ns.Obj() + + assert ns.is_same(o, o)