QAtomicScopedValueRollback: fix UB (passing rel/acq_rel to std::atomic::load())
It's explicitly undefined behavior to pass release/acq_rel memory_order to load(), so don't. This is private API, so no ChangeLog needed. Reported-by: Fabian Kosmale <fabian.kosmale@qt.io> Task-number: QTBUG-115107 Pick-to: 6.5 Change-Id: Iee119303d790c31937238ef92d900a25020e9713 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> (cherry picked from commit 5797f29e8c249e13da6285ae9b2d50fff4ffb505) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
f0286b60ba
commit
401950a76f
@ -45,6 +45,24 @@ class QAtomicScopedValueRollback
|
|||||||
#if !defined(Q_CC_GNU_ONLY) || (Q_CC_GNU >= 900)
|
#if !defined(Q_CC_GNU_ONLY) || (Q_CC_GNU >= 900)
|
||||||
// NOLINTNEXTLINE(qt-use-unreachable-return): Triggers on Clang, breaking GCC 8
|
// NOLINTNEXTLINE(qt-use-unreachable-return): Triggers on Clang, breaking GCC 8
|
||||||
Q_UNREACHABLE();
|
Q_UNREACHABLE();
|
||||||
|
#endif
|
||||||
|
return std::memory_order_seq_cst;
|
||||||
|
}
|
||||||
|
|
||||||
|
static constexpr std::memory_order load_part(std::memory_order mo) noexcept
|
||||||
|
{
|
||||||
|
switch (mo) {
|
||||||
|
case std::memory_order_relaxed:
|
||||||
|
case std::memory_order_release: return std::memory_order_relaxed;
|
||||||
|
case std::memory_order_consume: return std::memory_order_consume;
|
||||||
|
case std::memory_order_acquire:
|
||||||
|
case std::memory_order_acq_rel: return std::memory_order_acquire;
|
||||||
|
case std::memory_order_seq_cst: return std::memory_order_seq_cst;
|
||||||
|
}
|
||||||
|
// GCC 8.x does not treat __builtin_unreachable() as constexpr
|
||||||
|
#if !defined(Q_CC_GNU_ONLY) || (Q_CC_GNU >= 900)
|
||||||
|
// NOLINTNEXTLINE(qt-use-unreachable-return): Triggers on Clang, breaking GCC 8
|
||||||
|
Q_UNREACHABLE();
|
||||||
#endif
|
#endif
|
||||||
return std::memory_order_seq_cst;
|
return std::memory_order_seq_cst;
|
||||||
}
|
}
|
||||||
@ -56,7 +74,7 @@ public:
|
|||||||
explicit constexpr
|
explicit constexpr
|
||||||
QAtomicScopedValueRollback(std::atomic<T> &var,
|
QAtomicScopedValueRollback(std::atomic<T> &var,
|
||||||
std::memory_order mo = std::memory_order_seq_cst)
|
std::memory_order mo = std::memory_order_seq_cst)
|
||||||
: m_atomic(var), m_value(var.load(mo)), m_mo(mo) {}
|
: m_atomic(var), m_value(var.load(load_part(mo))), m_mo(mo) {}
|
||||||
|
|
||||||
Q_NODISCARD_CTOR
|
Q_NODISCARD_CTOR
|
||||||
explicit constexpr
|
explicit constexpr
|
||||||
@ -104,7 +122,7 @@ public:
|
|||||||
|
|
||||||
constexpr void commit()
|
constexpr void commit()
|
||||||
{
|
{
|
||||||
m_value = m_atomic.load(m_mo);
|
m_value = m_atomic.load(load_part(m_mo));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user