Initialize the return value of signals

Before, the constructor was called for complex objects, but
POD were left unitinialized. Now, they are zero-initialized.

Also add test for return values

Change-Id: Iff9bf6687589d7b7395a71fb6f650ab8aa2b6bd1
Reviewed-by: Bradley T. Hughes <bradley.hughes@nokia.com>
This commit is contained in:
Olivier Goffart 2011-11-09 00:11:30 +01:00 committed by Qt by Nokia
parent ed0b262de9
commit 1c5db1aff3
2 changed files with 237 additions and 1 deletions

View File

@ -1051,7 +1051,7 @@ void Generator::generateSignal(FunctionDef *def,int index)
} }
fprintf(out, ")%s\n{\n", constQualifier); fprintf(out, ")%s\n{\n", constQualifier);
if (def->type.name.size() && def->normalizedType.size()) if (def->type.name.size() && def->normalizedType.size())
fprintf(out, " %s _t0;\n", noRef(def->normalizedType).constData()); fprintf(out, " %s _t0 = %s();\n", noRef(def->normalizedType).constData(), noRef(def->normalizedType).constData());
fprintf(out, " void *_a[] = { "); fprintf(out, " void *_a[] = { ");
if (def->normalizedType.isEmpty()) { if (def->normalizedType.isEmpty()) {

View File

@ -131,6 +131,10 @@ private slots:
void connectConvert(); void connectConvert();
void connectWithReference(); void connectWithReference();
void connectManyArguments(); void connectManyArguments();
void returnValue_data();
void returnValue();
void returnValue2_data();
void returnValue2();
}; };
class SenderObject : public QObject class SenderObject : public QObject
@ -4775,6 +4779,238 @@ void tst_QObject::connectManyArguments()
#endif #endif
} }
class ReturnValue : public QObject {
friend class tst_QObject;
Q_OBJECT
signals:
QVariant returnVariant(int);
QString returnString(int);
int returnInt(int);
void returnVoid(int);
CustomType returnCustomType(int);
public slots:
QVariant returnVariantSlot(int i) { return i; }
QString returnStringSlot(int i) { return QString::number(i); }
int returnIntSlot(int i) { return i; }
CustomType returnCustomTypeSlot(int i) { return CustomType(i); }
void returnVoidSlot() {}
int return23() { return 23; }
QString returnHello() { return QStringLiteral("hello"); }
public:
struct VariantFunctor {
QVariant operator()(int i) { return i; }
};
struct CustomTypeFunctor {
CustomType operator()(int i) { return CustomType(i); }
};
struct StringFunctor {
QString operator()(int i) { return QString::number(i); }
};
struct IntFunctor {
int operator()(int i) { return i; }
};
struct VoidFunctor {
void operator()(int) {}
};
};
QString someFunctionReturningString(int i) {
return '\'' + QString::number(i) + '\'';
}
void tst_QObject::returnValue_data()
{
QTest::addColumn<bool>("isBlockingQueued");
QTest::newRow("DirectConnection") << false;
QTest::newRow("BlockingQueuedConnection") << true;
}
void tst_QObject::returnValue()
{
CheckInstanceCount checker;
QFETCH(bool, isBlockingQueued);
QThread thread;
ReturnValue receiver;
Qt::ConnectionType type = Qt::DirectConnection;
if (isBlockingQueued) {
thread.start();
receiver.moveToThread(&thread);
type = Qt::BlockingQueuedConnection;
}
{ // connected to nothing
CheckInstanceCount checker;
ReturnValue r;
QCOMPARE(emit r.returnVariant(45), QVariant());
QCOMPARE(emit r.returnString(45), QString());
QCOMPARE(emit r.returnInt(45), int());
emit r.returnVoid(45);
QCOMPARE((emit r.returnCustomType(45)).value(), CustomType().value());
}
{ // connected to a slot returning the same type
CheckInstanceCount checker;
ReturnValue r;
QVERIFY(connect(&r, &ReturnValue::returnVariant, &receiver, &ReturnValue::returnVariantSlot, type));
QCOMPARE(emit r.returnVariant(45), QVariant(45));
QVERIFY(connect(&r, &ReturnValue::returnString, &receiver, &ReturnValue::returnStringSlot, type));
QCOMPARE(emit r.returnString(45), QString::fromLatin1("45"));
QVERIFY(connect(&r, &ReturnValue::returnInt, &receiver, &ReturnValue::returnIntSlot, type));
QCOMPARE(emit r.returnInt(45), int(45));
QVERIFY(connect(&r, &ReturnValue::returnCustomType, &receiver, &ReturnValue::returnCustomTypeSlot, type));
QCOMPARE((emit r.returnCustomType(45)).value(), CustomType(45).value());
}
if (!isBlockingQueued) { // connected to simple functions or functor
CheckInstanceCount checker;
ReturnValue r;
QVERIFY(connect(&r, &ReturnValue::returnString, someFunctionReturningString));
QCOMPARE(emit r.returnString(49), QString::fromLatin1("'49'"));
ReturnValue::CustomTypeFunctor customTypeFunctor;
QVERIFY(connect(&r, &ReturnValue::returnCustomType, customTypeFunctor));
QCOMPARE((emit r.returnCustomType(49)).value(), CustomType(49).value());
ReturnValue::VariantFunctor variantFunctor;
QVERIFY(connect(&r, &ReturnValue::returnVariant, variantFunctor));
QCOMPARE(emit r.returnVariant(45), QVariant(45));
ReturnValue::IntFunctor intFunctor;
QVERIFY(connect(&r, &ReturnValue::returnInt, intFunctor));
QCOMPARE(emit r.returnInt(45), int(45));
}
{ // connected to a slot with different type
CheckInstanceCount checker;
ReturnValue r;
QVERIFY(connect(&r, &ReturnValue::returnVariant, &receiver, &ReturnValue::returnStringSlot, type));
QCOMPARE(emit r.returnVariant(48), QVariant(QString::fromLatin1("48")));
QVERIFY(connect(&r, &ReturnValue::returnCustomType, &receiver, &ReturnValue::returnIntSlot, type));
QCOMPARE((emit r.returnCustomType(48)).value(), CustomType(48).value());
QVERIFY(connect(&r, &ReturnValue::returnVoid, &receiver, &ReturnValue::returnCustomTypeSlot, type));
emit r.returnVoid(48);
}
if (!isBlockingQueued) { // connected to functor with different type
CheckInstanceCount checker;
ReturnValue r;
ReturnValue::CustomTypeFunctor customTypeFunctor;
QVERIFY(connect(&r, &ReturnValue::returnCustomType, customTypeFunctor));
QCOMPARE((emit r.returnCustomType(49)).value(), CustomType(49).value());
ReturnValue::StringFunctor stringFunctor;
QVERIFY(connect(&r, &ReturnValue::returnVariant, stringFunctor));
QCOMPARE(emit r.returnVariant(45), QVariant(QString::fromLatin1("45")));
}
{ // connected to a void
CheckInstanceCount checker;
ReturnValue r;
QVERIFY(connect(&r, &ReturnValue::returnVariant, &receiver, &ReturnValue::returnVoidSlot, type));
QCOMPARE(emit r.returnVariant(45), QVariant());
QVERIFY(connect(&r, &ReturnValue::returnString, &receiver, &ReturnValue::returnVoidSlot, type));
QCOMPARE(emit r.returnString(45), QString());
QVERIFY(connect(&r, &ReturnValue::returnInt, &receiver, &ReturnValue::returnVoidSlot, type));
QCOMPARE(emit r.returnInt(45), int());
QVERIFY(connect(&r, &ReturnValue::returnCustomType, &receiver, &ReturnValue::returnVoidSlot, type));
QCOMPARE((emit r.returnCustomType(45)).value(), CustomType().value());
}
{ // connected to many slots
ReturnValue::VoidFunctor voidFunctor;
ReturnValue::IntFunctor intFunctor;
ReturnValue r;
QVERIFY(connect(&r, &ReturnValue::returnVariant, &receiver, &ReturnValue::returnVariantSlot, type));
QCOMPARE(emit r.returnVariant(45), QVariant(45));
QVERIFY(connect(&r, &ReturnValue::returnVariant, &receiver, &ReturnValue::return23, type));
QCOMPARE(emit r.returnVariant(45), QVariant(23));
QVERIFY(connect(&r, &ReturnValue::returnVariant, &receiver, &ReturnValue::returnVoidSlot, type));
QCOMPARE(emit r.returnVariant(45), QVariant(23));
QVERIFY(connect(&r, &ReturnValue::returnVariant, &receiver, &ReturnValue::returnHello, type));
QCOMPARE(emit r.returnVariant(45), QVariant(QStringLiteral("hello")));
QVERIFY(connect(&r, &ReturnValue::returnVariant, voidFunctor));
QCOMPARE(emit r.returnVariant(45), QVariant(QStringLiteral("hello")));
QVERIFY(connect(&r, &ReturnValue::returnVariant, intFunctor));
QCOMPARE(emit r.returnVariant(45), QVariant(45));
QCOMPARE(emit r.returnInt(45), int());
QVERIFY(connect(&r, &ReturnValue::returnInt, &receiver, &ReturnValue::returnVoidSlot, type));
QCOMPARE(emit r.returnInt(45), int());
QVERIFY(connect(&r, &ReturnValue::returnInt, &receiver, &ReturnValue::returnIntSlot, type));
QCOMPARE(emit r.returnInt(45), int(45));
QVERIFY(connect(&r, &ReturnValue::returnInt, &receiver, &ReturnValue::return23, type));
QCOMPARE(emit r.returnInt(45), int(23));
QVERIFY(connect(&r, &ReturnValue::returnInt, voidFunctor));
QCOMPARE(emit r.returnInt(45), int(23));
QVERIFY(connect(&r, &ReturnValue::returnInt, intFunctor));
QCOMPARE(emit r.returnInt(45), int(45));
}
if (isBlockingQueued) {
thread.quit();
thread.wait();
}
}
void tst_QObject::returnValue2_data()
{ returnValue_data(); }
//String based syntax
void tst_QObject::returnValue2()
{
CheckInstanceCount checker;
QFETCH(bool, isBlockingQueued);
QThread thread;
ReturnValue receiver;
Qt::ConnectionType type = Qt::DirectConnection;
if (isBlockingQueued) {
thread.start();
receiver.moveToThread(&thread);
type = Qt::BlockingQueuedConnection;
}
{ // connected to a simple slot
CheckInstanceCount checker;
ReturnValue r;
QVERIFY(connect(&r, SIGNAL(returnVariant(int)), &receiver, SLOT(returnVariantSlot(int)), type));
QCOMPARE(emit r.returnVariant(45), QVariant(45));
QVERIFY(connect(&r, SIGNAL(returnString(int)), &receiver, SLOT(returnStringSlot(int)), type));
QCOMPARE(emit r.returnString(45), QString(QStringLiteral("45")));
QVERIFY(connect(&r, SIGNAL(returnInt(int)), &receiver, SLOT(returnIntSlot(int)), type));
QCOMPARE(emit r.returnInt(45), int(45));
QVERIFY(connect(&r, SIGNAL(returnCustomType(int)), &receiver, SLOT(returnCustomTypeSlot(int)), type));
QCOMPARE((emit r.returnCustomType(45)).value(), CustomType(45).value());
}
{ // connected to a slot returning void
CheckInstanceCount checker;
ReturnValue r;
QVERIFY(connect(&r, SIGNAL(returnVariant(int)), &receiver, SLOT(returnVoidSlot()), type));
QCOMPARE(emit r.returnVariant(45), QVariant());
QVERIFY(connect(&r, SIGNAL(returnString(int)), &receiver, SLOT(returnVoidSlot()), type));
QCOMPARE(emit r.returnString(45), QString());
QVERIFY(connect(&r, SIGNAL(returnInt(int)), &receiver, SLOT(returnVoidSlot()), type));
QCOMPARE(emit r.returnInt(45), int());
QVERIFY(connect(&r, SIGNAL(returnCustomType(int)), &receiver, SLOT(returnVoidSlot()), type));
QCOMPARE((emit r.returnCustomType(45)).value(), CustomType().value());
}
{ // connected to many slots
ReturnValue r;
QVERIFY(connect(&r, SIGNAL(returnInt(int)), &receiver, SLOT(returnIntSlot(int)), type));
QCOMPARE(emit r.returnInt(45), int(45));
QVERIFY(connect(&r, SIGNAL(returnInt(int)), &receiver, SLOT(returnVoidSlot()), type));
QCOMPARE(emit r.returnInt(45), int(45));
QVERIFY(connect(&r, SIGNAL(returnInt(int)), &receiver, SLOT(return23()), type));
QCOMPARE(emit r.returnInt(45), int(23));
QVERIFY(connect(&r, SIGNAL(returnString(int)), &receiver, SLOT(returnStringSlot(int)), type));
QCOMPARE(emit r.returnString(45), QString(QStringLiteral("45")));
QVERIFY(connect(&r, SIGNAL(returnString(int)), &receiver, SLOT(returnVoidSlot()), type));
QCOMPARE(emit r.returnString(45), QString(QStringLiteral("45")));
QVERIFY(connect(&r, SIGNAL(returnString(int)), &receiver, SLOT(returnHello()), type));
QCOMPARE(emit r.returnString(45), QString(QStringLiteral("hello")));
}
if (isBlockingQueued) {
thread.quit();
thread.wait();
}
}
QTEST_MAIN(tst_QObject) QTEST_MAIN(tst_QObject)