summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuboš Luňák <l.lunak@collabora.com>2020-09-04 15:51:07 +0200
committerLuboš Luňák <l.lunak@collabora.com>2020-09-10 11:15:47 +0200
commit4f36f2ccab6286ec09480caea602c0fa19195736 (patch)
tree0d3156c2f322983fa30d3a6f4600be5102e2718e
parent3f620e74aa00e34f773d97e9480a6532d9e8863e (diff)
detect if a cell still needs interpreting after Interpret()
https://bugs.documentfoundation.org/attachment.cgi?id=51878 after hard-recalc asserts because of not having cell dependencies non-dirty for threaded calculation. This is because Interpret() actually sometimes returns without computing a value for the cell, e.g. when it backs out because of a need to do iteration. This is handled when Interpret() is called from InterpretTail(), but ScDependantsCalculator does not handle this and considers all cells interpreted, unless it detected a problem. We've already fixed a number of such bugs, and given that there are still problematic corner cases after all this time, add code simply detecting this generic problem and avoiding threading in that case, with a SAL_WARN. This does not fix the problem itself, but at least now it's handled. Change-Id: I2f454b577f6516d2ce008005dbfbeb554e18d811 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/102156 Tested-by: Jenkins Reviewed-by: Luboš Luňák <l.lunak@collabora.com>
-rw-r--r--sc/source/core/data/column4.cxx28
1 files changed, 26 insertions, 2 deletions
diff --git a/sc/source/core/data/column4.cxx b/sc/source/core/data/column4.cxx
index ae3cd16fffa7..f6dac8ae3c65 100644
--- a/sc/source/core/data/column4.cxx
+++ b/sc/source/core/data/column4.cxx
@@ -1667,6 +1667,10 @@ static bool lcl_InterpretSpan(sc::formula_block::const_iterator& rSpanIter, SCRO
// Found a completely dirty sub span [nSpanStart, nSpanEnd] inside the required span [nStartOffset, nEndOffset]
bool bGroupInterpreted = pCellStart->Interpret(nSpanStart, nSpanEnd);
+ if (bGroupInterpreted)
+ for (SCROW nIdx = nSpanStart; nIdx <= nSpanEnd; ++nIdx, ++itSpanStart)
+ assert(!(*itSpanStart)->NeedsInterpret());
+
ScRecursionHelper& rRecursionHelper = rDoc.GetRecursionHelper();
// child cell's Interpret could result in calling dependency calc
// and that could detect a cycle involving mxGroup
@@ -1686,7 +1690,15 @@ static bool lcl_InterpretSpan(sc::formula_block::const_iterator& rSpanIter, SCRO
++itSpanStart;
for (SCROW nIdx = nSpanStart+1; nIdx <= nSpanEnd; ++nIdx, ++itSpanStart)
{
- (*itSpanStart)->Interpret(); // We know for sure that this cell is dirty so directly call Interpret().
+ if( !(*itSpanStart)->Interpret()) // We know for sure that this cell is dirty so directly call Interpret().
+ {
+ SAL_WARN("sc.core.formulagroup", "Internal error, cell " << (*itSpanStart)->aPos
+ << " failed running Interpret(), not allowing threading");
+ bAllowThreading = false;
+ return bAnyDirty;
+ }
+ assert(!(*itSpanStart)->NeedsInterpret());
+
// Allow early exit like above.
if ((mxParentGroup && mxParentGroup->mbPartOfCycle) || !rRecursionHelper.AreGroupsIndependent())
{
@@ -1788,7 +1800,19 @@ static void lcl_EvalDirty(sc::CellStoreType& rCells, SCROW nRow1, SCROW nRow2, S
else
{
// No formula-group here.
- bool bDirtyFlag = (*itCell)->MaybeInterpret();
+ bool bDirtyFlag = false;
+ if( (*itCell)->NeedsInterpret())
+ {
+ bDirtyFlag = true;
+ if(!(*itCell)->Interpret())
+ {
+ SAL_WARN("sc.core.formulagroup", "Internal error, cell " << (*itCell)->aPos
+ << " failed running Interpret(), not allowing threading");
+ bAllowThreading = false;
+ return;
+ }
+ assert(!(*itCell)->NeedsInterpret());
+ }
bIsDirty = bIsDirty || bDirtyFlag;
// child cell's Interpret could result in calling dependency calc