aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Tismer <tismer@stackless.com>2021-10-04 17:51:18 +0200
committerChristian Tismer <tismer@stackless.com>2021-10-11 20:31:00 +0200
commit3e5bfbff99334b8c15ee705079d5a7f0cfa371d5 (patch)
treef1789bdcd832379eb500dae61bedad5af848e6c1
parent87d1bb58877bb956e8fe15e262d173ddaa011b08 (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.cpp45
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