summaryrefslogtreecommitdiffstats
path: root/tests/auto/concurrent
diff options
context:
space:
mode:
authorSona Kurazyan <sona.kurazyan@qt.io>2022-05-18 17:28:12 +0200
committerSona Kurazyan <sona.kurazyan@qt.io>2022-05-20 17:11:15 +0200
commitbd1023a824efeafbd48c79d4dfbdd5f017044ceb (patch)
tree49d7fb8e5e853f2fa6db5a8f066c3e285caf3bc7 /tests/auto/concurrent
parentfa01e0bd71b42f0887790598106893c558557b60 (diff)
QtConcurrent: prevent conversion of ReduceOption to initial value
QtConcurrent map- and filter-reduce functions take an initial value, which can be of any type that is convertable to the result type. The side-effect of this is that the enum values passed as ReduceOptions can be treated as an initial value (if they are convertable to the result type) which will result into a wrong overload call. To avoid this, added additional check to make sure that the initial value type doesn't match with ReduceOption enum. Note that this required including the qtconcurrentreducekernel.h header in qtconcurrentfunctionwrappers.h (which contains compiler checks for QtConcurrent) for accessing ReduceOption enum, so I had to get rid of qtconcurrentfunctionwrappers.h include from qtconcurrentreducekernel.h to avoid circular header includes. This, in turn, required moving the QtPrivate::SequenceHolder helper type to qtconcurrentreducekernel.h, which didn't belong to qtconcurrentfunctionwrappers.h anyway. Pick-to: 6.3 6.2 Fixes: QTBUG-102999 Change-Id: Ieaa8ef2e4bd82ce2ada2e0af9a47b87b51d59e87 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Marc Mutz <marc.mutz@qt.io>
Diffstat (limited to 'tests/auto/concurrent')
-rw-r--r--tests/auto/concurrent/qtconcurrentfilter/tst_qtconcurrentfilter.cpp51
-rw-r--r--tests/auto/concurrent/qtconcurrentmap/tst_qtconcurrentmap.cpp46
2 files changed, 97 insertions, 0 deletions
diff --git a/tests/auto/concurrent/qtconcurrentfilter/tst_qtconcurrentfilter.cpp b/tests/auto/concurrent/qtconcurrentfilter/tst_qtconcurrentfilter.cpp
index 85eb8c8259..50819a3742 100644
--- a/tests/auto/concurrent/qtconcurrentfilter/tst_qtconcurrentfilter.cpp
+++ b/tests/auto/concurrent/qtconcurrentfilter/tst_qtconcurrentfilter.cpp
@@ -27,6 +27,7 @@ private slots:
void filteredReducedInitialValueThreadPool();
void filteredReducedInitialValueWithMoveOnlyCallables();
void filteredReducedDifferentTypeInitialValue();
+ void filteredReduceOptionConvertableToResultType();
void resultAt();
void incrementalResults();
void noDetach();
@@ -1338,6 +1339,56 @@ void tst_QtConcurrentFilter::filteredReducedDifferentTypeInitialValue()
CHECK_FAIL("lambda-lambda");
}
+void tst_QtConcurrentFilter::filteredReduceOptionConvertableToResultType()
+{
+ const QList<int> intList { 1, 2, 3 };
+ const int sum = 4;
+ QThreadPool p;
+ ReduceOption ro = OrderedReduce;
+
+ // With container
+ QCOMPARE(QtConcurrent::filteredReduced(intList, keepOddIntegers, intSumReduce, ro).result(),
+ sum);
+ QCOMPARE(QtConcurrent::blockingFilteredReduced(intList, keepOddIntegers, intSumReduce, ro),
+ sum);
+
+ // With iterators
+ QCOMPARE(QtConcurrent::filteredReduced(intList.begin(), intList.end(), keepOddIntegers,
+ intSumReduce, ro).result(), sum);
+ QCOMPARE(QtConcurrent::blockingFilteredReduced(intList.begin(), intList.end(), keepOddIntegers,
+ intSumReduce, ro), sum);
+
+ // With custom QThreadPool;
+ QCOMPARE(QtConcurrent::filteredReduced(&p, intList, keepOddIntegers, intSumReduce, ro).result(),
+ sum);
+ QCOMPARE(QtConcurrent::blockingFilteredReduced(&p, intList, keepOddIntegers, intSumReduce, ro),
+ sum);
+ QCOMPARE(QtConcurrent::filteredReduced(&p, intList.begin(), intList.end(), keepOddIntegers,
+ intSumReduce, ro).result(), sum);
+ QCOMPARE(QtConcurrent::blockingFilteredReduced(&p, intList.begin(), intList.end(),
+ keepOddIntegers, intSumReduce, ro), sum);
+
+ // The same as above, but specify the result type explicitly (this invokes different overloads)
+ QCOMPARE(QtConcurrent::filteredReduced<int>(intList, keepOddIntegers, intSumReduce,
+ ro).result(), sum);
+ QCOMPARE(QtConcurrent::blockingFilteredReduced<int>(intList, keepOddIntegers, intSumReduce, ro),
+ sum);
+
+ QCOMPARE(QtConcurrent::filteredReduced<int>(intList.begin(), intList.end(), keepOddIntegers,
+ intSumReduce, ro).result(), sum);
+ QCOMPARE(QtConcurrent::blockingFilteredReduced<int>(intList.begin(), intList.end(),
+ keepOddIntegers, intSumReduce, ro), sum);
+
+ QCOMPARE(QtConcurrent::filteredReduced<int>(&p, intList, keepOddIntegers, intSumReduce,
+ ro).result(), sum);
+ QCOMPARE(QtConcurrent::blockingFilteredReduced<int>(&p, intList, keepOddIntegers, intSumReduce,
+ ro), sum);
+ QCOMPARE(QtConcurrent::filteredReduced<int>(&p, intList.begin(), intList.end(), keepOddIntegers,
+ intSumReduce, ro).result(),sum);
+ QCOMPARE(QtConcurrent::blockingFilteredReduced<int>(&p, intList.begin(), intList.end(),
+ keepOddIntegers, intSumReduce, ro), sum);
+}
+
bool filterfn(int i)
{
return (i % 2);
diff --git a/tests/auto/concurrent/qtconcurrentmap/tst_qtconcurrentmap.cpp b/tests/auto/concurrent/qtconcurrentmap/tst_qtconcurrentmap.cpp
index cdf046a524..a6c73777a1 100644
--- a/tests/auto/concurrent/qtconcurrentmap/tst_qtconcurrentmap.cpp
+++ b/tests/auto/concurrent/qtconcurrentmap/tst_qtconcurrentmap.cpp
@@ -30,6 +30,7 @@ private slots:
void mappedReducedInitialValueThreadPool();
void mappedReducedInitialValueWithMoveOnlyCallable();
void mappedReducedDifferentTypeInitialValue();
+ void mappedReduceOptionConvertableToResultType();
void assignResult();
void functionOverloads();
void noExceptFunctionOverloads();
@@ -1605,6 +1606,51 @@ void tst_QtConcurrentMap::mappedReducedDifferentTypeInitialValue()
CHECK_FAIL("lambda-lambda");
}
+void tst_QtConcurrentMap::mappedReduceOptionConvertableToResultType()
+{
+ const QList<int> intList { 1, 2, 3 };
+ const int sum = 12;
+ QThreadPool p;
+ ReduceOption ro = OrderedReduce;
+
+ // With container
+ QCOMPARE(QtConcurrent::mappedReduced(intList, multiplyBy2, intSumReduce, ro).result(), sum);
+ QCOMPARE(QtConcurrent::blockingMappedReduced(intList, multiplyBy2, intSumReduce, ro), sum);
+
+ // With iterators
+ QCOMPARE(QtConcurrent::mappedReduced(intList.begin(), intList.end(), multiplyBy2, intSumReduce,
+ ro).result(), sum);
+ QCOMPARE(QtConcurrent::blockingMappedReduced(intList.begin(), intList.end(), multiplyBy2,
+ intSumReduce, ro), sum);
+
+ // With custom QThreadPool;
+ QCOMPARE(QtConcurrent::mappedReduced(&p, intList, multiplyBy2, intSumReduce, ro).result(), sum);
+ QCOMPARE(QtConcurrent::blockingMappedReduced(&p, intList, multiplyBy2, intSumReduce, ro), sum);
+ QCOMPARE(QtConcurrent::mappedReduced(&p, intList.begin(), intList.end(), multiplyBy2,
+ intSumReduce, ro).result(), sum);
+ QCOMPARE(QtConcurrent::blockingMappedReduced(&p, intList.begin(), intList.end(), multiplyBy2,
+ intSumReduce, ro), sum);
+
+ // The same as above, but specify the result type explicitly (this invokes different overloads)
+ QCOMPARE(QtConcurrent::mappedReduced<int>(intList, multiplyBy2, intSumReduce, ro).result(),
+ sum);
+ QCOMPARE(QtConcurrent::blockingMappedReduced<int>(intList, multiplyBy2, intSumReduce, ro), sum);
+
+ QCOMPARE(QtConcurrent::mappedReduced<int>(intList.begin(), intList.end(), multiplyBy2,
+ intSumReduce, ro).result(), sum);
+ QCOMPARE(QtConcurrent::blockingMappedReduced<int>(intList.begin(), intList.end(), multiplyBy2,
+ intSumReduce, ro), sum);
+
+ QCOMPARE(QtConcurrent::mappedReduced<int>(&p, intList, multiplyBy2, intSumReduce, ro).result(),
+ sum);
+ QCOMPARE(QtConcurrent::blockingMappedReduced<int>(&p, intList, multiplyBy2, intSumReduce, ro),
+ sum);
+ QCOMPARE(QtConcurrent::mappedReduced<int>(&p, intList.begin(), intList.end(), multiplyBy2,
+ intSumReduce, ro).result(), sum);
+ QCOMPARE(QtConcurrent::blockingMappedReduced<int>(&p, intList.begin(), intList.end(),
+ multiplyBy2, intSumReduce, ro), sum);
+}
+
int sleeper(int val)
{
QTest::qSleep(100);