diff options
author | Erik Verbruggen <erik.verbruggen@digia.com> | 2014-07-01 13:34:31 +0200 |
---|---|---|
committer | Erik Verbruggen <erik.verbruggen@digia.com> | 2014-07-24 14:03:03 +0200 |
commit | 36a179e8faa572544b9e8a9442f8c679a9509423 (patch) | |
tree | 6cc5784726992ccb4bc71e8e7a1416c613df6c68 /src | |
parent | 619790ba60e223c90a7ff33635ec5ab227584cbf (diff) |
V4: work around a bug in libc++'s std::vector<bool>
The ++operator of std::vector<bool>::iterator in libc++ has a bug when
using it on an iterator pointing to the last element. It will not be set
to ::end(), but beyond that. (It will be set to the first multiple of
the native word size that is bigger than size().)
See http://llvm.org/bugs/show_bug.cgi?id=19663
Task-number: QTBUG-39911
Change-Id: Ic244d9c90ee6b596261a6e322301c411a14820a8
Reviewed-by: Fawzi Mohamed <fawzi.mohamed@digia.com>
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/qml/compiler/qv4ssa.cpp | 31 |
1 files changed, 23 insertions, 8 deletions
diff --git a/src/qml/compiler/qv4ssa.cpp b/src/qml/compiler/qv4ssa.cpp index 97114b9507..d7dbfac50b 100644 --- a/src/qml/compiler/qv4ssa.cpp +++ b/src/qml/compiler/qv4ssa.cpp @@ -246,13 +246,31 @@ public: if (set.blockNumbers) numberIt = set.blockNumbers->begin(); else - flagIt = std::distance(set.blockFlags->begin(), - std::find(set.blockFlags->begin(), - set.blockFlags->end(), - true)); + findNextWithFlags(0); } } + void findNextWithFlags(size_t start) + { + flagIt = std::distance(set.blockFlags->begin(), + std::find(set.blockFlags->begin() + start, + set.blockFlags->end(), + true)); + + // The ++operator of std::vector<bool>::iterator in libc++ has a bug when using it on an + // iterator pointing to the last element. It will not be set to ::end(), but beyond + // that. (It will be set to the first multiple of the native word size that is bigger + // than size().) + // + // See http://llvm.org/bugs/show_bug.cgi?id=19663 + // + // As we use the size to for our end() iterator, take the minimum of the size and the + // distance for the flagIt: + flagIt = qMin(flagIt, set.blockFlags->size()); + + Q_ASSERT(flagIt <= set.blockFlags->size()); + } + public: BasicBlock *operator*() const { @@ -282,10 +300,7 @@ public: if (set.blockNumbers) ++numberIt; else - flagIt = std::distance(set.blockFlags->begin(), - std::find(set.blockFlags->begin() + flagIt + 1, - set.blockFlags->end(), - true)); + findNextWithFlags(flagIt + 1); return *this; } |