diff options
author | Christian Tismer <tismer@stackless.com> | 2021-10-04 17:51:18 +0200 |
---|---|---|
committer | Christian Tismer <tismer@stackless.com> | 2021-10-12 11:03:16 +0200 |
commit | 4788127dca1f90c0a83cbf3016da708404eaad69 (patch) | |
tree | 00026b5a74799160dfa4b9344ec7419fceea083d | |
parent | a3f40e25ebe81804bf1e19d5ee64108d4304c9ab (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
Reviewed-by: Cristian Maureira-Fredes <cristian.maureira-fredes@qt.io>
(cherry picked from commit 3e5bfbff99334b8c15ee705079d5a7f0cfa371d5)
-rw-r--r-- | sources/shiboken6/generator/shiboken/cppgenerator.cpp | 47 |
1 files changed, 25 insertions, 22 deletions
diff --git a/sources/shiboken6/generator/shiboken/cppgenerator.cpp b/sources/shiboken6/generator/shiboken/cppgenerator.cpp index 44304375a..0a237ed8d 100644 --- a/sources/shiboken6/generator/shiboken/cppgenerator.cpp +++ b/sources/shiboken6/generator/shiboken/cppgenerator.cpp @@ -1166,24 +1166,38 @@ 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->typeReplaced(0) != cPyObjectT()) { s << "// Check return type\n"; + if (func->typeReplaced(0).isEmpty()) { - 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" @@ -1227,17 +1241,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 |