summaryrefslogtreecommitdiff
path: root/sc
diff options
context:
space:
mode:
authorCaolán McNamara <caolan.mcnamara@collabora.com>2024-04-14 21:09:59 +0100
committerCaolán McNamara <caolan.mcnamara@collabora.com>2024-04-15 14:08:06 +0200
commit9d29649e07a3b2c5c2b3dda1dc15c0ca1ed51ae3 (patch)
tree74dca736747d5e86a777334b434f27107ba5f6d7 /sc
parentb25b8a41ab93890a71859feeba458523c0ec7015 (diff)
Related: tdf#160056 FormulaResult may ref an initial interpreter FormulaToken
If a token from the original tokens, supplied to a parallel group calculation while RefCounting was disabled for those tokens, ends up as a FormulaResult token, then fix up the ref count when parallel calculation ends Change-Id: I2587c25d216ab170725017b67b97d203a578160b Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166080 Tested-by: Jenkins Reviewed-by: Caolán McNamara <caolan.mcnamara@collabora.com>
Diffstat (limited to 'sc')
-rw-r--r--sc/inc/formularesult.hxx3
-rw-r--r--sc/source/core/data/formulacell.cxx2
-rw-r--r--sc/source/core/tool/formularesult.cxx25
3 files changed, 30 insertions, 0 deletions
diff --git a/sc/inc/formularesult.hxx b/sc/inc/formularesult.hxx
index 581d9a4bba3d..44aab47acd44 100644
--- a/sc/inc/formularesult.hxx
+++ b/sc/inc/formularesult.hxx
@@ -62,6 +62,7 @@ class ScFormulaResult
const formula::FormulaToken* mpToken; // if not, result token obtained from interpreter
};
bool mbToken :1; // whether content of union is a token
+ bool mbNoneRefCnt :1; // if token was added when using RefCntPolicy::None
bool mbEmpty :1; // empty cell result
bool mbEmptyDisplayedAsString :1; // only if mbEmpty
// If set it implies that the result is a simple double (in mfValue) and no error
@@ -208,6 +209,8 @@ public:
/** Get the ScMatrixFormulaCellToken* if token is of that type, else NULL.
Shouldn't be used externally except by ScFormulaCell::SetMatColsRows(). */
ScMatrixFormulaCellToken* GetMatrixFormulaCellTokenNonConst();
+
+ void HandleStuffAfterParallelCalculation();
};
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx
index e57514b0345a..529ea73a7e6e 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -2336,6 +2336,8 @@ void ScFormulaCell::InterpretTail( ScInterpreterContext& rContext, ScInterpretTa
void ScFormulaCell::HandleStuffAfterParallelCalculation(ScInterpreter* pInterpreter)
{
+ aResult.HandleStuffAfterParallelCalculation();
+
if( !pCode->GetCodeLen() )
return;
diff --git a/sc/source/core/tool/formularesult.cxx b/sc/source/core/tool/formularesult.cxx
index b421354550a3..08ef363ff68f 100644
--- a/sc/source/core/tool/formularesult.cxx
+++ b/sc/source/core/tool/formularesult.cxx
@@ -26,6 +26,7 @@ FormulaResultValue::FormulaResultValue( FormulaError nErr ) : mfValue(0.0), meTy
ScFormulaResult::ScFormulaResult() :
mpToken(nullptr),
mbToken(true),
+ mbNoneRefCnt(false),
mbEmpty(false),
mbEmptyDisplayedAsString(false),
mbValueCached(false),
@@ -58,10 +59,12 @@ ScFormulaResult::ScFormulaResult( const ScFormulaResult & r ) :
}
else
mfValue = r.mfValue;
+ mbNoneRefCnt = mbToken && mpToken && mpToken->GetRefCntPolicy() == formula::RefCntPolicy::None;
}
ScFormulaResult::ScFormulaResult( const formula::FormulaToken* p ) :
mbToken(false),
+ mbNoneRefCnt(false),
mbEmpty(false),
mbEmptyDisplayedAsString(false),
mbValueCached(false),
@@ -129,6 +132,7 @@ void ScFormulaResult::ResolveToken( const formula::FormulaToken * p )
mbToken = true;
}
}
+ mbNoneRefCnt = mbToken && mpToken && mpToken->GetRefCntPolicy() == formula::RefCntPolicy::None;
}
ScFormulaResult & ScFormulaResult::operator=( const ScFormulaResult & r )
@@ -151,6 +155,7 @@ void ScFormulaResult::Assign( const ScFormulaResult & r )
if (mbToken && mpToken)
mpToken->DecRef();
mbToken = false;
+ mbNoneRefCnt = false;
mbEmpty = true;
mbEmptyDisplayedAsString = r.mbEmptyDisplayedAsString;
meMultiline = r.meMultiline;
@@ -236,6 +241,7 @@ void ScFormulaResult::SetDouble( double f )
mpToken->DecRef();
mfValue = f;
mbToken = false;
+ mbNoneRefCnt = false;
meMultiline = MULTILINE_FALSE;
mbValueCached = true;
}
@@ -563,12 +569,14 @@ void ScFormulaResult::SetHybridDouble( double f )
mpToken->DecRef();
mpToken = new ScHybridCellToken( f, aString, aFormula, false);
mpToken->IncRef();
+ mbNoneRefCnt = false;
}
}
else
{
mfValue = f;
mbToken = false;
+ mbNoneRefCnt = false;
meMultiline = MULTILINE_FALSE;
mbValueCached = true;
}
@@ -585,6 +593,7 @@ void ScFormulaResult::SetHybridString( const svl::SharedString& rStr )
mpToken = new ScHybridCellToken( f, rStr, aFormula, false);
mpToken->IncRef();
mbToken = true;
+ mbNoneRefCnt = false;
}
void ScFormulaResult::SetHybridEmptyDisplayedAsString()
@@ -602,6 +611,7 @@ void ScFormulaResult::SetHybridEmptyDisplayedAsString()
mpToken = new ScHybridCellToken( f, aStr, aFormula, true);
mpToken->IncRef();
mbToken = true;
+ mbNoneRefCnt = false;
}
void ScFormulaResult::SetHybridFormula( const OUString & rFormula )
@@ -615,6 +625,7 @@ void ScFormulaResult::SetHybridFormula( const OUString & rFormula )
mpToken = new ScHybridCellToken( f, aStr, rFormula, false);
mpToken->IncRef();
mbToken = true;
+ mbNoneRefCnt = false;
}
void ScFormulaResult::SetMatrix( SCCOL nCols, SCROW nRows, const ScConstMatrixRef& pMat, const formula::FormulaToken* pUL )
@@ -625,6 +636,7 @@ void ScFormulaResult::SetMatrix( SCCOL nCols, SCROW nRows, const ScConstMatrixRe
mpToken = new ScMatrixFormulaCellToken(nCols, nRows, pMat, pUL);
mpToken->IncRef();
mbToken = true;
+ mbNoneRefCnt = false;
}
const ScMatrixFormulaCellToken* ScFormulaResult::GetMatrixFormulaCellToken() const
@@ -638,4 +650,17 @@ ScMatrixFormulaCellToken* ScFormulaResult::GetMatrixFormulaCellTokenNonConst()
return const_cast<ScMatrixFormulaCellToken*>( GetMatrixFormulaCellToken());
}
+// If a token from the original tokens, supplied to a parallel group calculation
+// while RefCounting was disabled for those tokens, ends up as a FormulaResult
+// token, then fix up the ref count now
+void ScFormulaResult::HandleStuffAfterParallelCalculation()
+{
+ if (mbNoneRefCnt)
+ {
+ assert(mbToken && mpToken && mpToken->GetRefCntPolicy() != formula::RefCntPolicy::None);
+ mpToken->IncRef();
+ mbNoneRefCnt = false;
+ }
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */