From bd1023a824efeafbd48c79d4dfbdd5f017044ceb Mon Sep 17 00:00:00 2001 From: Sona Kurazyan Date: Wed, 18 May 2022 17:28:12 +0200 Subject: 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 Reviewed-by: Marc Mutz --- src/concurrent/qtconcurrentfilter.h | 48 ++++++++++++++++++--------- src/concurrent/qtconcurrentfunctionwrappers.h | 14 ++++---- src/concurrent/qtconcurrentmap.h | 48 ++++++++++++++++++--------- src/concurrent/qtconcurrentreducekernel.h | 12 ++++++- 4 files changed, 81 insertions(+), 41 deletions(-) (limited to 'src/concurrent') diff --git a/src/concurrent/qtconcurrentfilter.h b/src/concurrent/qtconcurrentfilter.h index 86e9a531d2..e35c445b94 100644 --- a/src/concurrent/qtconcurrentfilter.h +++ b/src/concurrent/qtconcurrentfilter.h @@ -73,7 +73,8 @@ template , int> = 0> + std::enable_if_t, + int> = 0> #endif QFuture filteredReduced(QThreadPool *pool, Sequence &&sequence, @@ -95,7 +96,8 @@ template , int> = 0> + std::enable_if_t, + int> = 0> #endif QFuture filteredReduced(Sequence &&sequence, KeepFunctor &&keep, @@ -144,7 +146,8 @@ template ::value, int> = 0, typename ResultType = typename QtPrivate::ReduceResultTypeHelper::type, - std::enable_if_t, int> = 0> + std::enable_if_t, + int> = 0> QFuture filteredReduced(QThreadPool *pool, Sequence &&sequence, KeepFunctor &&keep, @@ -163,7 +166,8 @@ template ::value, int> = 0, typename ResultType = typename QtPrivate::ReduceResultTypeHelper::type, - std::enable_if_t, int> = 0> + std::enable_if_t, + int> = 0> QFuture filteredReduced(Sequence &&sequence, KeepFunctor &&keep, ReduceFunctor &&reduce, @@ -211,7 +215,8 @@ template , int> = 0> + std::enable_if_t, + int> = 0> #endif QFuture filteredReduced(QThreadPool *pool, Iterator begin, @@ -233,7 +238,8 @@ template , int> = 0> + std::enable_if_t, + int> = 0> #endif QFuture filteredReduced(Iterator begin, Iterator end, @@ -281,7 +287,8 @@ QFuture filteredReduced(Iterator begin, template ::type, typename InitialValueType, - std::enable_if_t, int> = 0> + std::enable_if_t, + int> = 0> QFuture filteredReduced(QThreadPool *pool, Iterator begin, Iterator end, @@ -300,7 +307,8 @@ template , int> = 0, typename ResultType = typename QtPrivate::ReduceResultTypeHelper::type, typename InitialValueType, - std::enable_if_t, int> = 0> + std::enable_if_t, + int> = 0> QFuture filteredReduced(Iterator begin, Iterator end, KeepFunctor &&keep, @@ -400,7 +408,8 @@ template , int> = 0> + std::enable_if_t, + int> = 0> #endif ResultType blockingFilteredReduced(QThreadPool *pool, Sequence &&sequence, @@ -423,7 +432,8 @@ template , int> = 0> + std::enable_if_t, + int> = 0> #endif ResultType blockingFilteredReduced(Sequence &&sequence, KeepFunctor &&keep, @@ -475,7 +485,8 @@ template ::value, int> = 0, typename ResultType = typename QtPrivate::ReduceResultTypeHelper::type, - std::enable_if_t, int> = 0> + std::enable_if_t, + int> = 0> ResultType blockingFilteredReduced(QThreadPool *pool, Sequence &&sequence, KeepFunctor &&keep, @@ -495,7 +506,8 @@ template ::value, int> = 0, typename ResultType = typename QtPrivate::ReduceResultTypeHelper::type, - std::enable_if_t, int> = 0> + std::enable_if_t, + int> = 0> ResultType blockingFilteredReduced(Sequence &&sequence, KeepFunctor &&keep, ReduceFunctor &&reduce, @@ -547,7 +559,8 @@ template , int> = 0> + std::enable_if_t, + int> = 0> #endif ResultType blockingFilteredReduced(QThreadPool *pool, Iterator begin, @@ -570,7 +583,8 @@ template , int> = 0> + std::enable_if_t, + int> = 0> #endif ResultType blockingFilteredReduced(Iterator begin, Iterator end, @@ -621,7 +635,8 @@ ResultType blockingFilteredReduced(Iterator begin, template ::type, typename InitialValueType, - std::enable_if_t, int> = 0> + std::enable_if_t, + int> = 0> ResultType blockingFilteredReduced(QThreadPool *pool, Iterator begin, Iterator end, KeepFunctor &&keep, @@ -640,7 +655,8 @@ template , int> = 0, typename ResultType = typename QtPrivate::ReduceResultTypeHelper::type, typename InitialValueType, - std::enable_if_t, int> = 0> + std::enable_if_t, + int> = 0> ResultType blockingFilteredReduced(Iterator begin, Iterator end, KeepFunctor &&keep, diff --git a/src/concurrent/qtconcurrentfunctionwrappers.h b/src/concurrent/qtconcurrentfunctionwrappers.h index b337b90e0a..4882ed8d89 100644 --- a/src/concurrent/qtconcurrentfunctionwrappers.h +++ b/src/concurrent/qtconcurrentfunctionwrappers.h @@ -5,6 +5,7 @@ #define QTCONCURRENT_FUNCTIONWRAPPERS_H #include +#include #include #include @@ -121,6 +122,11 @@ inline constexpr bool isIterator_v using isInvocable = std::is_invocable::value_type>; +template +inline constexpr bool isInitialValueCompatible_v = std::conjunction_v< + std::is_convertible, + std::negation, QtConcurrent::ReduceOption>>>; + template struct ReduceResultTypeHelper { @@ -163,14 +169,6 @@ struct MapSequenceResultType, MapFunctor> #endif // QT_NO_TEMPLATE_TEMPLATE_PARAMETER -template -struct SequenceHolder -{ - SequenceHolder(const Sequence &s) : sequence(s) { } - SequenceHolder(Sequence &&s) : sequence(std::move(s)) { } - Sequence sequence; -}; - } // namespace QtPrivate. diff --git a/src/concurrent/qtconcurrentmap.h b/src/concurrent/qtconcurrentmap.h index 3358d93a4e..2d829daca4 100644 --- a/src/concurrent/qtconcurrentmap.h +++ b/src/concurrent/qtconcurrentmap.h @@ -77,7 +77,8 @@ template , int> = 0> + std::enable_if_t, + int> = 0> #endif QFuture mappedReduced(QThreadPool *pool, Sequence &&sequence, @@ -98,7 +99,8 @@ template , int> = 0> + std::enable_if_t, + int> = 0> #endif QFuture mappedReduced(Sequence &&sequence, MapFunctor &&map, @@ -149,7 +151,8 @@ template ::value, int> = 0, typename ResultType = typename QtPrivate::ReduceResultTypeHelper::type, - std::enable_if_t, int> = 0> + std::enable_if_t, + int> = 0> #endif QFuture mappedReduced(QThreadPool *pool, Sequence &&sequence, @@ -172,7 +175,8 @@ template ::value, int> = 0, typename ResultType = typename QtPrivate::ReduceResultTypeHelper::type, - std::enable_if_t, int> = 0> + std::enable_if_t, + int> = 0> #endif QFuture mappedReduced(Sequence &&sequence, MapFunctor &&map, @@ -221,7 +225,8 @@ template , int> = 0> + std::enable_if_t, + int> = 0> #endif QFuture mappedReduced(QThreadPool *pool, Iterator begin, @@ -243,7 +248,8 @@ template , int> = 0> + std::enable_if_t, + int> = 0> #endif QFuture mappedReduced(Iterator begin, Iterator end, @@ -295,7 +301,8 @@ template ::type, typename InitialValueType, - std::enable_if_t, int> = 0> + std::enable_if_t, + int> = 0> #endif QFuture mappedReduced(QThreadPool *pool, Iterator begin, @@ -319,7 +326,8 @@ template, int> = 0, typename ResultType = typename QtPrivate::ReduceResultTypeHelper::type, typename InitialValueType, - std::enable_if_t, int> = 0> + std::enable_if_t, + int> = 0> #endif QFuture mappedReduced(Iterator begin, Iterator end, @@ -447,7 +455,8 @@ template , int> = 0> + std::enable_if_t, + int> = 0> #endif ResultType blockingMappedReduced(QThreadPool *pool, Sequence &&sequence, @@ -470,7 +479,8 @@ template , int> = 0> + std::enable_if_t, + int> = 0> #endif ResultType blockingMappedReduced(Sequence &&sequence, MapFunctor &&map, @@ -526,7 +536,8 @@ template ::value, int> = 0, typename ResultType = typename QtPrivate::ReduceResultTypeHelper::type, - std::enable_if_t, int> = 0> + std::enable_if_t, + int> = 0> #endif ResultType blockingMappedReduced(QThreadPool *pool, Sequence &&sequence, @@ -550,7 +561,8 @@ template ::value, int> = 0, typename ResultType = typename QtPrivate::ReduceResultTypeHelper::type, - std::enable_if_t, int> = 0> + std::enable_if_t, + int> = 0> #endif ResultType blockingMappedReduced(Sequence &&sequence, MapFunctor &&map, @@ -602,7 +614,8 @@ template , int> = 0> + std::enable_if_t, + int> = 0> #endif ResultType blockingMappedReduced(QThreadPool *pool, Iterator begin, @@ -626,7 +639,8 @@ template , int> = 0> + std::enable_if_t, + int> = 0> #endif ResultType blockingMappedReduced(Iterator begin, Iterator end, @@ -681,7 +695,8 @@ template ::type, typename InitialValueType, - std::enable_if_t, int> = 0> + std::enable_if_t, + int> = 0> #endif ResultType blockingMappedReduced(QThreadPool *pool, Iterator begin, @@ -706,7 +721,8 @@ template , int> = 0, typename ResultType = typename QtPrivate::ReduceResultTypeHelper::type, typename InitialValueType, - std::enable_if_t, int> = 0> + std::enable_if_t, + int> = 0> #endif ResultType blockingMappedReduced(Iterator begin, Iterator end, diff --git a/src/concurrent/qtconcurrentreducekernel.h b/src/concurrent/qtconcurrentreducekernel.h index 9ea0f33f91..a58739fc41 100644 --- a/src/concurrent/qtconcurrentreducekernel.h +++ b/src/concurrent/qtconcurrentreducekernel.h @@ -5,7 +5,6 @@ #define QTCONCURRENT_REDUCEKERNEL_H #include -#include #if !defined(QT_NO_CONCURRENT) || defined(Q_CLANG_QDOC) @@ -20,6 +19,17 @@ QT_BEGIN_NAMESPACE +namespace QtPrivate { + +template +struct SequenceHolder +{ + SequenceHolder(const Sequence &s) : sequence(s) { } + SequenceHolder(Sequence &&s) : sequence(std::move(s)) { } + Sequence sequence; +}; + +} namespace QtConcurrent { -- cgit v1.2.3