From 6951eb0dae90ea8d50f88ff528228eb0cb755dba Mon Sep 17 00:00:00 2001 From: Aaron Jomy Date: Sat, 29 Aug 2026 12:59:26 +0200 Subject: [PATCH] [cpyrt] Reuse InitializerListConverter element converters SetArg() created an element converter per call and appended it to fConverters, but Clear() frees only fBuffer, so the vector grew without bound across repeated std::initializer_list conversions. Create each element converter once, on first use of its index, and reuse it. --- src/cpyrt/Converters.cxx | 8 ++++---- test/test_leakcheck.py | 18 ++++++++++++++++++ 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/cpyrt/Converters.cxx b/src/cpyrt/Converters.cxx index 31ab848..c647696 100644 --- a/src/cpyrt/Converters.cxx +++ b/src/cpyrt/Converters.cxx @@ -3186,7 +3186,9 @@ bool cpyrt::InitializerListConverter::SetArg(PyObject* pyobject, PyObject* item = PySequence_GetItem(pyobject, i); bool convert_ok = false; if (item) { - Converter* converter = CreateConverter(fValueTypeName); + if (i >= fConverters.size()) + fConverters.emplace_back(CreateConverter(fValueTypeName)); + Converter* converter = fConverters[i]; if (!converter) { if (CPPInstance_Check(item)) { // by convention, use byte copy @@ -3208,10 +3210,8 @@ bool cpyrt::InitializerListConverter::SetArg(PyObject* pyobject, .c_str()); entries += 1; } - if (memloc) { + if (memloc) convert_ok = converter->ToMemory(item, memloc); - } - fConverters.emplace_back(converter); } Py_DECREF(item); diff --git a/test/test_leakcheck.py b/test/test_leakcheck.py index ea21184..6813f29 100644 --- a/test/test_leakcheck.py +++ b/test/test_leakcheck.py @@ -282,3 +282,21 @@ def wrapped_list_by_value(): ns.leak_list = wrapped_list_by_value self.check_func(ns, "leak_list") + + def test09_initializer_list_argument(self): + """Leak check of passing a list as an std::initializer_list argument""" + + import cppjit + + cppjit.cppdef("""\ + namespace LeakCheck { + int sum_il(std::initializer_list l) { + int s = 0; + for (auto i : l) s += i; + return s; + } + }""") + + ns = cppjit.gbl.LeakCheck + + self.check_func(ns, "sum_il", [1, 2, 3])