From f7c4677cb26808a6c75a4f7215d4cc50248e6e14 Mon Sep 17 00:00:00 2001 From: Ilya Sinitsyn Date: Wed, 14 Oct 2020 20:36:09 +0700 Subject: [PATCH] Fix list contents memory leak in wxAny unit test Also document the need for using WX_CLEAR_LIST() when converting a list-valued wxVariant to wxAny. Note that we intentionally don't fix the problem by clearing the list automatically, even if it could be done, because this would silently break the existing code which does already clear the list -- and now would attempt to clear it twice, with fatal consequences. Instead document the existing behaviour and explain how to avoid memory leaks. --- interface/wx/any.h | 19 +++++++++++++++++++ tests/any/anytest.cpp | 2 ++ 2 files changed, 21 insertions(+) diff --git a/interface/wx/any.h b/interface/wx/any.h index af8cc422e1..d9fb09bc5e 100644 --- a/interface/wx/any.h +++ b/interface/wx/any.h @@ -84,6 +84,25 @@ public: cannot be converted to a specific data type, wxAny will then hold and manage reference to wxVariantData* similar to how wxVariant does. + + Note that objects constructed from list-valued variants + require the list to be explicitly cleared using `WX_CLEAR_LIST` + to avoid leaking memory. This unfortunate behaviour will not + be changed to prevent breaking the existing code relying on it. + + @code + wxVariant vList; + vList.NullList(); + vList.Append(15); + vList.Append("abc"); + + // Create wxAny from the list variant. + wxAny any = wxAny(vList); + + // Clear the list to avoid the memory leak. + wxAnyList anyList = any.As(); + WX_CLEAR_LIST(wxAnyList, anyList); + @endcode */ wxAny(const wxVariant& variant); diff --git a/tests/any/anytest.cpp b/tests/any/anytest.cpp index 83b2c5e9bd..08546a2949 100644 --- a/tests/any/anytest.cpp +++ b/tests/any/anytest.cpp @@ -652,6 +652,8 @@ void wxAnyTestCase::wxVariantConversions() CPPUNIT_ASSERT(variant.GetCount() == 2); CPPUNIT_ASSERT(variant[0].GetLong() == 15); CPPUNIT_ASSERT(variant[1].GetString() == "abc"); + // Avoid the memory leak. + WX_CLEAR_LIST(wxAnyList, anyList); any = wxAny(vCustomType); CPPUNIT_ASSERT(wxANY_CHECK_TYPE(any, wxVariantData*));