QThread: fix UB (invalid enum value) on Private::Priority

The Unix code stores an additional flag, ThreadPriorityResetFlag, in
the Policy enum, but ubsan does not approve:

  qthread_unix.cpp:303:30: runtime error: load of value 2147483648, which is not a valid value for type 'Priority'
  qthread_unix.cpp:304:75: runtime error: load of value 2147483648, which is not a valid value for type 'Priority'

Fix by making the variable of std::underlying_type_t<Priority>.

The masking and unmasking code can now be simplified, too.

In the Windows version, replace some switch targets with equivalent
ones to keep -Wswitch-like warnings, though I hasten to note that both
switches use a default case, so have anyway implicitly disabled said
warning.

Pick-to: 6.3 6.2 5.15
Change-Id: Ie4ea7d05e2928d2755ad12d36535197f85493191
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
This commit is contained in:
Marc Mutz 2021-12-16 13:50:21 +01:00
parent c953e5c417
commit 591a35d6fd
3 changed files with 6 additions and 6 deletions

View File

@ -164,7 +164,7 @@ public:
int returnCode;
uint stackSize;
QThread::Priority priority;
std::underlying_type_t<QThread::Priority> priority;
#ifdef Q_OS_UNIX
QWaitCondition thread_done;

View File

@ -322,8 +322,8 @@ void *QThreadPrivate::start(void *arg)
QMutexLocker locker(&thr->d_func()->mutex);
// do we need to reset the thread priority?
if (qToUnderlying(thr->d_func()->priority) & ThreadPriorityResetFlag) {
thr->d_func()->setPriority(QThread::Priority(qToUnderlying(thr->d_func()->priority) & ~ThreadPriorityResetFlag));
if (thr->d_func()->priority & ThreadPriorityResetFlag) {
thr->d_func()->setPriority(QThread::Priority(thr->d_func()->priority & ~ThreadPriorityResetFlag));
}
// threadId is set in QThread::start()
@ -703,7 +703,7 @@ void QThread::start(Priority priority)
// could not set scheduling hints, fallback to inheriting them
// we'll try again from inside the thread
pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED);
d->priority = Priority(qToUnderlying(priority) | ThreadPriorityResetFlag);
d->priority = qToUnderlying(priority) | ThreadPriorityResetFlag;
}
break;
}

View File

@ -457,7 +457,7 @@ void QThread::start(Priority priority)
int prio;
d->priority = priority;
switch (d->priority) {
switch (priority) {
case IdlePriority:
prio = THREAD_PRIORITY_IDLE;
break;
@ -584,7 +584,7 @@ void QThreadPrivate::setPriority(QThread::Priority threadPriority)
int prio;
priority = threadPriority;
switch (priority) {
switch (threadPriority) {
case QThread::IdlePriority:
prio = THREAD_PRIORITY_IDLE;
break;