From d6954bfec1d874b6f6af3b0c868b99dbd5cfeb44 Mon Sep 17 00:00:00 2001 From: Andreas Heinisch Date: Sun, 10 May 2026 17:35:34 +0200 Subject: [PATCH] tdf#143706 - Mark skipped named optional parameters as missing/empty When calling a Basic procedure using a named argument (for example, foo(y:=10)), optional skipped parameters were not correctly marked as missing, causing the function IsMissing() to return incorrect results. Change-Id: I90a9910165ec00a24deba86f7b3397dbc0720c93 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/205034 Tested-by: Jenkins Reviewed-by: Andreas Heinisch --- .../basic_coverage/test_ismissing_basic.bas | 9 ++++++++ .../test_ismissing_compatible.bas | 9 ++++++++ basic/qa/vba_tests/ismissing.vb | 9 ++++++++ basic/source/runtime/runtime.cxx | 21 +++++++++++++++++++ 4 files changed, 48 insertions(+) diff --git a/basic/qa/basic_coverage/test_ismissing_basic.bas b/basic/qa/basic_coverage/test_ismissing_basic.bas index 0996da0f82a4..ee515c6c8540 100644 --- a/basic/qa/basic_coverage/test_ismissing_basic.bas +++ b/basic/qa/basic_coverage/test_ismissing_basic.bas @@ -109,6 +109,15 @@ Sub verify_testIsMissingBasic() TestUtil.AssertEqual(TestOptArrayByRefByVal(, aB), IsMissingA, "TestOptArrayByRefByVal(, B)") TestUtil.AssertEqual(TestOptArrayByRefByVal(aA, aB), IsMissingNone, "TestOptArrayByRefByVal(A, B)") + ' tdf#143706 - optionals with named arguments (:= syntax) + ' Without the fix in place, this test would have failed with: + ' - Expected: 0 (IsMissingA) + ' - Actual : -1 (IsMissingNone) + TestUtil.AssertEqual(TestOptVariant(B := 456), IsMissingA, "TestOptVariant(B := 456)") + TestUtil.AssertEqual(TestOptVariant(A := 123), IsMissingB, "TestOptVariant(A := 123)") + TestUtil.AssertEqual(TestOptVariant(A := 123, B := 456), IsMissingNone, "TestOptVariant(A := 123, B := 456)") + TestUtil.AssertEqual(TestOptVariant(B := 456, A := 123), IsMissingNone, "TestOptVariant(B := 456, A := 123)") + Exit Sub errorHandler: TestUtil.ReportErrorHandler("verify_testIsMissingBasic", Err, Error$, Erl) diff --git a/basic/qa/basic_coverage/test_ismissing_compatible.bas b/basic/qa/basic_coverage/test_ismissing_compatible.bas index 6d11ab0902be..792418b927b2 100644 --- a/basic/qa/basic_coverage/test_ismissing_compatible.bas +++ b/basic/qa/basic_coverage/test_ismissing_compatible.bas @@ -109,6 +109,15 @@ Sub verify_testIsMissingCompatible() TestUtil.AssertEqual(TestOptArrayByRefByVal(, aB), IsMissingA, "TestOptArrayByRefByVal(, B)") TestUtil.AssertEqual(TestOptArrayByRefByVal(aA, aB), IsMissingNone, "TestOptArrayByRefByVal(A, B)") + ' tdf#143706 - optionals with named arguments (:= syntax) + ' Without the fix in place, this test would have failed with: + ' - Expected: 0 (IsMissingA) + ' - Actual : -1 (IsMissingNone) + TestUtil.AssertEqual(TestOptVariant(B := 456), IsMissingA, "TestOptVariant(B := 456)") + TestUtil.AssertEqual(TestOptVariant(A := 123), IsMissingNone, "TestOptVariant(A := 123)") + TestUtil.AssertEqual(TestOptVariant(A := 123, B := 456), IsMissingNone, "TestOptVariant(A := 123, B := 456)") + TestUtil.AssertEqual(TestOptVariant(B := 456, A := 123), IsMissingNone, "TestOptVariant(B := 456, A := 123)") + Exit Sub errorHandler: TestUtil.ReportErrorHandler("verify_testIsMissingCompatible", Err, Error$, Erl) diff --git a/basic/qa/vba_tests/ismissing.vb b/basic/qa/vba_tests/ismissing.vb index febe0339f68a..3d32b8db6861 100644 --- a/basic/qa/vba_tests/ismissing.vb +++ b/basic/qa/vba_tests/ismissing.vb @@ -115,6 +115,15 @@ Sub verify_testIsMissingVba() ' TestUtil.AssertEqual(TestOptArrayByRefByVal(, aB), IsMissingA, "TestOptArrayByRefByVal(, B)") TestUtil.AssertEqual(TestOptArrayByRefByVal(aA, aB), IsMissingNone, "TestOptArrayByRefByVal(A, B)") + ' tdf#143706 - optionals with named arguments (:= syntax) + ' Without the fix in place, this test would have failed with: + ' - Expected: 0 (IsMissingA) + ' - Actual : -1 (IsMissingNone) + TestUtil.AssertEqual(TestOptVariant(B := 456), IsMissingA, "TestOptVariant(B := 456)") + TestUtil.AssertEqual(TestOptVariant(A := 123), IsMissingNone, "TestOptVariant(A := 123)") + TestUtil.AssertEqual(TestOptVariant(A := 123, B := 456), IsMissingNone, "TestOptVariant(A := 123, B := 456)") + TestUtil.AssertEqual(TestOptVariant(B := 456, A := 123), IsMissingNone, "TestOptVariant(B := 456, A := 123)") + Exit Sub errorHandler: TestUtil.ReportErrorHandler("verify_testIsMissingVba", Err, Error$, Erl) diff --git a/basic/source/runtime/runtime.cxx b/basic/source/runtime/runtime.cxx index b625b928bc2d..40d5eebe7b6b 100644 --- a/basic/source/runtime/runtime.cxx +++ b/basic/source/runtime/runtime.cxx @@ -3923,6 +3923,27 @@ void SbiRuntime::SetupArgs( SbxVariable* p, sal_uInt32 nOp1 ) } pArg->Put(pVar, nCurPar++); } + // tdf#143706 - mark skipped named optional parameters as missing/empty + SbxMethod* pSbxMeth = dynamic_cast(p); + const bool bIsRuntimeFunction = pSbxMeth && pSbxMeth->IsRuntimeFunction(); + for (sal_uInt32 j = 1; j < pArg->Count(); j++) + { + if (!pArg->GetRef(j)) + { + SbxVariableRef xVar; + if (bIsRuntimeFunction) + xVar = new SbxVariable(SbxEMPTY); + else + { + // Same as in SbiRuntime::StepEMPTY(), because the compiler does not + // generate a StepEMPTY for StepPARAM when there is no COMMA token + xVar = new SbxVariable(SbxVARIANT); + xVar->PutErr(448); + SetIsMissing(xVar.get()); + } + pArg->Put(xVar.get(), j); + } + } refArgv = pArg; } }