summaryrefslogtreecommitdiffstats
path: root/tests/auto/qobject
diff options
context:
space:
mode:
authorBradley T. Hughes <bradley.hughes@nokia.com>2009-11-17 11:51:16 (GMT)
committerBradley T. Hughes <bradley.hughes@nokia.com>2009-11-30 14:58:31 (GMT)
commitb881d8fb99972f1bd04ab4c84843cc8d43ddbeed (patch)
treef415bc8c76ecc388d05f940a02e2c863dc96f111 /tests/auto/qobject
parentf3ac20ac8100142cde0accfb72eab48590303c4a (diff)
downloadQt-b881d8fb99972f1bd04ab4c84843cc8d43ddbeed.zip
Qt-b881d8fb99972f1bd04ab4c84843cc8d43ddbeed.tar.gz
Qt-b881d8fb99972f1bd04ab4c84843cc8d43ddbeed.tar.bz2
Fix certain type-const-ref syntax not recognized by normalizedSignature()
Normally, const Type & is normalized to just Type, but this didn't work for Template<T>const& 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
Diffstat (limited to 'tests/auto/qobject')
-rw-r--r--tests/auto/qobject/moc_oldnormalizeobject.cpp118
-rw-r--r--tests/auto/qobject/oldnormalizeobject.h28
-rw-r--r--tests/auto/qobject/tst_qobject.cpp172
-rw-r--r--tests/auto/qobject/tst_qobject.pro22
4 files changed, 331 insertions, 9 deletions
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 <QObject>."
+#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<Class&>&)\0"
+ "constTypeRefSignal(Template<const Class&>)\0"
+ "typeConstRefSignal(Template<const Class&>const&)\0"
+ "typeRefSlot(Template<Class&>&)\0"
+ "constTypeRefSlot(Template<const Class&>)\0"
+ "typeConstRefSlot(Template<const Class&>const&)\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<void*>(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<Class&>(*)>(_a[1]))); break;
+ case 1: constTypeRefSignal((*reinterpret_cast< const Template<const Class&>(*)>(_a[1]))); break;
+ case 2: typeConstRefSignal((*reinterpret_cast< Template<const Class&>const(*)>(_a[1]))); break;
+ case 3: typeRefSlot((*reinterpret_cast< Template<Class&>(*)>(_a[1]))); break;
+ case 4: constTypeRefSlot((*reinterpret_cast< const Template<const Class&>(*)>(_a[1]))); break;
+ case 5: typeConstRefSlot((*reinterpret_cast< Template<const Class&>const(*)>(_a[1]))); break;
+ default: ;
+ }
+ _id -= 6;
+ }
+ return _id;
+}
+
+// SIGNAL 0
+void OldNormalizeObject::typeRefSignal(Template<Class&> & _t1)
+{
+ void *_a[] = { 0, const_cast<void*>(reinterpret_cast<const void*>(&_t1)) };
+ QMetaObject::activate(this, &staticMetaObject, 0, _a);
+}
+
+// SIGNAL 1
+void OldNormalizeObject::constTypeRefSignal(const Template<const Class&> & _t1)
+{
+ void *_a[] = { 0, const_cast<void*>(reinterpret_cast<const void*>(&_t1)) };
+ QMetaObject::activate(this, &staticMetaObject, 1, _a);
+}
+
+// SIGNAL 2
+void OldNormalizeObject::typeConstRefSignal(Template<Class const&> const & _t1)
+{
+ void *_a[] = { 0, const_cast<void*>(reinterpret_cast<const void*>(&_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 <QObject>
+
+struct Struct;
+class Class;
+template <typename T> class Template;
+
+// An object with old moc output that incorrectly normalizes 'T<C> const &' in the function
+// signatures
+class OldNormalizeObject : public QObject
+{
+ /* tmake ignore Q_OBJECT */
+ Q_OBJECT
+
+signals:
+ void typeRefSignal(Template<Class &> &ref);
+ void constTypeRefSignal(const Template<const Class &> &ref);
+ void typeConstRefSignal(Template<Class const &> const &ref);
+
+public slots:
+ void typeRefSlot(Template<Class &> &) {}
+ void constTypeRefSlot(const Template<const Class &> &) {}
+ void typeConstRefSlot(Template<Class const &> 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 <typename T> class Template { };
class NormalizeObject : public QObject
{
@@ -2054,6 +2055,12 @@ signals:
void unsignedshortSignal(unsigned short);
void unsignedcharSignal(unsigned char);
+ void typeRefSignal(Template<Class &> &ref);
+ void constTypeRefSignal(const Template<Class const &> &ref);
+ void typeConstRefSignal(Template<Class const &> 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<Class &> &) {}
+ void constTypeRefSlot(const Template<const Class &> &) {}
+ void typeConstRefSlot(Template<Class const &> 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<C const &> const &',
+ // 'const T<const C &> &', and 'T<const C &>'
+
+ QVERIFY(object.connect(&object,
+ SIGNAL(typeRefSignal(Template<Class &> &)),
+ SLOT(typeRefSlot(Template<Class &> &))));
+
+ QVERIFY(object.connect(&object,
+ SIGNAL(constTypeRefSignal(const Template<const Class &> &)),
+ SLOT(constTypeRefSlot(const Template<const Class &> &))));
+ QVERIFY(object.connect(&object,
+ SIGNAL(constTypeRefSignal(const Template<const Class &> &)),
+ SLOT(constTypeRefSlot(const Template<Class const &> &))));
+ QVERIFY(object.connect(&object,
+ SIGNAL(constTypeRefSignal(const Template<const Class &> &)),
+ SLOT(constTypeRefSlot(Template<Class const &> const &))));
+ QVERIFY(object.connect(&object,
+ SIGNAL(constTypeRefSignal(Template<const Class &> const &)),
+ SLOT(constTypeRefSlot(Template<Class const &> const &))));
+ QVERIFY(object.connect(&object,
+ SIGNAL(constTypeRefSignal(Template<Class const &> const &)),
+ SLOT(constTypeRefSlot(Template<Class const &> const &))));
+ QVERIFY(object.connect(&object,
+ SIGNAL(constTypeRefSignal(const Template<const Class &> &)),
+ SLOT(typeConstRefSlot(const Template<const Class &> &))));
+ QVERIFY(object.connect(&object,
+ SIGNAL(constTypeRefSignal(const Template<const Class &> &)),
+ SLOT(typeConstRefSlot(const Template<Class const &> &))));
+ QVERIFY(object.connect(&object,
+ SIGNAL(constTypeRefSignal(const Template<const Class &> &)),
+ SLOT(typeConstRefSlot(Template<Class const &> const &))));
+ QVERIFY(object.connect(&object,
+ SIGNAL(constTypeRefSignal(Template<const Class &> const &)),
+ SLOT(typeConstRefSlot(Template<Class const &> const &))));
+ QVERIFY(object.connect(&object,
+ SIGNAL(constTypeRefSignal(Template<Class const &> const &)),
+ SLOT(typeConstRefSlot(Template<Class const &> const &))));
+
+ QVERIFY(object.connect(&object,
+ SIGNAL(typeConstRefSignal(const Template<const Class &> &)),
+ SLOT(constTypeRefSlot(const Template<const Class &> &))));
+ QVERIFY(object.connect(&object,
+ SIGNAL(typeConstRefSignal(const Template<const Class &> &)),
+ SLOT(constTypeRefSlot(const Template<Class const &> &))));
+ QVERIFY(object.connect(&object,
+ SIGNAL(typeConstRefSignal(const Template<const Class &> &)),
+ SLOT(constTypeRefSlot(Template<Class const &> const &))));
+ QVERIFY(object.connect(&object,
+ SIGNAL(typeConstRefSignal(Template<const Class &> const &)),
+ SLOT(constTypeRefSlot(Template<Class const &> const &))));
+ QVERIFY(object.connect(&object,
+ SIGNAL(typeConstRefSignal(Template<Class const &> const &)),
+ SLOT(constTypeRefSlot(Template<Class const &> const &))));
+
+ QVERIFY(object.connect(&object,
+ SIGNAL(typeConstRefSignal(const Template<const Class &> &)),
+ SLOT(typeConstRefSlot(const Template<const Class &> &))));
+ QVERIFY(object.connect(&object,
+ SIGNAL(typeConstRefSignal(const Template<const Class &> &)),
+ SLOT(typeConstRefSlot(const Template<Class const &> &))));
+ QVERIFY(object.connect(&object,
+ SIGNAL(typeConstRefSignal(const Template<const Class &> &)),
+ SLOT(typeConstRefSlot(Template<Class const &> const &))));
+ QVERIFY(object.connect(&object,
+ SIGNAL(typeConstRefSignal(Template<const Class &> const &)),
+ SLOT(typeConstRefSlot(Template<Class const &> const &))));
+ QVERIFY(object.connect(&object,
+ SIGNAL(typeConstRefSignal(Template<Class const &> const &)),
+ SLOT(typeConstRefSlot(Template<Class const &> 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<const Class &> &)),
+ SLOT(constTypeRefSlot(const Template<const Class &> &))));
+ QVERIFY(oldobject.connect(&oldobject,
+ SIGNAL(constTypeRefSignal(const Template<const Class &> &)),
+ SLOT(constTypeRefSlot(const Template<Class const &> &))));
+ // this fails in older versions, but passes now due to proper normalizing
+ QVERIFY(oldobject.connect(&oldobject,
+ SIGNAL(constTypeRefSignal(const Template<const Class &> &)),
+ SLOT(constTypeRefSlot(Template<Class const &> const &))));
+ // this fails in older versions, but passes now due to proper normalizing
+ QVERIFY(oldobject.connect(&oldobject,
+ SIGNAL(constTypeRefSignal(Template<const Class &> const &)),
+ SLOT(constTypeRefSlot(Template<Class const &> const &))));
+ // this fails in older versions, but passes now due to proper normalizing
+ QVERIFY(oldobject.connect(&oldobject,
+ SIGNAL(constTypeRefSignal(Template<Class const &> const &)),
+ SLOT(constTypeRefSlot(Template<Class const &> const &))));
+
+ // these fail in older Qt versions, but pass now due to proper normalizing
+ QVERIFY(oldobject.connect(&oldobject,
+ SIGNAL(constTypeRefSignal(const Template<const Class &> &)),
+ SLOT(typeConstRefSlot(const Template<const Class &> &))));
+ QVERIFY(oldobject.connect(&oldobject,
+ SIGNAL(constTypeRefSignal(const Template<const Class &> &)),
+ SLOT(typeConstRefSlot(const Template<Class const &> &))));
+ QVERIFY(oldobject.connect(&oldobject,
+ SIGNAL(constTypeRefSignal(const Template<const Class &> &)),
+ SLOT(typeConstRefSlot(Template<Class const &> const &))));
+ QVERIFY(oldobject.connect(&oldobject,
+ SIGNAL(constTypeRefSignal(Template<const Class &> const &)),
+ SLOT(typeConstRefSlot(Template<Class const &> const &))));
+ QVERIFY(oldobject.connect(&oldobject,
+ SIGNAL(constTypeRefSignal(Template<Class const &> const &)),
+ SLOT(typeConstRefSlot(Template<Class const &> const &))));
+
+ // these also fail in older Qt versions, but pass now due to proper normalizing
+ QVERIFY(oldobject.connect(&oldobject,
+ SIGNAL(typeConstRefSignal(const Template<const Class &> &)),
+ SLOT(constTypeRefSlot(const Template<const Class &> &))));
+ QVERIFY(oldobject.connect(&oldobject,
+ SIGNAL(typeConstRefSignal(const Template<const Class &> &)),
+ SLOT(constTypeRefSlot(const Template<Class const &> &))));
+ QVERIFY(oldobject.connect(&oldobject,
+ SIGNAL(typeConstRefSignal(const Template<const Class &> &)),
+ SLOT(constTypeRefSlot(Template<Class const &> const &))));
+ QVERIFY(oldobject.connect(&oldobject,
+ SIGNAL(typeConstRefSignal(Template<const Class &> const &)),
+ SLOT(constTypeRefSlot(Template<Class const &> const &))));
+ QVERIFY(oldobject.connect(&oldobject,
+ SIGNAL(typeConstRefSignal(Template<Class const &> const &)),
+ SLOT(constTypeRefSlot(Template<Class const &> const &))));
+
+ // this fails in older versions, but passes now due to proper normalizing
+ QVERIFY(oldobject.connect(&oldobject,
+ SIGNAL(typeConstRefSignal(const Template<const Class &> &)),
+ SLOT(typeConstRefSlot(const Template<const Class &> &))));
+ // this fails in older versions, but passes now due to proper normalizing
+ QVERIFY(oldobject.connect(&oldobject,
+ SIGNAL(typeConstRefSignal(const Template<const Class &> &)),
+ SLOT(typeConstRefSlot(const Template<Class const &> &))));
+ // this fails in older versions, but passes now due to proper normalizing
+ QVERIFY(oldobject.connect(&oldobject,
+ SIGNAL(typeConstRefSignal(const Template<const Class &> &)),
+ SLOT(typeConstRefSlot(Template<Class const &> const &))));
+ QVERIFY(oldobject.connect(&oldobject,
+ SIGNAL(typeConstRefSignal(Template<const Class &> const &)),
+ SLOT(typeConstRefSlot(Template<Class const &> const &))));
+ QVERIFY(oldobject.connect(&oldobject,
+ SIGNAL(typeConstRefSignal(Template<Class const &> const &)),
+ SLOT(typeConstRefSlot(Template<Class const &> 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