sc: ignore the dynamic-array master flag when @ ends the RPN

An @-prefixed formula opts out of dynamic-array spilling, but
the OOXML import still arrives with cm="1" on such cells. The
cell then turned into #SPILL! because the spill check ran
against the 1x1 declared range.

Reject the dynamic-array master request when the RPN ends with
@. The @ collapses the array at interpret time.

testAtFormulaIgnoresDynamicArrayMasterFlag checks that
SetDynamicArrayMaster has no effect on an @-prefixed cell.

Signed-off-by: Tomaž Vajngerl <tomaz.vajngerl@collabora.co.uk>
Change-Id: I33322626a32893287c8859580a719dbeb9b915b4
Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/5490
Reviewed-by: Tomaž Vajngerl <tomaz.vajngerl@collabora.com>
Tested-by: Tomaž Vajngerl <tomaz.vajngerl@collabora.com>
(cherry picked from commit 02c7d85b6a0aa6269582072642501148da2d092d)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/207867
Tested-by: Jenkins
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
This commit is contained in:
Tomaž Vajngerl
2026-07-09 17:08:36 +02:00
committed by Xisco Fauli
parent 5663da9fa7
commit ee4bd7f201
2 changed files with 33 additions and 0 deletions
+26
View File
@@ -6468,6 +6468,32 @@ CPPUNIT_TEST_FIXTURE(TestFormula2, testCallableWhereNumberExpected)
m_pDoc->DeleteTab(0);
}
CPPUNIT_TEST_FIXTURE(TestFormula2, testAtFormulaIgnoresDynamicArrayMasterFlag)
{
// An @-prefixed formula opts out of dynamic-array spilling.
// SetDynamicArrayMaster ignores a request to enable the flag on
// such a cell, so an OOXML cm="1" arriving on an @-cell does not
// turn into a #SPILL! at interpret time.
sc::AutoCalcSwitch aACSwitch(*m_pDoc, true);
m_pDoc->InsertTab(0, u"Sheet1"_ustr);
m_pDoc->SetValue(ScAddress(0, 0, 0), 1.0);
m_pDoc->SetValue(ScAddress(0, 1, 0), 2.0);
m_pDoc->SetValue(ScAddress(0, 2, 0), 3.0);
m_pDoc->SetFormula(ScAddress(1, 0, 0), u"=@(A1:A3+0)"_ustr,
formula::FormulaGrammar::GRAM_NATIVE);
ScFormulaCell* pCell = m_pDoc->GetFormulaCell(ScAddress(1, 0, 0));
CPPUNIT_ASSERT(pCell);
pCell->SetDynamicArrayMaster(true);
CPPUNIT_ASSERT(!pCell->IsDynamicArrayMaster());
CPPUNIT_ASSERT_EQUAL(1.0, m_pDoc->GetValue(ScAddress(1, 0, 0)));
m_pDoc->DeleteTab(0);
}
CPPUNIT_TEST_FIXTURE(TestFormula2, testMatrixConcatRendersBooleansAsTrueFalse)
{
// A boolean value pulled into a string context renders as the
+7
View File
@@ -2731,6 +2731,13 @@ void ScFormulaCell::SetCompile( bool bVal )
void ScFormulaCell::SetDynamicArrayMaster(bool bDynamic)
{
// A formula with @ on top of its RPN opts out of dynamic-array
// spilling: the operator collapses any array operand to a single
// value, so there is nothing to spill. XLSX still emits the cm="1"
// marker on such cells, so reject the request rather than letting
// the spill check fire against a 1x1 declared matrix.
if (bDynamic && pCode && rpnTopIsImplicitIntersection(*pCode))
return;
mbDynamicArrayMaster = bDynamic;
// A plain single-cell formula that opts into the dynamic-array flag
// becomes a 1x1 matrix master so the first interpret can expand it