QObjectPrivate: encode the version number in the constructor parameters
Instead of allowing the code to start and then possibly fail at runtime. This isn't a 100% sure solution because it's a function call. With lazy symbol binding on some OSes, the mistake won't be noticed until the function call is attempted. However, most OSes now resolve *all* calls at load time so they can mark the GOT (or equivalent) pages read-only, meaning the loading of the library will fail. qversiontagging_p.h is a more sure way in OSes / executable formats it works on. Change-Id: If7867a37256b7141001dfffd9bd299bb1bbd7c63 Reviewed-by: Marc Mutz <marc.mutz@qt.io>
This commit is contained in:
parent
1b85143d21
commit
744fda9cb4
@ -158,11 +158,9 @@ QMetaObject *QObjectData::dynamicMetaObject() const
|
||||
return metaObject->toDynamicMetaObject(q_ptr);
|
||||
}
|
||||
|
||||
QObjectPrivate::QObjectPrivate(int version)
|
||||
QObjectPrivate::QObjectPrivate(decltype(QObjectPrivateVersion))
|
||||
: threadData(nullptr), currentChildBeingDeleted(nullptr)
|
||||
{
|
||||
checkForIncompatibleLibraryVersion(version);
|
||||
|
||||
// QObjectData initialization
|
||||
q_ptr = nullptr;
|
||||
parent = nullptr; // no parent yet. It is set by setParent()
|
||||
|
@ -39,6 +39,19 @@ QT_BEGIN_NAMESPACE
|
||||
#define QT_ANONYMOUS_PRIVATE_PROPERTY(d, text) QT_ANNOTATE_CLASS2(qt_anonymous_private_property, d, text)
|
||||
#endif
|
||||
|
||||
#define QT_CONCAT(B, M, m, u) QT_CONCAT2(B, M, m, u)
|
||||
#define QT_CONCAT2(B, M, m, u) B ## M ## _ ## m ## _ ## u
|
||||
#if defined(QT_BUILD_INTERNAL) && !QT_CONFIG(elf_private_full_version)
|
||||
// Don't check the version parameter in internal builds.
|
||||
// This allows incompatible versions to be loaded, possibly for testing.
|
||||
enum QObjectPrivateVersionEnum
|
||||
#else
|
||||
enum QT_CONCAT(QtPrivate_, QT_VERSION_MAJOR, QT_VERSION_MINOR, QT_VERSION_PATCH)
|
||||
#endif
|
||||
{ QObjectPrivateVersion = QT_VERSION };
|
||||
#undef QT_CONCAT
|
||||
#undef QT_CONCAT2
|
||||
|
||||
class QVariant;
|
||||
class QThreadData;
|
||||
class QObjectConnectionListVector;
|
||||
@ -58,8 +71,6 @@ void Q_CORE_EXPORT qt_register_signal_spy_callbacks(QSignalSpyCallbackSet *callb
|
||||
|
||||
extern Q_CORE_EXPORT QBasicAtomicPointer<QSignalSpyCallbackSet> qt_signal_spy_callback_set;
|
||||
|
||||
enum { QObjectPrivateVersion = QT_VERSION };
|
||||
|
||||
class Q_CORE_EXPORT QAbstractDeclarativeData
|
||||
{
|
||||
public:
|
||||
@ -130,14 +141,12 @@ public:
|
||||
linked list.
|
||||
*/
|
||||
|
||||
QObjectPrivate(int version = QObjectPrivateVersion);
|
||||
QObjectPrivate(decltype(QObjectPrivateVersion) version = QObjectPrivateVersion);
|
||||
virtual ~QObjectPrivate();
|
||||
void deleteChildren();
|
||||
// used to clear binding storage early in ~QObject
|
||||
void clearBindingStorage();
|
||||
|
||||
inline void checkForIncompatibleLibraryVersion(int version) const;
|
||||
|
||||
void setParent_helper(QObject *);
|
||||
void moveToThread_helper();
|
||||
void setThreadData_helper(QThreadData *currentData, QThreadData *targetData, QBindingStatus *status);
|
||||
@ -216,28 +225,6 @@ public:
|
||||
QAtomicPointer<QtSharedPointer::ExternalRefCountData> sharedRefcount;
|
||||
};
|
||||
|
||||
/*
|
||||
Catch mixing of incompatible library versions.
|
||||
|
||||
Should be called from the constructor of every non-final subclass
|
||||
of QObjectPrivate, to ensure we catch incompatibilities between
|
||||
the intermediate base and subclasses thereof.
|
||||
*/
|
||||
inline void QObjectPrivate::checkForIncompatibleLibraryVersion(int version) const
|
||||
{
|
||||
#if defined(QT_BUILD_INTERNAL)
|
||||
// Don't check the version parameter in internal builds.
|
||||
// This allows incompatible versions to be loaded, possibly for testing.
|
||||
Q_UNUSED(version);
|
||||
#else
|
||||
if (Q_UNLIKELY(version != QObjectPrivateVersion)) {
|
||||
qFatal("Cannot mix incompatible Qt library (%d.%d.%d) with this library (%d.%d.%d)",
|
||||
(version >> 16) & 0xff, (version >> 8) & 0xff, version & 0xff,
|
||||
(QObjectPrivateVersion >> 16) & 0xff, (QObjectPrivateVersion >> 8) & 0xff, QObjectPrivateVersion & 0xff);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
inline bool QObjectPrivate::isDeclarativeSignalConnected(uint signal_index) const
|
||||
{
|
||||
return !isDeletingChildren && declarativeData && QAbstractDeclarativeData::isSignalConnected
|
||||
|
@ -25,7 +25,7 @@ using namespace Qt::StringLiterals;
|
||||
// we use a tighter limit for the variables range.
|
||||
const qreal g_offset = (sizeof(qreal) == sizeof(double)) ? QWIDGETSIZE_MAX : QWIDGETSIZE_MAX / 32;
|
||||
|
||||
QGraphicsAnchorPrivate::QGraphicsAnchorPrivate(int version)
|
||||
QGraphicsAnchorPrivate::QGraphicsAnchorPrivate(decltype(QObjectPrivateVersion) version)
|
||||
: QObjectPrivate(version), layoutPrivate(nullptr), data(nullptr),
|
||||
sizePolicy(QSizePolicy::Fixed), preferredSize(0),
|
||||
hasSize(true)
|
||||
|
@ -313,7 +313,7 @@ class QGraphicsAnchorPrivate : public QObjectPrivate
|
||||
Q_DECLARE_PUBLIC(QGraphicsAnchor)
|
||||
|
||||
public:
|
||||
explicit QGraphicsAnchorPrivate(int version = QObjectPrivateVersion);
|
||||
explicit QGraphicsAnchorPrivate(decltype(QObjectPrivateVersion) = QObjectPrivateVersion);
|
||||
~QGraphicsAnchorPrivate();
|
||||
|
||||
void setSpacing(qreal value);
|
||||
|
@ -103,7 +103,7 @@ static inline bool qRectIntersects(const QRect &r1, const QRect &r2)
|
||||
|
||||
extern bool qt_sendSpontaneousEvent(QObject*, QEvent*); // qapplication.cpp
|
||||
|
||||
QWidgetPrivate::QWidgetPrivate(int version)
|
||||
QWidgetPrivate::QWidgetPrivate(decltype(QObjectPrivateVersion) version)
|
||||
: QObjectPrivate(version)
|
||||
, focus_next(nullptr)
|
||||
, focus_prev(nullptr)
|
||||
@ -164,16 +164,6 @@ QWidgetPrivate::QWidgetPrivate(int version)
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef QT_BUILD_INTERNAL
|
||||
// Don't check the version parameter in internal builds.
|
||||
// This allows incompatible versions to be loaded, possibly for testing.
|
||||
Q_UNUSED(version);
|
||||
#else
|
||||
if (Q_UNLIKELY(version != QObjectPrivateVersion))
|
||||
qFatal("Cannot mix incompatible Qt library (version 0x%x) with this library (version 0x%x)",
|
||||
version, QObjectPrivateVersion);
|
||||
#endif
|
||||
|
||||
willBeWidget = true; // used in QObject's ctor
|
||||
memset(high_attributes, 0, sizeof(high_attributes));
|
||||
|
||||
|
@ -207,7 +207,7 @@ public:
|
||||
Q_ENUM(Direction)
|
||||
|
||||
// Functions.
|
||||
explicit QWidgetPrivate(int version = QObjectPrivateVersion);
|
||||
explicit QWidgetPrivate(decltype(QObjectPrivateVersion) = QObjectPrivateVersion);
|
||||
~QWidgetPrivate();
|
||||
|
||||
static QWidgetPrivate *get(QWidget *w) { return w->d_func(); }
|
||||
|
Loading…
x
Reference in New Issue
Block a user