summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Kaganski <mike.kaganski@collabora.com>2024-08-18 02:31:00 +0500
committerMike Kaganski <mike.kaganski@collabora.com>2024-08-18 09:08:49 +0200
commitafb46ee8803a04664f26da3e1f8f88a75d92cb7f (patch)
tree6c7f7d0f25b76123f44a298b1dbbc62190191903
parent4e1ee0ba1dd6b2de4ff78b8fb7daa72b40bb940a (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.cxx1
-rw-r--r--basic/qa/vba_tests/for.vb43
-rw-r--r--basic/source/runtime/runtime.cxx11
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