aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorErik Verbruggen <erik.verbruggen@digia.com>2014-07-01 13:34:31 +0200
committerErik Verbruggen <erik.verbruggen@digia.com>2014-07-24 14:03:03 +0200
commit36a179e8faa572544b9e8a9442f8c679a9509423 (patch)
tree6cc5784726992ccb4bc71e8e7a1416c613df6c68 /src
parent619790ba60e223c90a7ff33635ec5ab227584cbf (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.cpp31
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;
}