Use std::addressof for taking an address instead of operator& in moc

Moc shouldn't artificially introduce calls to possibly overloaded
operator&. It can cause odd side effects in a user code.

Change-Id: Iaa1b491fe6a1a5ebd4dfa1172359dc792cc7604f
Fixes: QTBUG-68191
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Jędrzej Nowacki 2018-09-24 11:28:46 +02:00
parent b9ce354fb0
commit 5b99f3a34f
3 changed files with 34 additions and 5 deletions

View File

@ -1549,16 +1549,16 @@ void Generator::generateSignal(FunctionDef *def,int index)
fprintf(out, "nullptr");
} else {
if (def->returnTypeIsVolatile)
fprintf(out, "const_cast<void*>(reinterpret_cast<const volatile void*>(&_t0))");
fprintf(out, "const_cast<void*>(reinterpret_cast<const volatile void*>(std::addressof(_t0)))");
else
fprintf(out, "const_cast<void*>(reinterpret_cast<const void*>(&_t0))");
fprintf(out, "const_cast<void*>(reinterpret_cast<const void*>(std::addressof(_t0)))");
}
int i;
for (i = 1; i < offset; ++i)
if (i <= def->arguments.count() && def->arguments.at(i - 1).type.isVolatile)
fprintf(out, ", const_cast<void*>(reinterpret_cast<const volatile void*>(&_t%d))", i);
fprintf(out, ", const_cast<void*>(reinterpret_cast<const volatile void*>(std::addressof(_t%d)))", i);
else
fprintf(out, ", const_cast<void*>(reinterpret_cast<const void*>(&_t%d))", i);
fprintf(out, ", const_cast<void*>(reinterpret_cast<const void*>(std::addressof(_t%d)))", i);
fprintf(out, " };\n");
fprintf(out, " QMetaObject::activate(%s, &staticMetaObject, %d, _a);\n", thisPtr.constData(), index);
if (def->normalizedType != "void")

View File

@ -992,7 +992,7 @@ void Moc::generate(FILE *out)
fprintf(out, "** WARNING! All changes made in this file will be lost!\n"
"*****************************************************************************/\n\n");
fprintf(out, "#include <memory>\n"); // For std::addressof
if (!noInclude) {
if (includePath.size() && !includePath.endsWith('/'))
includePath += '/';

View File

@ -682,6 +682,7 @@ private slots:
void finalClasses();
void explicitOverrideControl_data();
void explicitOverrideControl();
void overloadedAddressOperator();
void autoPropertyMetaTypeRegistration();
void autoMethodArgumentMetaTypeRegistration();
void autoSignalSpyMetaTypeRegistration();
@ -2939,6 +2940,34 @@ void tst_Moc::explicitOverrideControl()
#endif
}
class OverloadedAddressOperator : public QObject
{
Q_OBJECT
public:
void* operator&() { return nullptr; }
signals:
void self(OverloadedAddressOperator&);
public slots:
void assertSelf(OverloadedAddressOperator &o)
{
QCOMPARE(std::addressof(o), this);
testResult = (std::addressof(o) == this);
}
public:
bool testResult = false;
};
void tst_Moc::overloadedAddressOperator()
{
OverloadedAddressOperator o;
OverloadedAddressOperator *p = std::addressof(o);
QCOMPARE(&o, nullptr);
QVERIFY(p);
QObject::connect(p, &OverloadedAddressOperator::self, p, &OverloadedAddressOperator::assertSelf);
emit o.self(o);
QVERIFY(o.testResult);
}
class CustomQObject : public QObject
{
Q_OBJECT