diff options
author | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2022-04-04 11:46:51 +0200 |
---|---|---|
committer | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2022-04-04 15:14:57 +0200 |
commit | f21f5c469813ab8fb13b2607624dd9a33c345acb (patch) | |
tree | 4e337303e7a5a028d5c6ea309f523921e4d78cf0 | |
parent | 545e90b4c434c7380a61113ec377ba56007eb0dc (diff) |
shiboken6: Add a check for null to the smart pointer access
If a null check method exists, generate a check into getattro() with
a better error message than the attribute access error.
This will be vital for std::optional to suppress a C++ exception
being thrown.
Pick-to: 6.2
Task-number: PYSIDE-454
Change-Id: I6d8e16e31c094aa695e150990c471007bcd34eb9
Reviewed-by: Christian Tismer <tismer@stackless.com>
-rw-r--r-- | sources/shiboken6/generator/shiboken/cppgenerator.cpp | 18 | ||||
-rw-r--r-- | sources/shiboken6/generator/shiboken/cppgenerator.h | 7 |
2 files changed, 21 insertions, 4 deletions
diff --git a/sources/shiboken6/generator/shiboken/cppgenerator.cpp b/sources/shiboken6/generator/shiboken/cppgenerator.cpp index 1734237ba..64c748ca5 100644 --- a/sources/shiboken6/generator/shiboken/cppgenerator.cpp +++ b/sources/shiboken6/generator/shiboken/cppgenerator.cpp @@ -872,7 +872,7 @@ void CppGenerator::generateSmartPointerClass(TextStream &s, const GeneratorConte // Write tp_s/getattro function const auto boolCastOpt = boolCast(metaClass); - writeSmartPointerGetattroFunction(s, classContext); + writeSmartPointerGetattroFunction(s, classContext, boolCastOpt); writeSmartPointerSetattroFunction(s, classContext); if (boolCastOpt.has_value()) @@ -6305,7 +6305,9 @@ void CppGenerator::writeGetattroFunction(TextStream &s, AttroCheck attroCheck, s << "return " << getattrFunc << ";\n" << outdent << "}\n\n"; } -void CppGenerator::writeSmartPointerGetattroFunction(TextStream &s, const GeneratorContext &context) +void CppGenerator::writeSmartPointerGetattroFunction(TextStream &s, + const GeneratorContext &context, + const BoolCastFunctionOptional &boolCast) { Q_ASSERT(context.forSmartPointer()); const AbstractMetaClass *metaClass = context.metaClass(); @@ -6316,6 +6318,18 @@ void CppGenerator::writeSmartPointerGetattroFunction(TextStream &s, const Genera << indent << "return nullptr;\n" << outdent << "PyErr_Clear();\n"; + if (boolCast.has_value()) { + writeSmartPointerCppSelfDefinition(s, context); + s << "if ("; + writeNbBoolExpression(s, boolCast.value(), true /* invert */); + s << ") {\n" << indent + << R"(PyTypeObject *tp = Py_TYPE(self); +PyErr_Format(PyExc_AttributeError, "Attempt to retrieve '%s' from null object '%s'.", + Shiboken::String::toCString(name), tp->tp_name); +return nullptr; +)" << outdent << "}\n"; + } + // This generates the code which dispatches access to member functions // and fields from the smart pointer to its pointee. s << smartPtrComment diff --git a/sources/shiboken6/generator/shiboken/cppgenerator.h b/sources/shiboken6/generator/shiboken/cppgenerator.h index 9f0dc6732..9bed05432 100644 --- a/sources/shiboken6/generator/shiboken/cppgenerator.h +++ b/sources/shiboken6/generator/shiboken/cppgenerator.h @@ -189,11 +189,14 @@ private: void writeSetattroDefinition(TextStream &s, const AbstractMetaClass *metaClass) const; static void writeSetattroDefaultReturn(TextStream &s); - void writeSmartPointerSetattroFunction(TextStream &s, const GeneratorContext &context) const; + void writeSmartPointerSetattroFunction(TextStream &s, + const GeneratorContext &context) const; void writeSetattroFunction(TextStream &s, AttroCheck attroCheck, const GeneratorContext &context) const; static void writeGetattroDefinition(TextStream &s, const AbstractMetaClass *metaClass); - static void writeSmartPointerGetattroFunction(TextStream &s, const GeneratorContext &context); + static void writeSmartPointerGetattroFunction(TextStream &s, + const GeneratorContext &context, + const BoolCastFunctionOptional &boolCast); void writeGetattroFunction(TextStream &s, AttroCheck attroCheck, const GeneratorContext &context) const; QString qObjectGetAttroFunction() const; |