Fix source incompatibility while connecting signals with forward declared arguments
QObject::connect tries to determine if the arguments are registered metatypes. This used to work even for arguments that were forward declared. But now, the metatype system tries to call QtPrivate::IsQEnumHelper<T>::Value to know if it is registered. That fails on gcc if T is forward declared. Apparently gcc needs to know the full type of T to pass it in the ellipsis function, even within a sizeof expression. So change the ellipsis expression to a template one. Task-number: QTBUG-44496 Change-Id: I7fa07bd3cde470b134c2ec53b0d581333d16a6f1 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
parent
59c4024171
commit
7c77013c7f
@ -1364,15 +1364,15 @@ namespace QtPrivate
|
|||||||
enum { Value = sizeof(checkType(static_cast<T*>(0))) == sizeof(void*) };
|
enum { Value = sizeof(checkType(static_cast<T*>(0))) == sizeof(void*) };
|
||||||
};
|
};
|
||||||
|
|
||||||
char qt_getEnumMetaObject(...);
|
template<typename T> char qt_getEnumMetaObject(const T&);
|
||||||
char qt_getEnumMetaObject(); // Workaround bugs in MSVC.
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct IsQEnumHelper {
|
struct IsQEnumHelper {
|
||||||
static const T &declval();
|
static const T &declval();
|
||||||
// If the type was declared with Q_ENUM, the friend qt_getEnumMetaObject(T) declared in the
|
// If the type was declared with Q_ENUM, the friend qt_getEnumMetaObject() declared in the
|
||||||
// Q_ENUM macro will be chosen by ADL, and the return type will be QMetaObject*.
|
// Q_ENUM macro will be chosen by ADL, and the return type will be QMetaObject*.
|
||||||
// Otherwise the chosen overload will be qt_getEnumMetaObject(...) which returne 'char'
|
// Otherwise the chosen overload will be the catch all template function
|
||||||
|
// qt_getEnumMetaObject(T) which returns 'char'
|
||||||
enum { Value = sizeof(qt_getEnumMetaObject(declval())) == sizeof(QMetaObject*) };
|
enum { Value = sizeof(qt_getEnumMetaObject(declval())) == sizeof(QMetaObject*) };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
**
|
**
|
||||||
** Copyright (C) 2015 The Qt Company Ltd.
|
** Copyright (C) 2015 The Qt Company Ltd.
|
||||||
** Copyright (C) 2013 Olivier Goffart <ogoffart@woboq.com>
|
** Copyright (C) 2015 Olivier Goffart <ogoffart@woboq.com>
|
||||||
** Contact: http://www.qt.io/licensing/
|
** Contact: http://www.qt.io/licensing/
|
||||||
**
|
**
|
||||||
** This file is part of the test suite of the Qt Toolkit.
|
** This file is part of the test suite of the Qt Toolkit.
|
||||||
@ -127,6 +127,7 @@ private slots:
|
|||||||
void connectConvert();
|
void connectConvert();
|
||||||
void connectWithReference();
|
void connectWithReference();
|
||||||
void connectManyArguments();
|
void connectManyArguments();
|
||||||
|
void connectForwardDeclare();
|
||||||
void returnValue_data();
|
void returnValue_data();
|
||||||
void returnValue();
|
void returnValue();
|
||||||
void returnValue2_data();
|
void returnValue2_data();
|
||||||
@ -5208,6 +5209,24 @@ void tst_QObject::connectManyArguments()
|
|||||||
QCOMPARE(ManyArgumentNamespace::count, 12);
|
QCOMPARE(ManyArgumentNamespace::count, 12);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ForwardDeclared;
|
||||||
|
|
||||||
|
class ForwardDeclareArguments : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
signals:
|
||||||
|
void mySignal(const ForwardDeclared&);
|
||||||
|
public slots:
|
||||||
|
void mySlot(const ForwardDeclared&) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
void tst_QObject::connectForwardDeclare()
|
||||||
|
{
|
||||||
|
ForwardDeclareArguments ob;
|
||||||
|
// it should compile
|
||||||
|
QVERIFY(connect(&ob, &ForwardDeclareArguments::mySignal, &ob, &ForwardDeclareArguments::mySlot, Qt::QueuedConnection));
|
||||||
|
}
|
||||||
|
|
||||||
class ReturnValue : public QObject {
|
class ReturnValue : public QObject {
|
||||||
friend class tst_QObject;
|
friend class tst_QObject;
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
Loading…
x
Reference in New Issue
Block a user