aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2022-04-04 11:46:51 +0200
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2022-04-04 15:14:57 +0200
commitf21f5c469813ab8fb13b2607624dd9a33c345acb (patch)
tree4e337303e7a5a028d5c6ea309f523921e4d78cf0
parent545e90b4c434c7380a61113ec377ba56007eb0dc (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.cpp18
-rw-r--r--sources/shiboken6/generator/shiboken/cppgenerator.h7
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;