From 709648993c1ea5f6b46ebe8bfd0f27d75c9b4e95 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Wed, 29 Apr 2020 11:53:18 +0200 Subject: [PATCH] Fix crash when using QProperty::setBinding(Functor ...) We must move the functor properly into the binding object, otherwise we end up with stale pointers as pointed out by ASAN. Change-Id: Icd84f4c113dd48e1e3e2d744abac0902cdf9339e Reviewed-by: Fabian Kosmale --- src/corelib/kernel/qproperty.h | 7 ++++--- .../auto/corelib/kernel/qproperty/tst_qproperty.cpp | 12 ++++++++++++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/corelib/kernel/qproperty.h b/src/corelib/kernel/qproperty.h index 24aa1804f28..22313bc92e0 100644 --- a/src/corelib/kernel/qproperty.h +++ b/src/corelib/kernel/qproperty.h @@ -316,10 +316,11 @@ public: #ifndef Q_CLANG_QDOC template - QPropertyBinding setBinding(Functor f, - const QPropertyBindingSourceLocation &location = QT_PROPERTY_DEFAULT_BINDING_LOCATION) + QPropertyBinding setBinding(Functor &&f, + const QPropertyBindingSourceLocation &location = QT_PROPERTY_DEFAULT_BINDING_LOCATION, + std::enable_if_t> * = nullptr) { - return setBinding(Qt::makePropertyBinding(f, location)); + return setBinding(Qt::makePropertyBinding(std::forward(f), location)); } #else template diff --git a/tests/auto/corelib/kernel/qproperty/tst_qproperty.cpp b/tests/auto/corelib/kernel/qproperty/tst_qproperty.cpp index 488ecacb8d5..88942609884 100644 --- a/tests/auto/corelib/kernel/qproperty/tst_qproperty.cpp +++ b/tests/auto/corelib/kernel/qproperty/tst_qproperty.cpp @@ -68,6 +68,7 @@ private slots: void genericPropertyBinding(); void genericPropertyBindingBool(); void staticChangeHandler(); + void setBindingFunctor(); }; void tst_QProperty::functorBinding() @@ -674,6 +675,17 @@ void tst_QProperty::staticChangeHandler() QCOMPARE(t.observedValues, values); } +void tst_QProperty::setBindingFunctor() +{ + QProperty property; + QProperty injectedValue(100); + // Make sure that this picks the setBinding overload that takes a functor and + // moves it correctly. + property.setBinding([&injectedValue]() { return injectedValue.value(); }); + injectedValue = 200; + QCOMPARE(property.value(), 200); +} + QTEST_MAIN(tst_QProperty); #include "tst_qproperty.moc"