From 85451c40f23a7298b5f35744e8588307e124a751 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 12 Oct 2020 13:50:24 +0200 Subject: shiboken2: Use an AbstractMetaType for "void" Previously, nullptr for an AbstractMetaType meant "void", particularly for function return types. The problem with this is that it causes unexpected crashes when dealing with template types like QFuture due to one of the instantiations of the AbstractMetaType being nullptr. Use an AbstractMetaType based on the existing "void" type entry for this. Task-number: PYSIDE-1202 Change-Id: Ib06035cc7903480fd509f7e927d9114c55d51b62 Reviewed-by: Cristian Maureira-Fredes Reviewed-by: Qt CI Bot --- .../shiboken2/generator/shiboken2/cppgenerator.cpp | 31 +++++++++++----------- .../generator/shiboken2/headergenerator.cpp | 9 ++++--- .../shiboken2/generator/shiboken2/overloaddata.cpp | 22 +++++---------- .../generator/shiboken2/shibokengenerator.cpp | 2 +- 4 files changed, 30 insertions(+), 34 deletions(-) (limited to 'sources/shiboken2/generator/shiboken2') diff --git a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp index c1f1b21db..ea970331e 100644 --- a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp +++ b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp @@ -247,7 +247,7 @@ const AbstractMetaFunction *CppGenerator::boolCast(const AbstractMetaClass *meta return nullptr; // TODO: This could be configurable someday const AbstractMetaFunction *func = metaClass->findFunction(QLatin1String("isNull")); - if (!func || !func->type() || !func->type()->typeEntry()->isPrimitive() || !func->isPublic()) + if (!func || func->isVoid() || !func->type()->typeEntry()->isPrimitive() || !func->isPublic()) return nullptr; auto pte = static_cast(func->type()->typeEntry()); while (pte->referencedTypeEntry()) @@ -892,9 +892,9 @@ QString CppGenerator::virtualMethodReturn(QTextStream &s, const AbstractMetaFunction *func, const FunctionModificationList &functionModifications) { - const AbstractMetaType *returnType = func->type(); - if (!returnType) + if (func->isVoid()) return QLatin1String("return;"); + const AbstractMetaType *returnType = func->type(); for (const FunctionModification &mod : functionModifications) { for (const ArgumentModification &argMod : mod.argument_mods) { if (argMod.index == 0 && !argMod.replacedDefaultExpression.isEmpty()) { @@ -951,7 +951,7 @@ void CppGenerator::writeVirtualMethodNative(QTextStream &s, ((func->name() == QLatin1String("metaObject")) || (func->name() == QLatin1String("qt_metacall")))) return; - const TypeEntry *retType = func->type() ? func->type()->typeEntry() : nullptr; + const TypeEntry *retType = func->type()->typeEntry(); const QString funcName = func->isOperatorOverload() ? pythonOperatorFunctionName(func) : func->name(); QString prefix = wrapperName(func->ownerClass()) + QLatin1String("::"); @@ -994,7 +994,7 @@ void CppGenerator::writeVirtualMethodNative(QTextStream &s, << R"(] << '\n';)" << '\n'; } // PYSIDE-803: Build a boolean cache for unused overrides. - const bool multi_line = retType == nullptr || !snips.isEmpty() || func->isAbstract(); + const bool multi_line = func->isVoid() || !snips.isEmpty() || func->isAbstract(); s << INDENT << "if (m_PyMethodCache[" << cacheIndex << "])" << (multi_line ? " {\n" : "\n"); { Indentation indentation(INDENT); @@ -1126,7 +1126,7 @@ void CppGenerator::writeVirtualMethodNative(QTextStream &s, } s << INDENT << "}\n"; - if (retType) { + if (!func->isVoid()) { if (invalidateReturn) s << INDENT << "bool invalidateArg0 = " << PYTHON_RETURN_VAR << "->ob_refcnt == 1;\n"; @@ -1211,7 +1211,7 @@ void CppGenerator::writeVirtualMethodNative(QTextStream &s, writeCodeSnips(s, snips, TypeSystem::CodeSnipPositionEnd, TypeSystem::NativeCode, func, lastArg); } - if (retType) { + if (!func->isVoid()) { s << INDENT << "return "; if (avoidProtectedHack() && retType->isEnum()) { const AbstractMetaEnum *metaEnum = findAbstractMetaEnum(retType); @@ -2329,6 +2329,7 @@ void CppGenerator::writeTypeCheck(QTextStream &s, const AbstractMetaType *argTyp static void checkTypeViability(const AbstractMetaFunction *func, const AbstractMetaType *type, int argIdx) { if (!type + || type->isVoid() || !type->typeEntry()->isPrimitive() || type->indirections() == 0 || (type->indirections() == 1 && type->typeUsagePattern() == AbstractMetaType::NativePointerAsArrayPattern) @@ -2596,7 +2597,7 @@ void CppGenerator::writeConversionRule(QTextStream &s, const AbstractMetaFunctio void CppGenerator::writeNoneReturn(QTextStream &s, const AbstractMetaFunction *func, bool thereIsReturnValue) { - if (thereIsReturnValue && (!func->type() || func->argumentRemoved(0)) && !injectedCodeHasReturnValueAttribution(func)) { + if (thereIsReturnValue && (func->isVoid() || func->argumentRemoved(0)) && !injectedCodeHasReturnValueAttribution(func)) { s << INDENT << PYTHON_RETURN_VAR << " = Py_None;\n"; s << INDENT << "Py_INCREF(Py_None);\n"; } @@ -3237,7 +3238,7 @@ QString CppGenerator::argumentNameFromIndex(const AbstractMetaFunction *func, in } else if (argIndex == 0) { AbstractMetaType *funcType = func->type(); AbstractMetaType *returnType = getTypeWithoutContainer(funcType); - if (returnType) { + if (!returnType->isVoid()) { pyArgName = QLatin1String(PYTHON_RETURN_VAR); *wrappedClass = AbstractMetaClass::findClass(classes(), returnType->typeEntry()); } else { @@ -3560,7 +3561,7 @@ void CppGenerator::writeMethodCall(QTextStream &s, const AbstractMetaFunction *f if (isCtor) { s << (useVAddr.isEmpty() ? QString::fromLatin1("cptr = %1;").arg(methodCall) : useVAddr) << Qt::endl; - } else if (func->type() && !func->isInplaceOperator()) { + } else if (!func->isVoid() && !func->isInplaceOperator()) { bool writeReturnType = true; if (avoidProtectedHack()) { const AbstractMetaEnum *metaEnum = findAbstractMetaEnum(func->type()); @@ -3598,7 +3599,7 @@ void CppGenerator::writeMethodCall(QTextStream &s, const AbstractMetaFunction *f // Convert result if (!func->conversionRule(TypeSystem::TargetLangCode, 0).isEmpty()) { writeConversionRule(s, func, TypeSystem::TargetLangCode, QLatin1String(PYTHON_RETURN_VAR)); - } else if (!isCtor && !func->isInplaceOperator() && func->type() + } else if (!isCtor && !func->isInplaceOperator() && !func->isVoid() && !injectedCodeHasReturnValueAttribution(func, TypeSystem::TargetLangCode)) { s << INDENT << PYTHON_RETURN_VAR << " = "; if (isObjectTypeUsedAsValueType(func->type())) { @@ -4696,7 +4697,7 @@ void CppGenerator::writeRichCompareFunction(QTextStream &s, const GeneratorConte } if (generateOperatorCode) { s << INDENT; - if (func->type()) + if (!func->isVoid()) s << func->type()->cppSignature() << " " << CPP_RETURN_VAR << " = "; // expression if (func->isPointerOperator()) @@ -4706,7 +4707,7 @@ void CppGenerator::writeRichCompareFunction(QTextStream &s, const GeneratorConte s << '*'; s << CPP_ARG0 << ");\n"; s << INDENT << PYTHON_RETURN_VAR << " = "; - if (func->type()) + if (!func->isVoid()) writeToPythonConversion(s, func->type(), metaClass, QLatin1String(CPP_RETURN_VAR)); else s << "Py_None;\n" << INDENT << "Py_INCREF(Py_None)"; @@ -4830,7 +4831,7 @@ void CppGenerator::writeSignatureInfo(QTextStream &s, const AbstractMetaFunction if (multiple) s << idx-- << ':'; s << funcName << '(' << args.join(QLatin1Char(',')) << ')'; - if (f->type()) + if (!f->isVoid()) s << "->" << f->type()->pythonSignature(); s << Qt::endl; } @@ -6214,7 +6215,7 @@ void CppGenerator::writeReturnValueHeuristics(QTextStream &s, const AbstractMeta AbstractMetaType *type = func->type(); if (!useReturnValueHeuristic() || !func->ownerClass() - || !type + || type->isVoid() || func->isStatic() || func->isConstructor() || !func->typeReplaced(0).isEmpty()) { diff --git a/sources/shiboken2/generator/shiboken2/headergenerator.cpp b/sources/shiboken2/generator/shiboken2/headergenerator.cpp index 36ccefb58..107e28a4a 100644 --- a/sources/shiboken2/generator/shiboken2/headergenerator.cpp +++ b/sources/shiboken2/generator/shiboken2/headergenerator.cpp @@ -239,7 +239,8 @@ void HeaderGenerator::writeFunction(QTextStream &s, const AbstractMetaFunction * s << INDENT << "inline " << (func->isStatic() ? "static " : ""); s << functionSignature(func, QString(), QLatin1String("_protected"), Generator::EnumAsInts|Generator::OriginalTypeDescription) << " { "; - s << (func->type() ? "return " : ""); + if (!func->isVoid()) + s << "return "; if (!func->isAbstract()) s << func->ownerClass()->qualifiedCppName() << "::"; s << func->originalName() << '('; @@ -637,8 +638,10 @@ void HeaderGenerator::writeInheritedOverloads(QTextStream &s) { for (const AbstractMetaFunction *func : qAsConst(m_inheritedOverloads)) { s << INDENT << "inline "; - s << functionSignature(func, QString(), QString(), Generator::EnumAsInts|Generator::OriginalTypeDescription) << " { "; - s << (func->type() ? "return " : ""); + s << functionSignature(func, QString(), QString(), Generator::EnumAsInts|Generator::OriginalTypeDescription) + << " { "; + if (!func->isVoid()) + s << "return "; s << func->ownerClass()->qualifiedCppName() << "::" << func->originalName() << '('; QStringList args; const AbstractMetaArgumentList &arguments = func->arguments(); diff --git a/sources/shiboken2/generator/shiboken2/overloaddata.cpp b/sources/shiboken2/generator/shiboken2/overloaddata.cpp index 36725d3fc..9f79060da 100644 --- a/sources/shiboken2/generator/shiboken2/overloaddata.cpp +++ b/sources/shiboken2/generator/shiboken2/overloaddata.cpp @@ -579,10 +579,8 @@ QStringList OverloadData::returnTypes() const for (const AbstractMetaFunction *func : m_overloads) { if (!func->typeReplaced(0).isEmpty()) retTypes << func->typeReplaced(0); - else if (func->type() && !func->argumentRemoved(0)) + else if (!func->argumentRemoved(0)) retTypes << func->type()->cppSignature(); - else - retTypes << QLatin1String("void"); } return retTypes.values(); } @@ -878,12 +876,9 @@ QString OverloadData::dumpGraph() const // Shows all function signatures s << "legend [fontsize=9 fontname=freemono shape=rect label=\""; for (const AbstractMetaFunction *func : m_overloads) { - s << "f" << functionNumber(func) << " : "; - if (func->type()) - s << toHtml(func->type()->cppSignature()); - else - s << "void"; - s << ' ' << toHtml(func->minimalSignature()) << "\\l"; + s << "f" << functionNumber(func) << " : " + << toHtml(func->type()->cppSignature()) + << ' ' << toHtml(func->minimalSignature()) << "\\l"; } s << "\"];\n"; @@ -903,12 +898,9 @@ QString OverloadData::dumpGraph() const s << ""; // Function return type - s << "original type"; - if (rfunc->type()) - s << toHtml(rfunc->type()->cppSignature()); - else - s << "void"; - s << ""; + s << "original type" + << toHtml(rfunc->type()->cppSignature()) + << ""; // Shows type changes for all function signatures for (const AbstractMetaFunction *func : m_overloads) { diff --git a/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp b/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp index 8cea5aeda..3cd6b8e53 100644 --- a/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp +++ b/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp @@ -1862,7 +1862,7 @@ void ShibokenGenerator::writeCodeSnips(QTextStream &s, if (func->isConstructor()) { code.replace(QLatin1String("%0."), QLatin1String("cptr->")); code.replace(QLatin1String("%0"), QLatin1String("cptr")); - } else if (func->type()) { + } else if (!func->isVoid()) { QString returnValueOp = isPointerToWrapperType(func->type()) ? QLatin1String("%1->") : QLatin1String("%1."); if (ShibokenGenerator::isWrapperType(func->type())) -- cgit v1.2.3