diff options
author | Christian Tismer <tismer@stackless.com> | 2021-10-04 17:51:18 +0200 |
---|---|---|
committer | Christian Tismer <tismer@stackless.com> | 2021-10-11 20:31:00 +0200 |
commit | 3e5bfbff99334b8c15ee705079d5a7f0cfa371d5 (patch) | |
tree | f1789bdcd832379eb500dae61bedad5af848e6c1 | |
parent | 87d1bb58877bb956e8fe15e262d173ddaa011b08 (diff) |
shiboken: fix missing cleanup in overridden virtual methods of wrappers
In an error condition, all arguments must be invalidated
in order to get a clean state.
This is currently not done when an error condition exists.
Rewrite the code to generate in a way that all
destructions are done, regardless of function outcome.
That needed some reordering of the code, in order to
move the necessary cleanup right after the Python function
call and before PyErr_Print/return.
[ChangeLog][shiboken6] Overridden virtual methods are now
always correctly finalized, regardless of errors.
Change-Id: If87cc4631f9b5731c1b1b8c7bf204e72d8744cc7
Fixes: PYSIDE-656
Pick-to: 6.2
Reviewed-by: Cristian Maureira-Fredes <cristian.maureira-fredes@qt.io>
-rw-r--r-- | sources/shiboken6/generator/shiboken/cppgenerator.cpp | 45 |
1 files changed, 23 insertions, 22 deletions
diff --git a/sources/shiboken6/generator/shiboken/cppgenerator.cpp b/sources/shiboken6/generator/shiboken/cppgenerator.cpp index a3fdc0f21..a479ba8fa 100644 --- a/sources/shiboken6/generator/shiboken/cppgenerator.cpp +++ b/sources/shiboken6/generator/shiboken/cppgenerator.cpp @@ -1161,15 +1161,27 @@ void CppGenerator::writeVirtualMethodNative(TextStream &s, if (!func->injectedCodeCallsPythonOverride()) { s << "Shiboken::AutoDecRef " << pyRetVar << "(PyObject_Call(" - << PYTHON_OVERRIDE_VAR << ", " << PYTHON_ARGS << ", nullptr));\n" - << "if (" << pyRetVar << ".isNull()) {\n" << indent - << "// An error happened in python code!\n" - << "PyErr_Print();\n" << returnStatement << '\n' << outdent - << "}\n"; + << PYTHON_OVERRIDE_VAR << ", " << PYTHON_ARGS << ", nullptr));\n"; + + for (int argIndex : qAsConst(invalidateArgs)) { + s << "if (invalidateArg" << argIndex << ")\n" << indent + << "Shiboken::Object::invalidate(PyTuple_GET_ITEM(" << PYTHON_ARGS + << ", " << (argIndex - 1) << "));\n" << outdent; + } + + s << "if (" << pyRetVar << ".isNull()) {\n" << indent + << "// An error happened in python code!\n" + << "PyErr_Print();\n" + << returnStatement << "\n" << outdent + << "}\n"; + + if (invalidateReturn) { + s << "bool invalidateArg0 = " << pyRetVar << "->ob_refcnt == 1;\n" + << "if (invalidateArg0)\n" << indent + << "Shiboken::Object::releaseOwnership(" << pyRetVar << ".object());\n" << outdent; + } if (!func->isVoid()) { - if (invalidateReturn) - s << "bool invalidateArg0 = " << pyRetVar << "->ob_refcnt == 1;\n"; if (func->modifiedTypeName() != cPyObjectT()) { @@ -1177,10 +1189,10 @@ void CppGenerator::writeVirtualMethodNative(TextStream &s, if (!func->isTypeModified()) { - s << PYTHON_TO_CPPCONVERSION_STRUCT - << ' ' << PYTHON_TO_CPP_VAR << " = " - << cpythonIsConvertibleFunction(func->type()) - << pyRetVar << ");\n" + s << PYTHON_TO_CPPCONVERSION_STRUCT << ' ' + << PYTHON_TO_CPP_VAR << " =\n" << indent + << cpythonIsConvertibleFunction(func->type()) + << pyRetVar << ");\n" << outdent << "if (!" << PYTHON_TO_CPP_VAR << ") {\n" << indent << "Shiboken::warning(PyExc_RuntimeWarning, 2,\n" << indent << "\"Invalid return value in function %s, expected %s, got %s.\",\n" @@ -1228,17 +1240,6 @@ void CppGenerator::writeVirtualMethodNative(TextStream &s, } } - if (invalidateReturn) { - s << "if (invalidateArg0)\n" << indent - << "Shiboken::Object::releaseOwnership(" << pyRetVar - << ".object());\n" << outdent; - } - for (int argIndex : qAsConst(invalidateArgs)) { - s << "if (invalidateArg" << argIndex << ")\n" << indent - << "Shiboken::Object::invalidate(PyTuple_GET_ITEM(" << PYTHON_ARGS - << ", " << (argIndex - 1) << "));\n" << outdent; - } - for (const FunctionModification &funcMod : func->modifications()) { for (const ArgumentModification &argMod : funcMod.argument_mods()) { if (argMod.index() == 0 |