diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp index de7aa212081..be8467c2927 100644 --- a/src/corelib/kernel/qmetatype.cpp +++ b/src/corelib/kernel/qmetatype.cpp @@ -38,6 +38,7 @@ # include "qjsonobject.h" # include "qjsonvalue.h" # include "qline.h" +# include "qloggingcategory.h" # include "qmetaobject.h" # include "qobject.h" # include "qpoint.h" @@ -58,6 +59,10 @@ QT_BEGIN_NAMESPACE +#ifndef QT_BOOTSTRAPPED +Q_STATIC_LOGGING_CATEGORY(lcMetatypeDeprecated, "qt.core.qmetatype.deprecated"); +#endif + #define NS(x) QT_PREPEND_NAMESPACE(x) QT_IMPL_METATYPE_EXTERN_TAGGED(QtMetaTypePrivate::QPairVariantInterfaceImpl, QPairVariantInterfaceImpl) @@ -3265,6 +3270,13 @@ QMetaType::QMetaType(int typeId) : QMetaType(interfaceForType(typeId)) {} */ namespace QtPrivate { +#if !defined(QT_BOOTSTRAPPED) +void QMetaTypeCopyTraits::warnAboutDeprecatedCopy(const char *name) +{ + qCWarning(lcMetatypeDeprecated, "QMetaType: copy construction of type '%s' is deprecated", name); +} +#endif + #if !defined(QT_BOOTSTRAPPED) && !defined(Q_CC_MSVC) && !defined(Q_OS_INTEGRITY) // Explicit instantiation definition diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h index 44dbae5342e..0ec95c3bb99 100644 --- a/src/corelib/kernel/qmetatype.h +++ b/src/corelib/kernel/qmetatype.h @@ -28,7 +28,7 @@ #include #include #include -#include +#include #ifdef Bool #error qmetatype.h must be included before any header file that defines Bool @@ -2408,6 +2408,20 @@ struct QDataStreamOperatorForType # pragma GCC visibility push(hidden) #endif +// ### Qt 7: consider removing this infrastructure if nothing uses it +// (see also getCopyCtr()) +namespace QMetaTypeCopyTraits +{ + // Hack to suppress deprecation warnings from types + // with deprecated copy operations, cf. QTBUG-132752 + template + using HasDeprecatedCopyConstructorTest = typename T::_q_hasDeprecatedCopyConstructor; + +#if !defined(QT_BOOTSTRAPPED) + Q_CORE_EXPORT void warnAboutDeprecatedCopy(const char *name); +#endif +} // namespace QMetaTypeCopyTraits + template class QMetaTypeForType { @@ -2465,7 +2479,14 @@ public: { if constexpr (std::is_copy_constructible_v && !std::is_trivially_copy_constructible_v) { return [](const QMetaTypeInterface *, void *addr, const void *other) { - new (addr) S(*reinterpret_cast(other)); + if constexpr (qxp::is_detected_v) { +#if !defined(QT_BOOTSTRAPPED) + QMetaTypeCopyTraits::warnAboutDeprecatedCopy(getName()); +#endif + QT_IGNORE_DEPRECATIONS(new (addr) S(*reinterpret_cast(other));) + } else { + new (addr) S(*reinterpret_cast(other)); + } }; } else { return nullptr; diff --git a/src/sql/kernel/qsqlquery.cpp b/src/sql/kernel/qsqlquery.cpp index b9ebfedb639..57268e33cf0 100644 --- a/src/sql/kernel/qsqlquery.cpp +++ b/src/sql/kernel/qsqlquery.cpp @@ -216,11 +216,12 @@ QSqlQuery::~QSqlQuery() delete d; } -#if QT_DEPRECATED_SINCE(6, 2) +#if QT_REMOVAL_QT7_DEPRECATED_SINCE(6, 2) /*! Constructs a copy of \a other. - \deprecated QSqlQuery cannot be meaningfully copied. Prepared + \deprecated [6.2] QSqlQuery cannot be meaningfully copied, and + therefore will no longer be copiable in Qt 7. Prepared statements, bound values and so on will not work correctly, depending on your database driver (for instance, changing the copy will affect the original). Treat QSqlQuery as a move-only type instead. @@ -235,7 +236,8 @@ QSqlQuery::QSqlQuery(const QSqlQuery& other) /*! Assigns \a other to this object. - \deprecated QSqlQuery cannot be meaningfully copied. Prepared + \deprecated [6.2] QSqlQuery cannot be meaningfully copied, and + therefore will no longer be copiable in Qt 7. Prepared statements, bound values and so on will not work correctly, depending on your database driver (for instance, changing the copy will affect the original). Treat QSqlQuery as a move-only type instead. diff --git a/src/sql/kernel/qsqlquery.h b/src/sql/kernel/qsqlquery.h index 96ad9022127..ec5f06550e1 100644 --- a/src/sql/kernel/qsqlquery.h +++ b/src/sql/kernel/qsqlquery.h @@ -32,7 +32,7 @@ public: explicit QSqlQuery(const QString& query = QString(), const QSqlDatabase &db = QSqlDatabase()); explicit QSqlQuery(const QSqlDatabase &db); -#if QT_DEPRECATED_SINCE(6, 2) +#if QT_REMOVAL_QT7_DEPRECATED_SINCE(6, 2) QT_DEPRECATED_VERSION_X_6_2("QSqlQuery is not meant to be copied. Use move construction instead.") QSqlQuery(const QSqlQuery &other); QT_DEPRECATED_VERSION_X_6_2("QSqlQuery is not meant to be copied. Use move assignment instead.") @@ -111,6 +111,10 @@ public: void finish(); bool nextResult(); +#if QT_REMOVAL_QT7_DEPRECATED_SINCE(6, 2) + // Avoid raising warnings in QMetaType, cf. QTBUG-132752 + using _q_hasDeprecatedCopyConstructor = void; +#endif private: QSqlQueryPrivate* d; }; diff --git a/src/sql/models/qsqlquerymodel.cpp b/src/sql/models/qsqlquerymodel.cpp index 99aa82428e4..6cd2f342a9c 100644 --- a/src/sql/models/qsqlquerymodel.cpp +++ b/src/sql/models/qsqlquerymodel.cpp @@ -379,9 +379,11 @@ void QSqlQueryModel::queryChange() // do nothing } -#if QT_DEPRECATED_SINCE(6, 2) +#if QT_REMOVAL_QT7_DEPRECATED_SINCE(6, 2) /*! \deprecated [6.2] Use the \c{setQuery(QSqlQuery &&query)} overload instead. + This overload will be removed in Qt 7. + \overload */ void QSqlQueryModel::setQuery(const QSqlQuery &query) @@ -389,7 +391,7 @@ void QSqlQueryModel::setQuery(const QSqlQuery &query) QT_IGNORE_DEPRECATIONS(QSqlQuery copy = query;) setQuery(std::move(copy)); } -#endif // QT_DEPRECATED_SINCE(6, 2) +#endif // QT_REMOVAL_QT7_DEPRECATED_SINCE(6, 2) /*! Resets the model and sets the data provider to be the given \a diff --git a/src/sql/models/qsqlquerymodel.h b/src/sql/models/qsqlquerymodel.h index f168d0bda13..72b9b053f03 100644 --- a/src/sql/models/qsqlquerymodel.h +++ b/src/sql/models/qsqlquerymodel.h @@ -40,7 +40,7 @@ public: bool insertColumns(int column, int count, const QModelIndex &parent = QModelIndex()) override; bool removeColumns(int column, int count, const QModelIndex &parent = QModelIndex()) override; -#if QT_DEPRECATED_SINCE(6, 2) +#if QT_REMOVAL_QT7_DEPRECATED_SINCE(6, 2) QT_DEPRECATED_VERSION_X_6_2("QSqlQuery is not meant to be copied. Pass it by move instead.") void setQuery(const QSqlQuery &query); #endif diff --git a/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp b/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp index be98b7c1909..edc3c67587b 100644 --- a/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp +++ b/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp @@ -274,6 +274,12 @@ private slots: void uuid_data() { generic_data(); } void uuid(); +#if QT_REMOVAL_QT7_DEPRECATED_SINCE(6, 2) + // cleanup() is data-driven + void qmetatypeDeprecatedCopy_data() { generic_data(); } + void qmetatypeDeprecatedCopy(); +#endif + private: // returns all database connections void generic_data(const QString &engine=QString()); @@ -5282,5 +5288,17 @@ void tst_QSqlQuery::uuid() QCOMPARE(qry.value(1).metaType().id(), QMetaType::QUuid); } +#if QT_REMOVAL_QT7_DEPRECATED_SINCE(6, 2) +void tst_QSqlQuery::qmetatypeDeprecatedCopy() +{ + QMetaType mt = QMetaType::fromType(); + QSqlQuery query; + + QTest::ignoreMessage(QtWarningMsg, "QMetaType: copy construction of type 'QSqlQuery' is deprecated"); + void *copy = mt.create(&query); + mt.destroy(copy); +} +#endif + QTEST_MAIN(tst_QSqlQuery) #include "tst_qsqlquery.moc"