From 3453879aac287670db6f700ab98b2519912e9355 Mon Sep 17 00:00:00 2001 From: Eike Rathke Date: Fri, 13 Jun 2014 10:50:27 +0200 Subject: resolved fdo#79957 propagate ForceArray through jump tokens ForceArray parameters weren't propagated and enforced to array arguments on svJump tokens (FormulaJumpToken), namely IF, CHOOSE, IFERROR and IFNA. Change-Id: Icf9074f11b826655a52858d778d9a0122d207aa4 (cherry picked from commit c9d037e5e8e5850e9c69372580e7a506b573fc2a) --- formula/source/core/api/token.cxx | 7 ++++++- include/formula/FormulaCompiler.hxx | 6 +++--- include/formula/token.hxx | 9 +++++++-- sc/source/core/inc/interpre.hxx | 2 +- 4 files changed, 17 insertions(+), 7 deletions(-) diff --git a/formula/source/core/api/token.cxx b/formula/source/core/api/token.cxx index 8da6dcebb255..0dd8d5c4d628 100644 --- a/formula/source/core/api/token.cxx +++ b/formula/source/core/api/token.cxx @@ -287,11 +287,16 @@ bool FormulaFAPToken::operator==( const FormulaToken& r ) const { return FormulaByteToken::operator==( r ) && pOrigToken == r.GetFAPOrigToken(); } + + short* FormulaJumpToken::GetJump() const { return pJump; } +bool FormulaJumpToken::HasForceArray() const { return bHasForceArray; } +void FormulaJumpToken::SetForceArray( bool b ) { bHasForceArray = b; } bool FormulaJumpToken::operator==( const FormulaToken& r ) const { return FormulaToken::operator==( r ) && pJump[0] == r.GetJump()[0] && - memcmp( pJump+1, r.GetJump()+1, pJump[0] * sizeof(short) ) == 0; + memcmp( pJump+1, r.GetJump()+1, pJump[0] * sizeof(short) ) == 0 && + bHasForceArray == r.HasForceArray(); } FormulaJumpToken::~FormulaJumpToken() { diff --git a/include/formula/FormulaCompiler.hxx b/include/formula/FormulaCompiler.hxx index 81277c9ee4bb..a4fd1af678c2 100644 --- a/include/formula/FormulaCompiler.hxx +++ b/include/formula/FormulaCompiler.hxx @@ -356,9 +356,9 @@ private: static inline void ForceArrayOperator( FormulaTokenRef& rCurr, const FormulaTokenRef& rPrev ) { - if ( rPrev && rPrev->HasForceArray() && - rCurr->GetType() == svByte && rCurr->GetOpCode() != ocPush - && !rCurr->HasForceArray() ) + if ( rPrev && rPrev->HasForceArray() && rCurr->GetOpCode() != ocPush && + (rCurr->GetType() == svByte || rCurr->GetType() == svJump) && + !rCurr->HasForceArray() ) rCurr->SetForceArray( true); } diff --git a/include/formula/token.hxx b/include/formula/token.hxx index d1654cce5f12..2efba0db00d7 100644 --- a/include/formula/token.hxx +++ b/include/formula/token.hxx @@ -352,15 +352,18 @@ class FORMULA_DLLPUBLIC FormulaJumpToken : public FormulaToken { private: short* pJump; + bool bHasForceArray; public: FormulaJumpToken( OpCode e, short* p ) : - FormulaToken( formula::svJump , e) + FormulaToken( formula::svJump , e), + bHasForceArray( false) { pJump = new short[ p[0] + 1 ]; memcpy( pJump, p, (p[0] + 1) * sizeof(short) ); } FormulaJumpToken( const FormulaJumpToken& r ) : - FormulaToken( r ) + FormulaToken( r ), + bHasForceArray( r.bHasForceArray) { pJump = new short[ r.pJump[0] + 1 ]; memcpy( pJump, r.pJump, (r.pJump[0] + 1) * sizeof(short) ); @@ -369,6 +372,8 @@ public: virtual short* GetJump() const SAL_OVERRIDE; virtual bool operator==( const formula::FormulaToken& rToken ) const SAL_OVERRIDE; virtual FormulaToken* Clone() const SAL_OVERRIDE { return new FormulaJumpToken(*this); } + virtual bool HasForceArray() const SAL_OVERRIDE; + virtual void SetForceArray( bool b ) SAL_OVERRIDE; }; diff --git a/sc/source/core/inc/interpre.hxx b/sc/source/core/inc/interpre.hxx index 642699a5a0be..9122e0a67993 100644 --- a/sc/source/core/inc/interpre.hxx +++ b/sc/source/core/inc/interpre.hxx @@ -888,7 +888,7 @@ public: inline void ScInterpreter::MatrixDoubleRefToMatrix() { - if ( bMatrixFormula && GetStackType() == formula::svDoubleRef ) + if ( (bMatrixFormula || pCur->HasForceArray()) && GetStackType() == formula::svDoubleRef ) { GetTokenMatrixMap(); // make sure it exists, create if not. PopDoubleRefPushMatrix(); -- cgit