basic/qa/cppunit/test_vba.cxx    |    1 
 basic/qa/vba_tests/for.vb        |   43 +++++++++++++++++++++++++++++++++++++++
 basic/source/runtime/runtime.cxx |   11 +++++++++
 3 files changed, 55 insertions(+)

New commits:
commit afb46ee8803a04664f26da3e1f8f88a75d92cb7f
Author:     Mike Kaganski <[email protected]>
AuthorDate: Sun Aug 18 02:31:00 2024 +0500
Commit:     Mike Kaganski <[email protected]>
CommitDate: Sun Aug 18 09:08:49 2024 +0200

    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 <[email protected]>

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

Reply via email to