From 7c77013c7f6ec57cd1b1faf3b480c40a619067c8 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Sun, 22 Feb 2015 10:02:08 +0100 Subject: 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::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 --- src/corelib/kernel/qmetatype.h | 8 ++++---- tests/auto/corelib/kernel/qobject/tst_qobject.cpp | 21 ++++++++++++++++++++- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h index 2c2dbeef9d..55f8fc9b2c 100644 --- a/src/corelib/kernel/qmetatype.h +++ b/src/corelib/kernel/qmetatype.h @@ -1364,15 +1364,15 @@ namespace QtPrivate enum { Value = sizeof(checkType(static_cast(0))) == sizeof(void*) }; }; - char qt_getEnumMetaObject(...); - char qt_getEnumMetaObject(); // Workaround bugs in MSVC. + template char qt_getEnumMetaObject(const T&); template struct IsQEnumHelper { 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*. - // 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*) }; }; diff --git a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp index 94242607f0..263cc5a07a 100644 --- a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp +++ b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2015 The Qt Company Ltd. -** Copyright (C) 2013 Olivier Goffart +** Copyright (C) 2015 Olivier Goffart ** Contact: http://www.qt.io/licensing/ ** ** This file is part of the test suite of the Qt Toolkit. @@ -127,6 +127,7 @@ private slots: void connectConvert(); void connectWithReference(); void connectManyArguments(); + void connectForwardDeclare(); void returnValue_data(); void returnValue(); void returnValue2_data(); @@ -5208,6 +5209,24 @@ void tst_QObject::connectManyArguments() 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 { friend class tst_QObject; Q_OBJECT -- cgit v1.2.3