diff options
author | Mike Kaganski <mike.kaganski@collabora.com> | 2024-08-18 02:31:00 +0500 |
---|---|---|
committer | Mike Kaganski <mike.kaganski@collabora.com> | 2024-08-18 09:08:49 +0200 |
commit | afb46ee8803a04664f26da3e1f8f88a75d92cb7f (patch) | |
tree | 6c7f7d0f25b76123f44a298b1dbbc62190191903 | |
parent | 4e1ee0ba1dd6b2de4ff78b8fb7daa72b40bb940a (diff) |
tdf#150458: evaluate for loop's end and step once in VBA support mode
As required by [MS-VBAL], and actual VBA implementation.
It is a question if we also need to change it likewise in other
modes (normal, compatible) - see tdf#150460.
Change-Id: I1e83d57fe4be3bf264a64fe977909cf7684bc798
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/172005
Tested-by: Jenkins
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
-rw-r--r-- | basic/qa/cppunit/test_vba.cxx | 1 | ||||
-rw-r--r-- | basic/qa/vba_tests/for.vb | 43 | ||||
-rw-r--r-- | basic/source/runtime/runtime.cxx | 11 |
3 files changed, 55 insertions, 0 deletions
diff --git a/basic/qa/cppunit/test_vba.cxx b/basic/qa/cppunit/test_vba.cxx index 7b0ca79ce887..e3082d40e02a 100644 --- a/basic/qa/cppunit/test_vba.cxx +++ b/basic/qa/cppunit/test_vba.cxx @@ -90,6 +90,7 @@ void VBATest::testMiscVBAFunctions() "gosub_goto.vb", "hex.vb", "hour.vb", + "for.vb", "formatnumber.vb", "formatpercent.vb", "if.vb", diff --git a/basic/qa/vba_tests/for.vb b/basic/qa/vba_tests/for.vb new file mode 100644 index 000000000000..62e886cdd056 --- /dev/null +++ b/basic/qa/vba_tests/for.vb @@ -0,0 +1,43 @@ +' +' This file is part of the LibreOffice project. +' +' This Source Code Form is subject to the terms of the Mozilla Public +' License, v. 2.0. If a copy of the MPL was not distributed with this +' file, You can obtain one at http://mozilla.org/MPL/2.0/. +' + +Option VBASupport 1 + +Function doUnitTest() As String + TestUtil.TestInit + test_for + doUnitTest = TestUtil.GetResult() +End Function + +Sub test_for() + On Error GoTo errorHandler + + Dim i As Long, j As Long, k As Long + ' Test that loop end value is evaluated only once, + ' and then changing the variable doesn't affect it + k=10 + For i=1 To k + k=1 + j=i + Next i + TestUtil.AssertEqual(j, 10, "Last loop control value (changing end variable)") + + ' Test that loop step value is evaluated only once, + ' and then changing the variable doesn't affect it + k=1 + j=0 + For i=1 To 10 Step k + k=10 + j=j+1 + Next i + TestUtil.AssertEqual(j, 10, "Number of iterations (changing step variable)") + + Exit Sub +errorHandler: + TestUtil.ReportErrorHandler("verify_testOptionalsVba", Err, Error$, Erl) +End Sub diff --git a/basic/source/runtime/runtime.cxx b/basic/source/runtime/runtime.cxx index 7d3f15d46f16..d8feb4123305 100644 --- a/basic/source/runtime/runtime.cxx +++ b/basic/source/runtime/runtime.cxx @@ -1131,6 +1131,17 @@ void SbiRuntime::PushFor() p->refInc = PopVar(); p->refEnd = PopVar(); + if (isVBAEnabled()) + { + // tdf#150458: only calculate these once, coercing to double + // tdf#150460: shouldn't we do it in non-VBA / compat mode, too? + SbxVariableRef incCopy(new SbxVariable(SbxDOUBLE)); + *incCopy = *p->refInc; + p->refInc = std::move(incCopy); + SbxVariableRef endCopy(new SbxVariable(SbxDOUBLE)); + *endCopy = *p->refEnd; + p->refEnd = std::move(endCopy); + } SbxVariableRef xBgn = PopVar(); p->refVar = PopVar(); // tdf#85371 - grant explicitly write access to the index variable |