summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJędrzej Nowacki <jedrzej.nowacki@qt.io>2018-09-24 11:28:46 +0200
committerJędrzej Nowacki <jedrzej.nowacki@qt.io>2018-10-01 09:45:31 +0000
commit5b99f3a34fef527beb8767eb12657f81ee65b969 (patch)
tree3fd514bd1a10ee11a0d16ef9b541e6a2b14edb4d
parentb9ce354fb09bae11e04e1cb6b37e037a7c93b749 (diff)
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>
-rw-r--r--src/tools/moc/generator.cpp8
-rw-r--r--src/tools/moc/moc.cpp2
-rw-r--r--tests/auto/tools/moc/tst_moc.cpp29
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<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")
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 <memory>\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