From 5b99f3a34fef527beb8767eb12657f81ee65b969 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Nowacki?= Date: Mon, 24 Sep 2018 11:28:46 +0200 Subject: [PATCH] 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 --- src/tools/moc/generator.cpp | 8 ++++---- src/tools/moc/moc.cpp | 2 +- tests/auto/tools/moc/tst_moc.cpp | 29 +++++++++++++++++++++++++++++ 3 files changed, 34 insertions(+), 5 deletions(-) diff --git a/src/tools/moc/generator.cpp b/src/tools/moc/generator.cpp index 9fb980893f..c8882343f4 100644 --- a/src/tools/moc/generator.cpp +++ b/src/tools/moc/generator.cpp @@ -1549,16 +1549,16 @@ void Generator::generateSignal(FunctionDef *def,int index) fprintf(out, "nullptr"); } else { if (def->returnTypeIsVolatile) - fprintf(out, "const_cast(reinterpret_cast(&_t0))"); + fprintf(out, "const_cast(reinterpret_cast(std::addressof(_t0)))"); else - fprintf(out, "const_cast(reinterpret_cast(&_t0))"); + fprintf(out, "const_cast(reinterpret_cast(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(reinterpret_cast(&_t%d))", i); + fprintf(out, ", const_cast(reinterpret_cast(std::addressof(_t%d)))", i); else - fprintf(out, ", const_cast(reinterpret_cast(&_t%d))", i); + fprintf(out, ", const_cast(reinterpret_cast(std::addressof(_t%d)))", i); fprintf(out, " };\n"); fprintf(out, " QMetaObject::activate(%s, &staticMetaObject, %d, _a);\n", thisPtr.constData(), index); if (def->normalizedType != "void") diff --git a/src/tools/moc/moc.cpp b/src/tools/moc/moc.cpp index 61a5542c83..76816960ff 100644 --- a/src/tools/moc/moc.cpp +++ b/src/tools/moc/moc.cpp @@ -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 \n"); // For std::addressof if (!noInclude) { if (includePath.size() && !includePath.endsWith('/')) includePath += '/'; diff --git a/tests/auto/tools/moc/tst_moc.cpp b/tests/auto/tools/moc/tst_moc.cpp index 92a94055a4..f1888aebab 100644 --- a/tests/auto/tools/moc/tst_moc.cpp +++ b/tests/auto/tools/moc/tst_moc.cpp @@ -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