diff options
Diffstat (limited to 'basic/source/comp/dim.cxx')
-rw-r--r-- | basic/source/comp/dim.cxx | 55 |
1 files changed, 45 insertions, 10 deletions
diff --git a/basic/source/comp/dim.cxx b/basic/source/comp/dim.cxx index 17eef0a263a5..cbc25b0152b4 100644 --- a/basic/source/comp/dim.cxx +++ b/basic/source/comp/dim.cxx @@ -431,9 +431,17 @@ void SbiParser::DefVar( SbiOpcode eOp, bool bStatic ) } else { + // tdf#145371, tdf#136755 - only delete the variable beforehand REDIM + if (eOp == SbiOpcode::REDIM_) + { + SbiExpression aExpr(this, *pDef, nullptr); + aExpr.Gen(); + aGen.Gen(bVBASupportOn ? SbiOpcode::ERASE_CLEAR_ : SbiOpcode::ERASE_); + } + pDef->SetDims( pDim->GetDims() ); - SbiExpression aExpr( this, *pDef, std::move(pDim) ); - aExpr.Gen(); + SbiExpression aExpr2( this, *pDef, std::move(pDim) ); + aExpr2.Gen(); aGen.Gen( SbiOpcode::DCREATE_, pDef->GetId(), pDef->GetTypeId() ); } } @@ -441,12 +449,39 @@ void SbiParser::DefVar( SbiOpcode eOp, bool bStatic ) { SbiExpression aExpr( this, *pDef ); aExpr.Gen(); + + /* tdf#88442 + * Don't initialize a + * Global X as New SomeObjectType + * if it has already been initialized. + * This approach relies on JUMPT evaluating Object->NULL as being 'false' + * But the effect of this code is similar to inserting + * If IsNull(YourGlobal) + * Set YourGlobal = ' new obj + * End If ' If IsNull(YourGlobal) + * Only for globals. For locals that check is skipped as it's unnecessary + */ + sal_uInt32 come_from = 0; + if ( pDef->GetScope() == SbGLOBAL ) + { + come_from = aGen.Gen( SbiOpcode::JUMPT_, 0 ); + aGen.Gen( SbiOpcode::FIND_, pDef->GetId(), pDef->GetTypeId() ); + } + SbiOpcode eOp_ = pDef->IsNew() ? SbiOpcode::CREATE_ : SbiOpcode::TCREATE_; aGen.Gen( eOp_, pDef->GetId(), pDef->GetTypeId() ); if ( bVBASupportOn ) aGen.Gen( SbiOpcode::VBASET_ ); else aGen.Gen( SbiOpcode::SET_ ); + + if ( come_from ) + { + // See other tdf#88442 comment above where come_from is + // initialized. This is effectively 'inserting' the + // End If ' If IsNull(YourGlobal) + aGen.BackChain( come_from ); + } } } else @@ -636,12 +671,12 @@ void SbiParser::DefType() } else if ( !bCompatible ) ub += nBase; - pArray->AddDim32( lb, ub ); + pArray->AddDim(lb, ub); } pArray->setHasFixedSize( true ); } else - pArray->unoAddDim32( 0, -1 ); // variant array + pArray->unoAddDim(0, -1); // variant array SbxFlagBits nSavFlags = pTypeElem->GetFlags(); // need to reset the FIXED flag // when calling PutObject ( because the type will not match Object ) @@ -659,12 +694,12 @@ void SbiParser::DefType() SbxObject* pTypeObj = static_cast< SbxObject* >( rTypeArray->Find( aTypeName, SbxClassType::Object ) ); if( pTypeObj != nullptr ) { - SbxObject* pCloneObj = cloneTypeObjectImpl( *pTypeObj ); - pTypeElem->PutObject( pCloneObj ); + SbxObjectRef pCloneObj = cloneTypeObjectImpl( *pTypeObj ); + pTypeElem->PutObject( pCloneObj.get() ); } } } - pTypeMembers->Insert32( pTypeElem, pTypeMembers->Count32() ); + pTypeMembers->Insert(pTypeElem, pTypeMembers->Count()); } } } @@ -672,7 +707,7 @@ void SbiParser::DefType() pType->Remove( "Name", SbxClassType::DontCare ); pType->Remove( "Parent", SbxClassType::DontCare ); - rTypeArray->Insert32 (pType,rTypeArray->Count32()); + rTypeArray->Insert(pType, rTypeArray->Count()); } @@ -796,14 +831,14 @@ void SbiParser::DefEnum( bool bPrivate ) pEnumElem->PutLong( nCurrentEnumValue ); pEnumElem->ResetFlag( SbxFlagBits::Write ); pEnumElem->SetFlag( SbxFlagBits::Const ); - pEnumMembers->Insert32( pEnumElem, pEnumMembers->Count32() ); + pEnumMembers->Insert(pEnumElem, pEnumMembers->Count()); } } pEnum->Remove( "Name", SbxClassType::DontCare ); pEnum->Remove( "Parent", SbxClassType::DontCare ); - rEnumArray->Insert32( pEnum, rEnumArray->Count32() ); + rEnumArray->Insert(pEnum, rEnumArray->Count()); } |