Android: Fix crash in String.replace() in release builds
authorEskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@digia.com>
Mon, 5 May 2014 13:01:10 +0000 (15:01 +0200)
committerThe Qt Project <gerrit-noreply@qt-project.org>
Mon, 5 May 2014 18:59:07 +0000 (20:59 +0200)
When enabling optimizations in the compiler, it produces bogus
code for the regExp->value deref in the line

nMatchOffsets += regExp->value->captureCount() * 2

This is a random refactoring to work around the compiler bug.
The only line that actually needs to be touched is the one mentioned
above, but I replaced all uses of regExp->value so that it
wouldn't look too weird.

Task-number: QTBUG-38692
Change-Id: Ib33a523a86ce51ebc6c7095a803fedaebcaa8e63
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
src/qml/jsruntime/qv4stringobject.cpp

index 7c38ae4..f1e5170 100644 (file)
@@ -508,21 +508,24 @@ ReturnedValue StringPrototype::method_replace(CallContext *ctx)
     Scoped<RegExpObject> regExp(scope, searchValue);
     if (regExp) {
         uint offset = 0;
+
+        // We extract the pointer here to work around a compiler bug on Android.
+        Scoped<RegExp> re(scope, regExp->value);
         while (true) {
             int oldSize = nMatchOffsets;
-            if (allocatedMatchOffsets < nMatchOffsets + regExp->value->captureCount() * 2) {
-                allocatedMatchOffsets = qMax(allocatedMatchOffsets * 2, nMatchOffsets + regExp->value->captureCount() * 2);
+            if (allocatedMatchOffsets < nMatchOffsets + re->captureCount() * 2) {
+                allocatedMatchOffsets = qMax(allocatedMatchOffsets * 2, nMatchOffsets + re->captureCount() * 2);
                 uint *newOffsets = (uint *)malloc(allocatedMatchOffsets*sizeof(uint));
                 memcpy(newOffsets, matchOffsets, nMatchOffsets*sizeof(uint));
                 if (matchOffsets != _matchOffsets)
                     free(matchOffsets);
                 matchOffsets = newOffsets;
             }
-            if (regExp->value->match(string, offset, matchOffsets + oldSize) == JSC::Yarr::offsetNoMatch) {
+            if (re->match(string, offset, matchOffsets + oldSize) == JSC::Yarr::offsetNoMatch) {
                 nMatchOffsets = oldSize;
                 break;
             }
-            nMatchOffsets += regExp->value->captureCount() * 2;
+            nMatchOffsets += re->captureCount() * 2;
             if (!regExp->global)
                 break;
             offset = qMax(offset + 1, matchOffsets[oldSize + 1]);