From b881d8fb99972f1bd04ab4c84843cc8d43ddbeed Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Tue, 17 Nov 2009 12:51:16 +0100 Subject: Fix certain type-const-ref syntax not recognized by normalizedSignature() Normally, const Type & is normalized to just Type, but this didn't work for Templateconst& or Type*const& types. This now works as expected. However, this changes the way these types are normalized, and existing code using the old syntax will break. We can prevent this breakage by also normalizing the method signature in the metaobject when looking up signals and slots in QObject::connect(). I have added an autotest for this, which includes moc output generated by Qt 4.6's moc. This means we need to bump the metaobject revision number even though we are not adding any new data (only changing the normalized strings we store). Task-number: QTBUG-2407 Task-number: QTBUG-3722 Reviewed-by: ogoffart --- src/corelib/kernel/qmetaobject.cpp | 58 ++++++--- src/corelib/kernel/qmetaobject_p.h | 24 +++- src/corelib/kernel/qobject.cpp | 36 ++++-- src/tools/moc/generator.cpp | 2 +- tests/auto/qobject/moc_oldnormalizeobject.cpp | 118 ++++++++++++++++++ tests/auto/qobject/oldnormalizeobject.h | 28 +++++ tests/auto/qobject/tst_qobject.cpp | 172 ++++++++++++++++++++++++++ tests/auto/qobject/tst_qobject.pro | 22 ++-- 8 files changed, 424 insertions(+), 36 deletions(-) create mode 100644 tests/auto/qobject/moc_oldnormalizeobject.cpp create mode 100644 tests/auto/qobject/oldnormalizeobject.h diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp index ad9db09..bc1e8dcc 100644 --- a/src/corelib/kernel/qmetaobject.cpp +++ b/src/corelib/kernel/qmetaobject.cpp @@ -488,18 +488,30 @@ int QMetaObject::classInfoCount() const * \a MethodType might be MethodSignal or MethodSlot, or 0 to match everything. */ template -static inline int indexOfMethodRelative(const QMetaObject **baseObject, const char *method) +static inline int indexOfMethodRelative(const QMetaObject **baseObject, + const char *method, + bool normalizeStringData) { while (*baseObject) { const QMetaObject *const m = *baseObject; int i = (MethodType == MethodSignal && priv(m->d.data)->revision >= 4) - ? (priv(m->d.data)->signalCount - 1) : (priv(m->d.data)->methodCount - 1); + ? (priv(m->d.data)->signalCount - 1) : (priv(m->d.data)->methodCount - 1); const int end = (MethodType == MethodSlot && priv(m->d.data)->revision >= 4) - ? (priv(m->d.data)->signalCount - 1) : 0; - for (; i >= end; --i) { - if ((MethodType == 0 || (m->d.data[priv(m->d.data)->methodData + 5*i + 4] & MethodTypeMask) == MethodType) - && strcmp(method, m->d.stringdata + m->d.data[priv(m->d.data)->methodData + 5*i]) == 0) - return i; + ? (priv(m->d.data)->signalCount - 1) : 0; + if (!normalizeStringData) { + for (; i >= end; --i) { + if ((MethodType == 0 || (m->d.data[priv(m->d.data)->methodData + 5*i + 4] & MethodTypeMask) == MethodType) + && strcmp(method, m->d.stringdata + m->d.data[priv(m->d.data)->methodData + 5*i]) == 0) + return i; + } + } else if (priv(m->d.data)->revision < 5) { + const char *stringdata = (m->d.stringdata + m->d.data[priv(m->d.data)->methodData + 5 * i]); + const QByteArray normalizedSignature = QMetaObject::normalizedSignature(stringdata); + for (; i >= end; --i) { + if ((MethodType == 0|| (m->d.data[priv(m->d.data)->methodData + 5*i + 4] & MethodTypeMask) == MethodType) + && normalizedSignature == method) + return i; + } } *baseObject = m->d.superdata; } @@ -541,7 +553,11 @@ int QMetaObject::indexOfConstructor(const char *constructor) const int QMetaObject::indexOfMethod(const char *method) const { const QMetaObject *m = this; - int i = indexOfMethodRelative<0>(&m, method); + int i = indexOfMethodRelative<0>(&m, method, false); + if (i < 0) { + m = this; + i = indexOfMethodRelative<0>(&m, method, true); + } if (i >= 0) i += m->methodOffset(); return i; @@ -561,7 +577,11 @@ int QMetaObject::indexOfMethod(const char *method) const int QMetaObject::indexOfSignal(const char *signal) const { const QMetaObject *m = this; - int i = QMetaObjectPrivate::indexOfSignalRelative(&m, signal); + int i = QMetaObjectPrivate::indexOfSignalRelative(&m, signal, false); + if (i < 0) { + m = this; + i = QMetaObjectPrivate::indexOfSignalRelative(&m, signal, true); + } if (i >= 0) i += m->methodOffset(); return i; @@ -572,9 +592,11 @@ int QMetaObject::indexOfSignal(const char *signal) const \a baseObject will be adjusted to the enclosing QMetaObject, or 0 if the signal is not found */ -int QMetaObjectPrivate::indexOfSignalRelative(const QMetaObject **baseObject, const char *signal) +int QMetaObjectPrivate::indexOfSignalRelative(const QMetaObject **baseObject, + const char *signal, + bool normalizeStringData) { - int i = indexOfMethodRelative(baseObject, signal); + int i = indexOfMethodRelative(baseObject, signal, normalizeStringData); #ifndef QT_NO_DEBUG const QMetaObject *m = *baseObject; if (i >= 0 && m && m->d.superdata) { @@ -587,7 +609,6 @@ int QMetaObjectPrivate::indexOfSignalRelative(const QMetaObject **baseObject, co return i; } - /*! Finds \a slot and returns its index; otherwise returns -1. @@ -598,8 +619,17 @@ int QMetaObjectPrivate::indexOfSignalRelative(const QMetaObject **baseObject, co */ int QMetaObject::indexOfSlot(const char *slot) const { - const QMetaObject *m = this; - int i = indexOfMethodRelative(&m, slot); + int i = QMetaObjectPrivate::indexOfSlot(this, slot, false); + if (i < 0) + i = QMetaObjectPrivate::indexOfSlot(this, slot, true); + return i; +} + +int QMetaObjectPrivate::indexOfSlot(const QMetaObject *m, + const char *slot, + bool normalizeStringData) +{ + int i = indexOfMethodRelative(&m, slot, normalizeStringData); if (i >= 0) i += m->methodOffset(); return i; diff --git a/src/corelib/kernel/qmetaobject_p.h b/src/corelib/kernel/qmetaobject_p.h index b5a7530..7afb70b 100644 --- a/src/corelib/kernel/qmetaobject_p.h +++ b/src/corelib/kernel/qmetaobject_p.h @@ -115,11 +115,17 @@ struct QMetaObjectPrivate int constructorCount, constructorData; //since revision 2 int flags; //since revision 3 int signalCount; //since revision 4 + // revision 5 introduces changes in normalized signatures, no new members static inline const QMetaObjectPrivate *get(const QMetaObject *metaobject) { return reinterpret_cast(metaobject->d.data); } - static int indexOfSignalRelative(const QMetaObject **baseObject, const char* name); + static int indexOfSignalRelative(const QMetaObject **baseObject, + const char* name, + bool normalizeStringData); + static int indexOfSlot(const QMetaObject *m, + const char *slot, + bool normalizeStringData); static int originalClone(const QMetaObject *obj, int local_method_index); #ifndef QT_NO_QOBJECT @@ -245,6 +251,7 @@ static QByteArray normalizeTypeInternal(const char *t, const char *e, bool fixSc } while (optional[++i].keyword != 0); } + bool star = false; while (t != e) { char c = *t++; if (fixScope && c == ':' && *t == ':' ) { @@ -255,6 +262,7 @@ static QByteArray normalizeTypeInternal(const char *t, const char *e, bool fixSc --i; result.resize(i + 1); } + star = star || c == '*'; result += c; if (c == '<') { //template recursion @@ -275,6 +283,20 @@ static QByteArray normalizeTypeInternal(const char *t, const char *e, bool fixSc } } } + + // cv qualifers can appear after the type as well + if (t != e && (e - t >= 5 && strncmp("const", t, 5) == 0)) { + t += 5; + while (t != e && is_space(*t)) + ++t; + if (adjustConst && t != e && *t == '&') { + // treat const ref as value + ++t; + } else if (!star) { + // move const to the front (but not if const comes after a *) + result.prepend("const "); + } + } } return result; diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 95602d9..52c94e9 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -2522,20 +2522,25 @@ bool QObject::connect(const QObject *sender, const char *signal, const QMetaObject *smeta = sender->metaObject(); const char *signal_arg = signal; ++signal; //skip code - int signal_index = QMetaObjectPrivate::indexOfSignalRelative(&smeta, signal); + int signal_index = QMetaObjectPrivate::indexOfSignalRelative(&smeta, signal, false); if (signal_index < 0) { // check for normalized signatures tmp_signal_name = QMetaObject::normalizedSignature(signal - 1); signal = tmp_signal_name.constData() + 1; smeta = sender->metaObject(); - signal_index = QMetaObjectPrivate::indexOfSignalRelative(&smeta, signal); + signal_index = QMetaObjectPrivate::indexOfSignalRelative(&smeta, signal, false); + } + if (signal_index < 0) { + // re-use tmp_signal_name and signal from above - if (signal_index < 0) { - err_method_notfound(sender, signal_arg, "connect"); - err_info_about_objects("connect", sender, receiver); - return false; - } + smeta = sender->metaObject(); + signal_index = QMetaObjectPrivate::indexOfSignalRelative(&smeta, signal, true); + } + if (signal_index < 0) { + err_method_notfound(sender, signal_arg, "connect"); + err_info_about_objects("connect", sender, receiver); + return false; } signal_index = QMetaObjectPrivate::originalClone(smeta, signal_index); int signalOffset, methodOffset; @@ -2555,16 +2560,21 @@ bool QObject::connect(const QObject *sender, const char *signal, int method_index = -1; switch (membcode) { case QSLOT_CODE: - method_index = rmeta->indexOfSlot(method); + method_index = QMetaObjectPrivate::indexOfSlot(rmeta, method, false); break; case QSIGNAL_CODE: - method_index = rmeta->indexOfSignal(method); + method_index = QMetaObjectPrivate::indexOfSignalRelative(&rmeta, method, false); + if (method_index >= 0) + method_index += rmeta->methodOffset(); break; } if (method_index < 0) { // check for normalized methods tmp_method_name = QMetaObject::normalizedSignature(method); method = tmp_method_name.constData(); + + // rmeta may have been modified above + rmeta = receiver->metaObject(); switch (membcode) { case QSLOT_CODE: method_index = rmeta->indexOfSlot(method); @@ -2752,7 +2762,9 @@ bool QObject::disconnect(const QObject *sender, const char *signal, do { int signal_index = -1; if (signal) { - signal_index = QMetaObjectPrivate::indexOfSignalRelative(&smeta, signal); + signal_index = QMetaObjectPrivate::indexOfSignalRelative(&smeta, signal, false); + if (signal_index < 0) + signal_index = QMetaObjectPrivate::indexOfSignalRelative(&smeta, signal, true); if (signal_index < 0) break; signal_index = QMetaObjectPrivate::originalClone(smeta, signal_index); @@ -3361,7 +3373,9 @@ int QObjectPrivate::signalIndex(const char *signalName) const { Q_Q(const QObject); const QMetaObject *base = q->metaObject(); - int relative_index = QMetaObjectPrivate::indexOfSignalRelative(&base, signalName); + int relative_index = QMetaObjectPrivate::indexOfSignalRelative(&base, signalName, false); + if (relative_index < 0) + relative_index = QMetaObjectPrivate::indexOfSignalRelative(&base, signalName, true); if (relative_index < 0) return relative_index; relative_index = QMetaObjectPrivate::originalClone(base, relative_index); diff --git a/src/tools/moc/generator.cpp b/src/tools/moc/generator.cpp index 1ed6586..b99cb28 100644 --- a/src/tools/moc/generator.cpp +++ b/src/tools/moc/generator.cpp @@ -173,7 +173,7 @@ void Generator::generateCode() int index = 14; fprintf(out, "static const uint qt_meta_data_%s[] = {\n", qualifiedClassNameIdentifier.constData()); fprintf(out, "\n // content:\n"); - fprintf(out, " %4d, // revision\n", 4); + fprintf(out, " %4d, // revision\n", 5); fprintf(out, " %4d, // classname\n", strreg(cdef->qualified)); fprintf(out, " %4d, %4d, // classinfo\n", cdef->classInfoList.count(), cdef->classInfoList.count() ? index : 0); index += cdef->classInfoList.count() * 2; diff --git a/tests/auto/qobject/moc_oldnormalizeobject.cpp b/tests/auto/qobject/moc_oldnormalizeobject.cpp new file mode 100644 index 0000000..4f590ae --- /dev/null +++ b/tests/auto/qobject/moc_oldnormalizeobject.cpp @@ -0,0 +1,118 @@ +/**************************************************************************** +** Meta object code from reading C++ file 'oldnormalizeobject.h' +** +** Created: Wed Nov 18 11:43:05 2009 +** by: The Qt Meta Object Compiler version 62 (Qt 4.7.0) +** +** WARNING! All changes made in this file will be lost! +*****************************************************************************/ + +#include "../../../../../../master/tests/auto/qobject/oldnormalizeobject.h" +#if !defined(Q_MOC_OUTPUT_REVISION) +#error "The header file 'oldnormalizeobject.h' doesn't include ." +#elif Q_MOC_OUTPUT_REVISION != 62 +#error "This file was generated using the moc from 4.7.0. It" +#error "cannot be used with the include files from this version of Qt." +#error "(The moc has changed too much.)" +#endif + +QT_BEGIN_MOC_NAMESPACE +static const uint qt_meta_data_OldNormalizeObject[] = { + + // content: + 4, // revision + 0, // classname + 0, 0, // classinfo + 6, 14, // methods + 0, 0, // properties + 0, 0, // enums/sets + 0, 0, // constructors + 0, // flags + 3, // signalCount + + // signals: signature, parameters, type, tag, flags + 24, 20, 19, 19, 0x05, + 57, 20, 19, 19, 0x05, + 100, 20, 19, 19, 0x05, + + // slots: signature, parameters, type, tag, flags + 149, 20, 19, 19, 0x0a, + 180, 20, 19, 19, 0x0a, + 221, 20, 19, 19, 0x0a, + + 0 // eod +}; + +static const char qt_meta_stringdata_OldNormalizeObject[] = { + "OldNormalizeObject\0\0ref\0" + "typeRefSignal(Template&)\0" + "constTypeRefSignal(Template)\0" + "typeConstRefSignal(Templateconst&)\0" + "typeRefSlot(Template&)\0" + "constTypeRefSlot(Template)\0" + "typeConstRefSlot(Templateconst&)\0" +}; + +const QMetaObject OldNormalizeObject::staticMetaObject = { + { &QObject::staticMetaObject, qt_meta_stringdata_OldNormalizeObject, + qt_meta_data_OldNormalizeObject, 0 } +}; + +#ifdef Q_NO_DATA_RELOCATION +const QMetaObject &OldNormalizeObject::getStaticMetaObject() { return staticMetaObject; } +#endif //Q_NO_DATA_RELOCATION + +const QMetaObject *OldNormalizeObject::metaObject() const +{ + return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject; +} + +void *OldNormalizeObject::qt_metacast(const char *_clname) +{ + if (!_clname) return 0; + if (!strcmp(_clname, qt_meta_stringdata_OldNormalizeObject)) + return static_cast(const_cast< OldNormalizeObject*>(this)); + return QObject::qt_metacast(_clname); +} + +int OldNormalizeObject::qt_metacall(QMetaObject::Call _c, int _id, void **_a) +{ + _id = QObject::qt_metacall(_c, _id, _a); + if (_id < 0) + return _id; + if (_c == QMetaObject::InvokeMetaMethod) { + switch (_id) { + case 0: typeRefSignal((*reinterpret_cast< Template(*)>(_a[1]))); break; + case 1: constTypeRefSignal((*reinterpret_cast< const Template(*)>(_a[1]))); break; + case 2: typeConstRefSignal((*reinterpret_cast< Templateconst(*)>(_a[1]))); break; + case 3: typeRefSlot((*reinterpret_cast< Template(*)>(_a[1]))); break; + case 4: constTypeRefSlot((*reinterpret_cast< const Template(*)>(_a[1]))); break; + case 5: typeConstRefSlot((*reinterpret_cast< Templateconst(*)>(_a[1]))); break; + default: ; + } + _id -= 6; + } + return _id; +} + +// SIGNAL 0 +void OldNormalizeObject::typeRefSignal(Template & _t1) +{ + void *_a[] = { 0, const_cast(reinterpret_cast(&_t1)) }; + QMetaObject::activate(this, &staticMetaObject, 0, _a); +} + +// SIGNAL 1 +void OldNormalizeObject::constTypeRefSignal(const Template & _t1) +{ + void *_a[] = { 0, const_cast(reinterpret_cast(&_t1)) }; + QMetaObject::activate(this, &staticMetaObject, 1, _a); +} + +// SIGNAL 2 +void OldNormalizeObject::typeConstRefSignal(Template const & _t1) +{ + void *_a[] = { 0, const_cast(reinterpret_cast(&_t1)) }; + QMetaObject::activate(this, &staticMetaObject, 2, _a); +} +QT_END_MOC_NAMESPACE diff --git a/tests/auto/qobject/oldnormalizeobject.h b/tests/auto/qobject/oldnormalizeobject.h new file mode 100644 index 0000000..8420a3a --- /dev/null +++ b/tests/auto/qobject/oldnormalizeobject.h @@ -0,0 +1,28 @@ +#ifndef OLDNORMALIZEOBJECT_H +#define OLDNORMALIZEOBJECT_H + +#include + +struct Struct; +class Class; +template class Template; + +// An object with old moc output that incorrectly normalizes 'T const &' in the function +// signatures +class OldNormalizeObject : public QObject +{ + /* tmake ignore Q_OBJECT */ + Q_OBJECT + +signals: + void typeRefSignal(Template &ref); + void constTypeRefSignal(const Template &ref); + void typeConstRefSignal(Template const &ref); + +public slots: + void typeRefSlot(Template &) {} + void constTypeRefSlot(const Template &) {} + void typeConstRefSlot(Template const &) {} +}; + +#endif // OLDNORMALIZEOBJECT_H diff --git a/tests/auto/qobject/tst_qobject.cpp b/tests/auto/qobject/tst_qobject.cpp index 5035139..b296e1b 100644 --- a/tests/auto/qobject/tst_qobject.cpp +++ b/tests/auto/qobject/tst_qobject.cpp @@ -2017,6 +2017,7 @@ enum Enum { }; struct Struct { }; class Class { }; +template class Template { }; class NormalizeObject : public QObject { @@ -2054,6 +2055,12 @@ signals: void unsignedshortSignal(unsigned short); void unsignedcharSignal(unsigned char); + void typeRefSignal(Template &ref); + void constTypeRefSignal(const Template &ref); + void typeConstRefSignal(Template const &ref); + + void typePointerConstRefSignal(Class * const &); + public slots: void uintPointerSlot(uint *) { } void ulongPointerSlot(ulong *) { } @@ -2085,8 +2092,15 @@ public slots: void unsignedshortSlot(unsigned short) {}; void unsignedcharSlot(unsigned char) {}; + void typeRefSlot(Template &) {} + void constTypeRefSlot(const Template &) {} + void typeConstRefSlot(Template const &) {} + + void typePointerConstRefSlot(Class * const &) {} }; +#include "oldnormalizeobject.h" + void tst_QObject::normalize() { NormalizeObject object; @@ -2326,7 +2340,165 @@ void tst_QObject::normalize() SIGNAL(unsignedcharSignal(unsigned char)), SLOT(unsignedcharSlot(unsigned char)))); + // connect when original template signature and mixed usage of 'T const &', + // 'const T &', and 'T' + + QVERIFY(object.connect(&object, + SIGNAL(typeRefSignal(Template &)), + SLOT(typeRefSlot(Template &)))); + + QVERIFY(object.connect(&object, + SIGNAL(constTypeRefSignal(const Template &)), + SLOT(constTypeRefSlot(const Template &)))); + QVERIFY(object.connect(&object, + SIGNAL(constTypeRefSignal(const Template &)), + SLOT(constTypeRefSlot(const Template &)))); + QVERIFY(object.connect(&object, + SIGNAL(constTypeRefSignal(const Template &)), + SLOT(constTypeRefSlot(Template const &)))); + QVERIFY(object.connect(&object, + SIGNAL(constTypeRefSignal(Template const &)), + SLOT(constTypeRefSlot(Template const &)))); + QVERIFY(object.connect(&object, + SIGNAL(constTypeRefSignal(Template const &)), + SLOT(constTypeRefSlot(Template const &)))); + QVERIFY(object.connect(&object, + SIGNAL(constTypeRefSignal(const Template &)), + SLOT(typeConstRefSlot(const Template &)))); + QVERIFY(object.connect(&object, + SIGNAL(constTypeRefSignal(const Template &)), + SLOT(typeConstRefSlot(const Template &)))); + QVERIFY(object.connect(&object, + SIGNAL(constTypeRefSignal(const Template &)), + SLOT(typeConstRefSlot(Template const &)))); + QVERIFY(object.connect(&object, + SIGNAL(constTypeRefSignal(Template const &)), + SLOT(typeConstRefSlot(Template const &)))); + QVERIFY(object.connect(&object, + SIGNAL(constTypeRefSignal(Template const &)), + SLOT(typeConstRefSlot(Template const &)))); + + QVERIFY(object.connect(&object, + SIGNAL(typeConstRefSignal(const Template &)), + SLOT(constTypeRefSlot(const Template &)))); + QVERIFY(object.connect(&object, + SIGNAL(typeConstRefSignal(const Template &)), + SLOT(constTypeRefSlot(const Template &)))); + QVERIFY(object.connect(&object, + SIGNAL(typeConstRefSignal(const Template &)), + SLOT(constTypeRefSlot(Template const &)))); + QVERIFY(object.connect(&object, + SIGNAL(typeConstRefSignal(Template const &)), + SLOT(constTypeRefSlot(Template const &)))); + QVERIFY(object.connect(&object, + SIGNAL(typeConstRefSignal(Template const &)), + SLOT(constTypeRefSlot(Template const &)))); + + QVERIFY(object.connect(&object, + SIGNAL(typeConstRefSignal(const Template &)), + SLOT(typeConstRefSlot(const Template &)))); + QVERIFY(object.connect(&object, + SIGNAL(typeConstRefSignal(const Template &)), + SLOT(typeConstRefSlot(const Template &)))); + QVERIFY(object.connect(&object, + SIGNAL(typeConstRefSignal(const Template &)), + SLOT(typeConstRefSlot(Template const &)))); + QVERIFY(object.connect(&object, + SIGNAL(typeConstRefSignal(Template const &)), + SLOT(typeConstRefSlot(Template const &)))); + QVERIFY(object.connect(&object, + SIGNAL(typeConstRefSignal(Template const &)), + SLOT(typeConstRefSlot(Template const &)))); + + // same test again, this time with an object compiled with old moc output... we know that + // it is not possible to connect everything, whic is the purpose for this test + OldNormalizeObject oldobject; + + QVERIFY(oldobject.connect(&oldobject, + SIGNAL(constTypeRefSignal(const Template &)), + SLOT(constTypeRefSlot(const Template &)))); + QVERIFY(oldobject.connect(&oldobject, + SIGNAL(constTypeRefSignal(const Template &)), + SLOT(constTypeRefSlot(const Template &)))); + // this fails in older versions, but passes now due to proper normalizing + QVERIFY(oldobject.connect(&oldobject, + SIGNAL(constTypeRefSignal(const Template &)), + SLOT(constTypeRefSlot(Template const &)))); + // this fails in older versions, but passes now due to proper normalizing + QVERIFY(oldobject.connect(&oldobject, + SIGNAL(constTypeRefSignal(Template const &)), + SLOT(constTypeRefSlot(Template const &)))); + // this fails in older versions, but passes now due to proper normalizing + QVERIFY(oldobject.connect(&oldobject, + SIGNAL(constTypeRefSignal(Template const &)), + SLOT(constTypeRefSlot(Template const &)))); + + // these fail in older Qt versions, but pass now due to proper normalizing + QVERIFY(oldobject.connect(&oldobject, + SIGNAL(constTypeRefSignal(const Template &)), + SLOT(typeConstRefSlot(const Template &)))); + QVERIFY(oldobject.connect(&oldobject, + SIGNAL(constTypeRefSignal(const Template &)), + SLOT(typeConstRefSlot(const Template &)))); + QVERIFY(oldobject.connect(&oldobject, + SIGNAL(constTypeRefSignal(const Template &)), + SLOT(typeConstRefSlot(Template const &)))); + QVERIFY(oldobject.connect(&oldobject, + SIGNAL(constTypeRefSignal(Template const &)), + SLOT(typeConstRefSlot(Template const &)))); + QVERIFY(oldobject.connect(&oldobject, + SIGNAL(constTypeRefSignal(Template const &)), + SLOT(typeConstRefSlot(Template const &)))); + + // these also fail in older Qt versions, but pass now due to proper normalizing + QVERIFY(oldobject.connect(&oldobject, + SIGNAL(typeConstRefSignal(const Template &)), + SLOT(constTypeRefSlot(const Template &)))); + QVERIFY(oldobject.connect(&oldobject, + SIGNAL(typeConstRefSignal(const Template &)), + SLOT(constTypeRefSlot(const Template &)))); + QVERIFY(oldobject.connect(&oldobject, + SIGNAL(typeConstRefSignal(const Template &)), + SLOT(constTypeRefSlot(Template const &)))); + QVERIFY(oldobject.connect(&oldobject, + SIGNAL(typeConstRefSignal(Template const &)), + SLOT(constTypeRefSlot(Template const &)))); + QVERIFY(oldobject.connect(&oldobject, + SIGNAL(typeConstRefSignal(Template const &)), + SLOT(constTypeRefSlot(Template const &)))); + + // this fails in older versions, but passes now due to proper normalizing + QVERIFY(oldobject.connect(&oldobject, + SIGNAL(typeConstRefSignal(const Template &)), + SLOT(typeConstRefSlot(const Template &)))); + // this fails in older versions, but passes now due to proper normalizing + QVERIFY(oldobject.connect(&oldobject, + SIGNAL(typeConstRefSignal(const Template &)), + SLOT(typeConstRefSlot(const Template &)))); + // this fails in older versions, but passes now due to proper normalizing + QVERIFY(oldobject.connect(&oldobject, + SIGNAL(typeConstRefSignal(const Template &)), + SLOT(typeConstRefSlot(Template const &)))); + QVERIFY(oldobject.connect(&oldobject, + SIGNAL(typeConstRefSignal(Template const &)), + SLOT(typeConstRefSlot(Template const &)))); + QVERIFY(oldobject.connect(&oldobject, + SIGNAL(typeConstRefSignal(Template const &)), + SLOT(typeConstRefSlot(Template const &)))); + + QVERIFY(object.connect(&object, + SIGNAL(typePointerConstRefSignal(Class*const&)), + SLOT(typePointerConstRefSlot(Class*const&)))); + QVERIFY(object.connect(&object, + SIGNAL(typePointerConstRefSignal(Class*const&)), + SLOT(typePointerConstRefSlot(Class*)))); + QVERIFY(object.connect(&object, + SIGNAL(typePointerConstRefSignal(Class*)), + SLOT(typePointerConstRefSlot(Class*const&)))); + QVERIFY(object.connect(&object, + SIGNAL(typePointerConstRefSignal(Class*)), + SLOT(typePointerConstRefSlot(Class*)))); } class SiblingDeleter : public QObject diff --git a/tests/auto/qobject/tst_qobject.pro b/tests/auto/qobject/tst_qobject.pro index 003ee98..0200f3e 100644 --- a/tests/auto/qobject/tst_qobject.pro +++ b/tests/auto/qobject/tst_qobject.pro @@ -1,16 +1,20 @@ load(qttest_p4) -SOURCES += tst_qobject.cpp +SOURCES += tst_qobject.cpp -QT = core network gui -contains(QT_CONFIG, qt3support):DEFINES+=QT_HAS_QT3SUPPORT +# this is here for a reason, moc_oldnormalizedobject.cpp is not auto-generated, it was generated by +# moc from Qt 4.6, and should *not* be generated by the current moc +SOURCES += moc_oldnormalizeobject.cpp -wince*: { - addFiles.sources = signalbug.exe - addFiles.path = . - DEPLOYMENT += addFiles +QT = core \ + network \ + gui +contains(QT_CONFIG, qt3support):DEFINES += QT_HAS_QT3SUPPORT +wince*: { + addFiles.sources = signalbug.exe + addFiles.path = . + DEPLOYMENT += addFiles } - -symbian: { +symbian: { addFiles.sources = signalbug.exe addFiles.path = \sys\bin DEPLOYMENT += addFiles -- cgit v0.12