aboutsummaryrefslogtreecommitdiffstats
path: root/sources/shiboken6/generator
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2024-04-23 14:17:15 +0200
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2024-04-24 10:20:16 +0200
commitf34dcb84adf20e9f3428660636aa8d377d14fc3b (patch)
treee44f337979c036d2eb41e7e04b358a6b37bc8a56 /sources/shiboken6/generator
parentc0674262fd7e859a8002e6e850b6ec0a4162b456 (diff)
shiboken6: Fix leaking tuples in introduceWrapperType()
When calling introduceWrapperType(), the generated code creates and leaks a tuple of base types if there are base classes. When there are no base classes, a tuple (containing SbkObjectType) is created and leaked within introduceWrapperType(). To fix this, generate the complete tuple including SbkObjectType in the generated code and remove the base type parameter to introduceWrapperType(). Pick-to: 6.7 Task-number: PYSIDE-1617 Change-Id: Ib3bec8e6b94bea14a46df826667373d3f859dfd5 Reviewed-by: Cristian Maureira-Fredes <cristian.maureira-fredes@qt.io>
Diffstat (limited to 'sources/shiboken6/generator')
-rw-r--r--sources/shiboken6/generator/shiboken/cppgenerator.cpp84
-rw-r--r--sources/shiboken6/generator/shiboken/cppgenerator.h1
2 files changed, 48 insertions, 37 deletions
diff --git a/sources/shiboken6/generator/shiboken/cppgenerator.cpp b/sources/shiboken6/generator/shiboken/cppgenerator.cpp
index bfde1ff53..037209dfb 100644
--- a/sources/shiboken6/generator/shiboken/cppgenerator.cpp
+++ b/sources/shiboken6/generator/shiboken/cppgenerator.cpp
@@ -60,6 +60,8 @@ static const char shibokenErrorsOccurred[] = "Shiboken::Errors::occurred() != nu
static constexpr auto virtualMethodStaticReturnVar = "result"_L1;
+static constexpr auto sbkObjectTypeF = "SbkObject_TypeF()"_L1;
+
static QString mangleName(QString name)
{
if (name == u"None" || name == u"False" || name == u"True" || name == u"from")
@@ -4356,7 +4358,6 @@ void CppGenerator::writeClassDefinition(TextStream &s,
QString tp_hash;
QString tp_call;
const QString className = chopType(cpythonTypeName(metaClass));
- QString baseClassName;
AbstractMetaFunctionCList ctors;
const auto &allCtors = metaClass->queryFunctions(FunctionQueryOption::AnyConstructor);
for (const auto &f : allCtors) {
@@ -4366,9 +4367,6 @@ void CppGenerator::writeClassDefinition(TextStream &s,
}
}
- if (!metaClass->baseClass())
- baseClassName = u"SbkObject_TypeF()"_s;
-
bool onlyPrivCtor = !metaClass->hasNonPrivateConstructor();
const bool isQApp = usePySideExtensions()
@@ -4702,7 +4700,7 @@ void CppGenerator::writeTpTraverseFunction(TextStream &s, const AbstractMetaClas
s << "static int " << baseName
<< "_traverse(PyObject *self, visitproc visit, void *arg)\n{\n" << indent
<< "auto traverseProc = "
- << pyTypeGetSlot("traverseproc", "SbkObject_TypeF()", "Py_tp_traverse") << ";\n"
+ << pyTypeGetSlot("traverseproc", sbkObjectTypeF, "Py_tp_traverse") << ";\n"
<< "return traverseProc(self, visit, arg);\n"
<< outdent << "}\n";
}
@@ -4712,7 +4710,7 @@ void CppGenerator::writeTpClearFunction(TextStream &s, const AbstractMetaClassCP
QString baseName = cpythonBaseName(metaClass);
s << "static int " << baseName << "_clear(PyObject *self)\n{\n" << indent
<< "auto clearProc = "
- << pyTypeGetSlot("inquiry", "SbkObject_TypeF()", "Py_tp_clear") << ";\n"
+ << pyTypeGetSlot("inquiry", sbkObjectTypeF, "Py_tp_clear") << ";\n"
<< "return clearProc(self);\n"
<< outdent << "}\n";
}
@@ -5441,6 +5439,40 @@ QString CppGenerator::destructorClassName(const AbstractMetaClassCPtr &metaClass
return metaClass->qualifiedCppName();
}
+// Return the base type entries for introduceWrapperType()
+static ComplexTypeEntryCList pyBaseTypeEntries(const AbstractMetaClassCPtr &metaClass)
+{
+ ComplexTypeEntryCList result;
+ if (metaClass->isNamespace()) {
+ if (auto extended = metaClass->extendedNamespace())
+ result.append(extended->typeEntry());
+ return result;
+ }
+
+ const auto &baseClasses = metaClass->typeSystemBaseClasses();
+ for (auto base : baseClasses) {
+ for (; base != nullptr; base = base->baseClass()) { // Find a type that is not disabled.
+ const auto ct = base->typeEntry()->codeGeneration();
+ if (ct == TypeEntry::GenerateCode || ct == TypeEntry::GenerateForSubclass)
+ break;
+ }
+ result.append(base->typeEntry());
+ }
+ return result;
+}
+
+// Return the base type strings for introduceWrapperType()
+QStringList CppGenerator::pyBaseTypes(const AbstractMetaClassCPtr &metaClass)
+{
+ const auto &baseEntries = pyBaseTypeEntries(metaClass);
+ QStringList result;
+ for (const auto &baseEntry : baseEntries)
+ result.append("reinterpret_cast<PyObject *>("_L1 + cpythonTypeNameExt(baseEntry) + u')');
+ if (result.isEmpty()) // no base classes -> SbkObjectType.
+ result.append(sbkObjectTypeF);
+ return result;
+}
+
void CppGenerator::writeClassRegister(TextStream &s,
const AbstractMetaClassCPtr &metaClass,
const GeneratorContext &classContext,
@@ -5467,18 +5499,15 @@ void CppGenerator::writeClassRegister(TextStream &s,
// Multiple inheritance
QString pyTypeBasesVariable = chopType(pyTypeName) + u"_Type_bases"_s;
- const auto &baseClasses = metaClass->typeSystemBaseClasses();
- if (metaClass->baseClassNames().size() > 1) {
- s << "PyObject *" << pyTypeBasesVariable
- << " = PyTuple_Pack(" << baseClasses.size() << ',' << '\n' << indent;
- for (qsizetype i = 0, size = baseClasses.size(); i < size; ++i) {
- if (i)
- s << ",\n";
- s << "reinterpret_cast<PyObject *>("
- << cpythonTypeNameExt(baseClasses.at(i)->typeEntry()) << ')';
- }
- s << ");\n\n" << outdent;
+ const QStringList pyBases = pyBaseTypes(metaClass);
+ s << "Shiboken::AutoDecRef " << pyTypeBasesVariable << "(PyTuple_Pack("
+ << pyBases.size() << ",\n" << indent;
+ for (qsizetype i = 0, size = pyBases.size(); i < size; ++i) {
+ if (i)
+ s << ",\n";
+ s << pyBases.at(i);
}
+ s << "));\n\n" << outdent;
// Create type and insert it in the module or enclosing class.
const QString typePtr = u"_"_s + chopType(pyTypeName)
@@ -5513,27 +5542,8 @@ void CppGenerator::writeClassRegister(TextStream &s,
s << "&Shiboken::callCppDestructor< " << globalScopePrefix(classContext)
<< dtorClassName << " >,\n";
- // 6:baseType: Find a type that is not disabled.
- auto base = metaClass->isNamespace()
- ? metaClass->extendedNamespace() : metaClass->baseClass();
- if (!metaClass->isNamespace()) {
- for (; base != nullptr; base = base->baseClass()) {
- const auto ct = base->typeEntry()->codeGeneration();
- if (ct == TypeEntry::GenerateCode || ct == TypeEntry::GenerateForSubclass)
- break;
- }
- }
- if (base) {
- s << cpythonTypeNameExt(base->typeEntry()) << ",\n";
- } else {
- s << "nullptr,\n";
- }
-
// 7:baseTypes
- if (metaClass->baseClassNames().size() > 1)
- s << pyTypeBasesVariable << ',' << '\n';
- else
- s << "nullptr,\n";
+ s << pyTypeBasesVariable << ".object()," << '\n';
// 8:wrapperflags
QByteArrayList wrapperFlags;
diff --git a/sources/shiboken6/generator/shiboken/cppgenerator.h b/sources/shiboken6/generator/shiboken/cppgenerator.h
index 1b4ebf803..6c20d9d78 100644
--- a/sources/shiboken6/generator/shiboken/cppgenerator.h
+++ b/sources/shiboken6/generator/shiboken/cppgenerator.h
@@ -400,6 +400,7 @@ private:
const AbstractMetaClassCPtr &metaClass,
const GeneratorContext &classContext,
const QString &signatures) const;
+ static QStringList pyBaseTypes(const AbstractMetaClassCPtr &metaClass);
static QString destructorClassName(const AbstractMetaClassCPtr &metaClass,
const GeneratorContext &classContext);
static void writeStaticFieldInitialization(TextStream &s,