From 200a3c92972473476d8323dd8ff8e4b8fbc182f7 Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Fri, 20 May 2022 18:36:48 +0200 Subject: [PATCH] QMetaType: disable conversion from smart pointer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QMetaType can register a converter from a smart pointer class to QObject *. The code tries to do so even if the smart pointer is actually holding a pointer to a _const_ QObject (e.g. shared_ptr), causing a compile error: ../src/qt5/qtbase/build/include/QtCore/../../../src/corelib/kernel/qmetatype.h:1208:32: error: invalid conversion from ‘const QObject*’ to ‘QObject*’ [-fpermissive] 1208 | return p.operator->(); | ~~~~~~~~~~~~^~ | | | const QObject* Disable the conversion if indeed the source is const qualified. Change-Id: I9e9bc5992f74131e5cfd6ece9b83d4f26d370e92 Fixes: QTBUG-103741 Reviewed-by: Thiago Macieira Reviewed-by: Qt CI Bot (cherry picked from commit c613dd4765637a00837dd66abc2b940632022a60) Reviewed-by: Qt Cherry-pick Bot --- src/corelib/kernel/qmetatype.h | 2 +- .../auto/corelib/kernel/qobject/tst_qobject.cpp | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h index a7796966131..2a341b870a3 100644 --- a/src/corelib/kernel/qmetatype.h +++ b/src/corelib/kernel/qmetatype.h @@ -1520,7 +1520,7 @@ struct SharedPointerMetaTypeIdHelper, true> \ }; \ template \ struct MetaTypeSmartPointerHelper , \ - typename std::enable_if::Value>::type> \ + typename std::enable_if::Value && !std::is_const_v>::type> \ { \ static bool registerConverter() \ { \ diff --git a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp index 6f3d8ba091e..d639cdec26c 100644 --- a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp +++ b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp @@ -8143,5 +8143,22 @@ void tst_QObject::objectNameBinding() static_assert(QtPrivate::HasQ_OBJECT_Macro::Value); static_assert(!QtPrivate::HasQ_OBJECT_Macro::Value); +Q_DECLARE_SMART_POINTER_METATYPE(std::shared_ptr) +Q_DECLARE_SMART_POINTER_METATYPE(std::unique_ptr) + + +// QTBUG-103741: OK to use smart pointers to const QObject in signals/slots +class SenderWithSharedPointerConstQObject : public QObject +{ + Q_OBJECT + +signals: + void aSignal1(const QSharedPointer &); + void aSignal2(const QWeakPointer &); + void aSignal3(const QPointer &); + void aSignal4(const std::shared_ptr &); + void aSignal5(const std::unique_ptr &); +}; + QTEST_MAIN(tst_QObject) #include "tst_qobject.moc"