QProperty: Work around constexpr issues on MSVC

MSVC complains about illegal uses of void, even though the code should
be guarded by an if constexpr statement.
 qproperty.h(85): error C2182: 'val': illegal use of type 'void'
 qproperty.h(92): error C2182: 'abstract declarator': illegal use of type 'void'

Avoid the issue by using a dedicated dummy type instead of void.

Fixes: QTBUG-100072
Task-number: QTQAINFRA-4242
Change-Id: Idc4886c26c3794e709eb762ba836139f720f8133
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
(cherry picked from commit 0842b01f0269cdd8099a5fbe849c5c2876a0d744)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Fabian Kosmale 2022-01-20 17:01:51 +01:00 committed by Qt Cherry-pick Bot
parent f2d1e1d41d
commit 60afb344ce

View File

@ -184,6 +184,12 @@ struct QPropertyProxyBindingData
namespace QtPrivate {
struct BindingEvaluationState;
/* used in BindingFunctionVTable::createFor; on all other compilers, void would work, but on
MSVC this causes C2182 when compiling in C++20 mode. As we only need to provide some default
value which gets ignored, we introduce this dummy type.
*/
struct MSVCWorkAround {};
struct BindingFunctionVTable
{
using CallFn = bool(*)(QMetaType, QUntypedPropertyData *, void *);
@ -194,7 +200,7 @@ struct BindingFunctionVTable
const MoveCtrFn moveConstruct;
const qsizetype size;
template<typename Callable, typename PropertyType=void>
template<typename Callable, typename PropertyType=MSVCWorkAround>
static constexpr BindingFunctionVTable createFor()
{
static_assert (alignof(Callable) <= alignof(std::max_align_t), "Bindings do not support overaligned functors!");
@ -205,7 +211,7 @@ struct BindingFunctionVTable
static_assert (std::is_invocable_r_v<bool, Callable, QMetaType, QUntypedPropertyData *> );
auto untypedEvaluationFunction = static_cast<Callable *>(f);
return std::invoke(*untypedEvaluationFunction, metaType, dataPtr);
} else if constexpr (!std::is_same_v<PropertyType, void>) { // check for void to workaround MSVC issue
} else if constexpr (!std::is_same_v<PropertyType, MSVCWorkAround>) {
Q_UNUSED(metaType);
QPropertyData<PropertyType> *propertyPtr = static_cast<QPropertyData<PropertyType> *>(dataPtr);
// That is allowed by POSIX even if Callable is a function pointer
@ -232,7 +238,7 @@ struct BindingFunctionVTable
}
};
template<typename Callable, typename PropertyType=void>
template<typename Callable, typename PropertyType=MSVCWorkAround>
inline constexpr BindingFunctionVTable bindingFunctionVTable = BindingFunctionVTable::createFor<Callable, PropertyType>();