diff options
author | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2019-10-12 01:01:25 +0200 |
---|---|---|
committer | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2019-10-12 01:01:25 +0200 |
commit | 721a0e807881e4d00e752e3c3cf62427eb681dd2 (patch) | |
tree | 091100b37905e10fc3905d3e1665e1e849d59d72 /src/corelib/tools | |
parent | 50d41f14eecc32e374ca34f76d45d65684a640c8 (diff) | |
parent | 8aa3329a7186b087163f68ef880c8ffdd47d01bf (diff) |
Merge remote-tracking branch 'origin/5.15' into dev
Change-Id: I6ad865b2c26003f4508da9b3f8e075a951ff8ef7
Diffstat (limited to 'src/corelib/tools')
-rw-r--r-- | src/corelib/tools/qlist.cpp | 7 | ||||
-rw-r--r-- | src/corelib/tools/qlist.h | 18 | ||||
-rw-r--r-- | src/corelib/tools/qset.h | 70 | ||||
-rw-r--r-- | src/corelib/tools/qset.qdoc | 8 | ||||
-rw-r--r-- | src/corelib/tools/qsimd.cpp | 103 |
5 files changed, 132 insertions, 74 deletions
diff --git a/src/corelib/tools/qlist.cpp b/src/corelib/tools/qlist.cpp index dfebd57e34..3dc962236c 100644 --- a/src/corelib/tools/qlist.cpp +++ b/src/corelib/tools/qlist.cpp @@ -847,9 +847,10 @@ void **QListData::erase(void **xi) /*! \fn template <class T> void QList<T>::insert(int i, const T &value) - Inserts \a value at index position \a i in the list. If \a i <= 0, - the value is prepended to the list. If \a i >= size(), the - value is appended to the list. + Inserts \a value at index position \a i in the list. + + If \a i == 0, the value is prepended to the list. If \a i == size(), + the value is appended to the list. Example: \snippet code/src_corelib_tools_qlistdata.cpp 8 diff --git a/src/corelib/tools/qlist.h b/src/corelib/tools/qlist.h index 425ffa42a5..ffd470efcd 100644 --- a/src/corelib/tools/qlist.h +++ b/src/corelib/tools/qlist.h @@ -580,8 +580,16 @@ inline T &QList<T>::operator[](int i) detach(); return reinterpret_cast<Node *>(p.at(i))->t(); } template <typename T> inline void QList<T>::removeAt(int i) -{ if(i >= 0 && i < p.size()) { detach(); - node_destruct(reinterpret_cast<Node *>(p.at(i))); p.remove(i); } } +{ +#if !QT_DEPRECATED_SINCE(5, 15) + Q_ASSERT_X(i >= 0 && i < p.size(), "QList<T>::removeAt", "index out of range"); +#elif !defined(QT_NO_DEBUG) + if (i < 0 || i >= p.size()) + qWarning("QList::removeAt(): Index out of range."); +#endif + detach(); + node_destruct(reinterpret_cast<Node *>(p.at(i))); p.remove(i); +} template <typename T> inline T QList<T>::takeAt(int i) { Q_ASSERT_X(i >= 0 && i < p.size(), "QList<T>::take", "index out of range"); @@ -676,6 +684,12 @@ inline void QList<T>::prepend(const T &t) template <typename T> inline void QList<T>::insert(int i, const T &t) { +#if !QT_DEPRECATED_SINCE(5, 15) + Q_ASSERT_X(i >= 0 && i <= p.size(), "QList<T>::insert", "index out of range"); +#elif !defined(QT_NO_DEBUG) + if (i < 0 || i > p.size()) + qWarning("QList::insert(): Index out of range."); +#endif if (d->ref.isShared()) { Node *n = detach_helper_grow(i, 1); QT_TRY { diff --git a/src/corelib/tools/qset.h b/src/corelib/tools/qset.h index 6683188ad4..923411c34c 100644 --- a/src/corelib/tools/qset.h +++ b/src/corelib/tools/qset.h @@ -108,7 +108,11 @@ public: friend class QSet<T>; public: +#if QT_DEPRECATED_SINCE(5, 15) typedef std::bidirectional_iterator_tag iterator_category; +#else + typedef std::forward_iterator_tag iterator_category; +#endif typedef qptrdiff difference_type; typedef T value_type; typedef const T *pointer; @@ -128,13 +132,15 @@ public: { return i != o.i; } inline iterator &operator++() { ++i; return *this; } inline iterator operator++(int) { iterator r = *this; ++i; return r; } - inline iterator &operator--() { --i; return *this; } - inline iterator operator--(int) { iterator r = *this; --i; return r; } - inline iterator operator+(int j) const { return i + j; } - inline iterator operator-(int j) const { return i - j; } - friend inline iterator operator+(int j, iterator k) { return k + j; } - inline iterator &operator+=(int j) { i += j; return *this; } - inline iterator &operator-=(int j) { i -= j; return *this; } +#if QT_DEPRECATED_SINCE(5, 15) + inline QT_DEPRECATED iterator &operator--() { --i; return *this; } + inline QT_DEPRECATED iterator operator--(int) { iterator r = *this; --i; return r; } + inline QT_DEPRECATED iterator operator+(int j) const { return i + j; } + inline QT_DEPRECATED iterator operator-(int j) const { return i - j; } + friend inline QT_DEPRECATED iterator operator+(int j, iterator k) { return k + j; } + inline QT_DEPRECATED iterator &operator+=(int j) { i += j; return *this; } + inline QT_DEPRECATED iterator &operator-=(int j) { i -= j; return *this; } +#endif }; class const_iterator @@ -145,7 +151,11 @@ public: friend class QSet<T>; public: +#if QT_DEPRECATED_SINCE(5, 15) typedef std::bidirectional_iterator_tag iterator_category; +#else + typedef std::forward_iterator_tag iterator_category; +#endif typedef qptrdiff difference_type; typedef T value_type; typedef const T *pointer; @@ -163,19 +173,18 @@ public: inline bool operator!=(const const_iterator &o) const { return i != o.i; } inline const_iterator &operator++() { ++i; return *this; } inline const_iterator operator++(int) { const_iterator r = *this; ++i; return r; } - inline const_iterator &operator--() { --i; return *this; } - inline const_iterator operator--(int) { const_iterator r = *this; --i; return r; } - inline const_iterator operator+(int j) const { return i + j; } - inline const_iterator operator-(int j) const { return i - j; } - friend inline const_iterator operator+(int j, const_iterator k) { return k + j; } - inline const_iterator &operator+=(int j) { i += j; return *this; } - inline const_iterator &operator-=(int j) { i -= j; return *this; } +#if QT_DEPRECATED_SINCE(5, 15) + inline QT_DEPRECATED const_iterator &operator--() { --i; return *this; } + inline QT_DEPRECATED const_iterator operator--(int) { const_iterator r = *this; --i; return r; } + inline QT_DEPRECATED const_iterator operator+(int j) const { return i + j; } + inline QT_DEPRECATED const_iterator operator-(int j) const { return i - j; } + friend inline QT_DEPRECATED const_iterator operator+(int j, const_iterator k) { return k + j; } + inline QT_DEPRECATED const_iterator &operator+=(int j) { i += j; return *this; } + inline QT_DEPRECATED const_iterator &operator-=(int j) { i -= j; return *this; } +#endif }; // STL style - typedef std::reverse_iterator<iterator> reverse_iterator; - typedef std::reverse_iterator<const_iterator> const_reverse_iterator; - inline iterator begin() { return q_hash.begin(); } inline const_iterator begin() const noexcept { return q_hash.begin(); } inline const_iterator cbegin() const noexcept { return q_hash.begin(); } @@ -185,12 +194,17 @@ public: inline const_iterator cend() const noexcept { return q_hash.end(); } inline const_iterator constEnd() const noexcept { return q_hash.constEnd(); } - reverse_iterator rbegin() { return reverse_iterator(end()); } - reverse_iterator rend() { return reverse_iterator(begin()); } - const_reverse_iterator rbegin() const noexcept { return const_reverse_iterator(end()); } - const_reverse_iterator rend() const noexcept { return const_reverse_iterator(begin()); } - const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(end()); } - const_reverse_iterator crend() const noexcept { return const_reverse_iterator(begin()); } +#if QT_DEPRECATED_SINCE(5, 15) + typedef std::reverse_iterator<iterator> reverse_iterator; + typedef std::reverse_iterator<const_iterator> const_reverse_iterator; + + reverse_iterator QT_DEPRECATED rbegin() { return reverse_iterator(end()); } + reverse_iterator QT_DEPRECATED rend() { return reverse_iterator(begin()); } + const_reverse_iterator QT_DEPRECATED rbegin() const noexcept { return const_reverse_iterator(end()); } + const_reverse_iterator QT_DEPRECATED rend() const noexcept { return const_reverse_iterator(begin()); } + const_reverse_iterator QT_DEPRECATED crbegin() const noexcept { return const_reverse_iterator(end()); } + const_reverse_iterator QT_DEPRECATED crend() const noexcept { return const_reverse_iterator(begin()); } +#endif iterator erase(iterator i) { return erase(m2c(i)); } @@ -399,17 +413,19 @@ public: inline bool hasNext() const { return c->constEnd() != i; } inline const T &next() { n = i++; return *n; } inline const T &peekNext() const { return *i; } - inline bool hasPrevious() const { return c->constBegin() != i; } - inline const T &previous() { n = --i; return *n; } - inline const T &peekPrevious() const { iterator p = i; return *--p; } inline void remove() { if (c->constEnd() != n) { i = c->erase(n); n = c->end(); } } inline const T &value() const { Q_ASSERT(item_exists()); return *n; } inline bool findNext(const T &t) { while (c->constEnd() != (n = i)) if (*i++ == t) return true; return false; } - inline bool findPrevious(const T &t) +#if QT_DEPRECATED_SINCE(5, 15) + inline QT_DEPRECATED bool hasPrevious() const { return c->constBegin() != i; } + inline QT_DEPRECATED const T &previous() { n = --i; return *n; } + inline QT_DEPRECATED const T &peekPrevious() const { iterator p = i; return *--p; } + inline QT_DEPRECATED bool findPrevious(const T &t) { while (c->constBegin() != i) if (*(n = --i) == t) return true; n = c->end(); return false; } +#endif }; #endif // QT_NO_JAVA_STYLE_ITERATORS diff --git a/src/corelib/tools/qset.qdoc b/src/corelib/tools/qset.qdoc index 084523ed4b..7c752d0318 100644 --- a/src/corelib/tools/qset.qdoc +++ b/src/corelib/tools/qset.qdoc @@ -906,8 +906,6 @@ Calling this function on QSet<T>::constEnd() leads to undefined results. - - \sa operator--() */ /*! @@ -924,6 +922,7 @@ /*! \fn template <class T> QSet<T>::iterator &QSet<T>::iterator::operator--() \fn template <class T> QSet<T>::const_iterator &QSet<T>::const_iterator::operator--() + \obsolete The prefix -- operator (\c{--it}) makes the preceding item current and returns an iterator to the new current item. @@ -937,6 +936,7 @@ /*! \fn template <class T> QSet<T>::iterator QSet<T>::iterator::operator--(int) \fn template <class T> QSet<T>::const_iterator QSet<T>::const_iterator::operator--(int) + \obsolete \overload @@ -947,6 +947,7 @@ /*! \fn template <class T> QSet<T>::iterator QSet<T>::iterator::operator+(int j) const \fn template <class T> QSet<T>::const_iterator QSet<T>::const_iterator::operator+(int j) const + \obsolete Returns an iterator to the item at \a j positions forward from this iterator. (If \a j is negative, the iterator goes backward.) @@ -959,6 +960,7 @@ /*! \fn template <class T> QSet<T>::iterator QSet<T>::iterator::operator-(int j) const \fn template <class T> QSet<T>::const_iterator QSet<T>::const_iterator::operator-(int j) const + \obsolete Returns an iterator to the item at \a j positions backward from this iterator. (If \a j is negative, the iterator goes forward.) @@ -971,6 +973,7 @@ /*! \fn template <class T> QSet<T>::iterator &QSet<T>::iterator::operator+=(int j) \fn template <class T> QSet<T>::const_iterator &QSet<T>::const_iterator::operator+=(int j) + \obsolete Advances the iterator by \a j items. (If \a j is negative, the iterator goes backward.) @@ -983,6 +986,7 @@ /*! \fn template <class T> QSet<T>::iterator &QSet<T>::iterator::operator-=(int j) \fn template <class T> QSet<T>::const_iterator &QSet<T>::const_iterator::operator-=(int j) + \obsolete Makes the iterator go back by \a j items. (If \a j is negative, the iterator goes forward.) diff --git a/src/corelib/tools/qsimd.cpp b/src/corelib/tools/qsimd.cpp index 6e3b0f9faf..d7c1d8c4a9 100644 --- a/src/corelib/tools/qsimd.cpp +++ b/src/corelib/tools/qsimd.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2018 Intel Corporation. +** Copyright (C) 2019 Intel Corporation. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtCore module of the Qt Toolkit. @@ -188,6 +188,8 @@ static inline quint64 detectProcessorFeatures() # define PICreg "%%rbx" #endif +static bool checkRdrndWorks() noexcept; + static int maxBasicCpuidSupported() { #if defined(Q_CC_EMSCRIPTEN) @@ -376,37 +378,8 @@ static quint64 detectProcessorFeatures() features &= ~AllAVX512; } -#if defined(Q_PROCESSOR_X86) && QT_COMPILER_SUPPORTS_HERE(RDRND) - /** - * Some AMD CPUs (e.g. AMD A4-6250J and AMD Ryzen 3000-series) have a - * failing random generation instruction, which always returns - * 0xffffffff, even when generation was "successful". - * - * This code checks if hardware random generator generates four consecutive - * equal numbers. If it does, then we probably have a failing one and - * should disable it completely. - * - * https://bugreports.qt.io/browse/QTBUG-69423 - */ - if (features & CpuFeatureRDRND) { - const qsizetype testBufferSize = 4; - unsigned testBuffer[4] = {}; - - const qsizetype generated = qRandomCpu(testBuffer, testBufferSize); - - if (Q_UNLIKELY(generated == testBufferSize && - testBuffer[0] == testBuffer[1] && - testBuffer[1] == testBuffer[2] && - testBuffer[2] == testBuffer[3])) { - - fprintf(stderr, "WARNING: CPU random generator seem to be failing, disable hardware random number generation\n"); - fprintf(stderr, "WARNING: RDRND generated: 0x%x 0x%x 0x%x 0x%x\n", - testBuffer[0], testBuffer[1], testBuffer[2], testBuffer[3]); - - features &= ~CpuFeatureRDRND; - } - } -#endif + if (features & CpuFeatureRDRND && !checkRdrndWorks()) + features &= ~(CpuFeatureRDRND | CpuFeatureRDSEED); return features; } @@ -662,15 +635,9 @@ static unsigned *qt_random_rdseed(unsigned *ptr, unsigned *) } # endif -QT_FUNCTION_TARGET(RDRND) qsizetype qRandomCpu(void *buffer, qsizetype count) noexcept +static QT_FUNCTION_TARGET(RDRND) unsigned *qt_random_rdrnd(unsigned *ptr, unsigned *end) noexcept { - unsigned *ptr = reinterpret_cast<unsigned *>(buffer); - unsigned *end = ptr + count; int retries = 10; - - if (qCpuHasFeature(RDSEED)) - ptr = qt_random_rdseed(ptr, end); - while (ptr + sizeof(qregisteruint)/sizeof(*ptr) <= end) { if (_rdrandXX_step(reinterpret_cast<qregisteruint *>(ptr))) ptr += sizeof(qregisteruint)/sizeof(*ptr); @@ -688,8 +655,64 @@ QT_FUNCTION_TARGET(RDRND) qsizetype qRandomCpu(void *buffer, qsizetype count) no } out: + return ptr; +} + +static QT_FUNCTION_TARGET(RDRND) Q_DECL_COLD_FUNCTION bool checkRdrndWorks() noexcept +{ + /* + * Some AMD CPUs (e.g. AMD A4-6250J and AMD Ryzen 3000-series) have a + * failing random generation instruction, which always returns + * 0xffffffff, even when generation was "successful". + * + * This code checks if hardware random generator generates four consecutive + * equal numbers. If it does, then we probably have a failing one and + * should disable it completely. + * + * https://bugreports.qt.io/browse/QTBUG-69423 + */ + constexpr qsizetype TestBufferSize = 4; + unsigned testBuffer[TestBufferSize] = {}; + + unsigned *end = qt_random_rdrnd(testBuffer, testBuffer + TestBufferSize); + if (end < testBuffer + 3) { + // Random generation didn't produce enough data for us to make a + // determination whether it's working or not. Assume it isn't, but + // don't print a warning. + return false; + } + + // Check the results for equality + if (testBuffer[0] == testBuffer[1] + && testBuffer[0] == testBuffer[2] + && end == testBuffer + TestBufferSize && testBuffer[0] == testBuffer[3]) { + fprintf(stderr, "WARNING: CPU random generator seem to be failing, " + "disabling hardware random number generation\n" + "WARNING: RDRND generated:"); + for (unsigned *ptr = testBuffer; ptr < end; ++ptr) + fprintf(stderr, " 0x%x", *ptr); + fprintf(stderr, "\n"); + return false; + } + + // We're good + return true; +} + +QT_FUNCTION_TARGET(RDRND) qsizetype qRandomCpu(void *buffer, qsizetype count) noexcept +{ + unsigned *ptr = reinterpret_cast<unsigned *>(buffer); + unsigned *end = ptr + count; + + if (qCpuHasFeature(RDSEED)) + ptr = qt_random_rdseed(ptr, end); + + // fill the buffer with RDRND if RDSEED didn't + ptr = qt_random_rdrnd(ptr, end); return ptr - reinterpret_cast<unsigned *>(buffer); } -#endif +#elif defined(Q_PROCESSOR_X86) && !defined(Q_OS_NACL) && !defined(Q_PROCESSOR_ARM) +static bool checkRdrndWorks() noexcept { return false; } +#endif // Q_PROCESSOR_X86 && RDRND QT_END_NAMESPACE |