From 2048cbbfad35dd30a0fadb61a64f5d5a1ef66b9b Mon Sep 17 00:00:00 2001 From: Caolán McNamara Date: Mon, 18 Oct 2010 16:15:57 +0100 Subject: #i111793# make cppuhelper/interfacecontainer strict aliasing safe --- cppuhelper/inc/cppuhelper/interfacecontainer.h | 23 ++++-- cppuhelper/source/interfacecontainer.cxx | 108 ++++++++++++------------- 2 files changed, 71 insertions(+), 60 deletions(-) (limited to 'cppuhelper') diff --git a/cppuhelper/inc/cppuhelper/interfacecontainer.h b/cppuhelper/inc/cppuhelper/interfacecontainer.h index 3f5da6bd10dc..ee57127a4fca 100644 --- a/cppuhelper/inc/cppuhelper/interfacecontainer.h +++ b/cppuhelper/inc/cppuhelper/interfacecontainer.h @@ -44,6 +44,17 @@ namespace cppu { +namespace detail { + + union element_alias + { + ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > > *pAsSequence; + ::com::sun::star::uno::XInterface * pAsInterface; + element_alias() : pAsInterface(0) {} + }; + +} + //=================================================================== class OInterfaceContainerHelper; /** @@ -95,7 +106,9 @@ public: private: OInterfaceContainerHelper & rCont; sal_Bool bIsList; - void * pData; + + detail::element_alias aData; + sal_Int32 nRemain; OInterfaceIteratorHelper( const OInterfaceIteratorHelper & ) SAL_THROW( () ); @@ -222,14 +235,14 @@ public: private: friend class OInterfaceIteratorHelper; /** - bIsList == TRUE -> pData of type Sequence< XInterfaceSequence >, - otherwise pData == of type (XEventListener *) + bIsList == TRUE -> aData.pAsSequence of type Sequence< XInterfaceSequence >, + otherwise aData.pAsInterface == of type (XEventListener *) */ - void * pData; + detail::element_alias aData; ::osl::Mutex & rMutex; /** TRUE -> used by an iterator. */ sal_Bool bInUse; - /** TRUE -> pData is of type Sequence< XInterfaceSequence >. */ + /** TRUE -> aData.pAsSequence is of type Sequence< XInterfaceSequence >. */ sal_Bool bIsList; OInterfaceContainerHelper( const OInterfaceContainerHelper & ) SAL_THROW( () ); diff --git a/cppuhelper/source/interfacecontainer.cxx b/cppuhelper/source/interfacecontainer.cxx index e10b018617b5..53a06f3112c9 100644 --- a/cppuhelper/source/interfacecontainer.cxx +++ b/cppuhelper/source/interfacecontainer.cxx @@ -100,15 +100,15 @@ OInterfaceIteratorHelper::OInterfaceIteratorHelper( OInterfaceContainerHelper & // worst case, two iterators at the same time rCont.copyAndResetInUse(); bIsList = rCont_.bIsList; - pData = rCont_.pData; + aData = rCont_.aData; if( bIsList ) { rCont.bInUse = sal_True; - nRemain = ((Sequence< Reference< XInterface > >*)pData)->getLength(); + nRemain = aData.pAsSequence->getLength(); } - else if( pData ) + else if( aData.pAsInterface ) { - ((XInterface *)pData)->acquire(); + aData.pAsInterface->acquire(); nRemain = 1; } else @@ -121,7 +121,7 @@ OInterfaceIteratorHelper::~OInterfaceIteratorHelper() SAL_THROW( () ) { MutexGuard aGuard( rCont.rMutex ); // bResetInUse protect the iterator against recursion - bShared = pData == rCont.pData && rCont.bIsList; + bShared = aData.pAsSequence == rCont.aData.pAsSequence && rCont.bIsList; if( bShared ) { OSL_ENSURE( rCont.bInUse, "OInterfaceContainerHelper must be in use" ); @@ -133,10 +133,10 @@ OInterfaceIteratorHelper::~OInterfaceIteratorHelper() SAL_THROW( () ) { if( bIsList ) // Sequence owned by the iterator - delete (Sequence< Reference< XInterface > >*)pData; - else if( pData ) + delete aData.pAsSequence; + else if( aData.pAsInterface ) // Interface is acquired by the iterator - ((XInterface*)pData)->release(); + aData.pAsInterface->release(); } } @@ -147,9 +147,9 @@ XInterface * OInterfaceIteratorHelper::next() SAL_THROW( () ) nRemain--; if( bIsList ) // typecase to const,so the getArray method is faster - return ((const Sequence< Reference< XInterface > >*)pData)->getConstArray()[nRemain].get(); - else if( pData ) - return (XInterface*)pData; + return aData.pAsSequence->getConstArray()[nRemain].get(); + else if( aData.pAsInterface ) + return aData.pAsInterface; } // exception return 0; @@ -160,15 +160,14 @@ void OInterfaceIteratorHelper::remove() SAL_THROW( () ) if( bIsList ) { OSL_ASSERT( nRemain >= 0 && - nRemain < ((const Sequence< Reference< XInterface > >*)pData)->getLength() ); - XInterface * p = - ((const Sequence< Reference< XInterface > >*)pData)->getConstArray()[nRemain].get(); + nRemain < aData.pAsSequence->getLength() ); + XInterface * p = aData.pAsSequence->getConstArray()[nRemain].get(); rCont.removeInterface( * reinterpret_cast< const Reference< XInterface > * >( &p ) ); } else { OSL_ASSERT( 0 == nRemain ); - rCont.removeInterface( * reinterpret_cast< const Reference< XInterface > * >(&pData)); + rCont.removeInterface( * reinterpret_cast< const Reference< XInterface > * >(&aData.pAsInterface)); } } @@ -178,8 +177,7 @@ void OInterfaceIteratorHelper::remove() SAL_THROW( () ) OInterfaceContainerHelper::OInterfaceContainerHelper( Mutex & rMutex_ ) SAL_THROW( () ) - : pData( 0 ) - , rMutex( rMutex_ ) + : rMutex( rMutex_ ) , bInUse( sal_False ) , bIsList( sal_False ) { @@ -189,17 +187,17 @@ OInterfaceContainerHelper::~OInterfaceContainerHelper() SAL_THROW( () ) { OSL_ENSURE( !bInUse, "~OInterfaceContainerHelper but is in use" ); if( bIsList ) - delete (Sequence< Reference< XInterface > >*)pData; - else if( pData ) - ((XInterface*)pData)->release(); + delete aData.pAsSequence; + else if( aData.pAsInterface ) + aData.pAsInterface->release(); } sal_Int32 OInterfaceContainerHelper::getLength() const SAL_THROW( () ) { MutexGuard aGuard( rMutex ); if( bIsList ) - return ((Sequence< Reference< XInterface > >*)pData)->getLength(); - else if( pData ) + return aData.pAsSequence->getLength(); + else if( aData.pAsInterface ) return 1; return 0; } @@ -208,10 +206,10 @@ Sequence< Reference > OInterfaceContainerHelper::getElements() const { MutexGuard aGuard( rMutex ); if( bIsList ) - return *(Sequence< Reference< XInterface > >*)pData; - else if( pData ) + return *aData.pAsSequence; + else if( aData.pAsInterface ) { - Reference x( (XInterface *)pData ); + Reference x( aData.pAsInterface ); return Sequence< Reference< XInterface > >( &x, 1 ); } return Sequence< Reference< XInterface > >(); @@ -225,9 +223,9 @@ void OInterfaceContainerHelper::copyAndResetInUse() SAL_THROW( () ) // this should be the worst case. If a iterator is active // and a new Listener is added. if( bIsList ) - pData = new Sequence< Reference< XInterface > >( *(Sequence< Reference< XInterface > >*)pData ); - else if( pData ) - ((XInterface*)pData)->acquire(); + aData.pAsSequence = new Sequence< Reference< XInterface > >( *aData.pAsSequence ); + else if( aData.pAsInterface ) + aData.pAsInterface->acquire(); bInUse = sal_False; } @@ -242,25 +240,25 @@ sal_Int32 OInterfaceContainerHelper::addInterface( const Reference & if( bIsList ) { - sal_Int32 nLen = ((Sequence< Reference< XInterface > >*)pData)->getLength(); - realloc( *(Sequence< Reference< XInterface > >*)pData, nLen +1 ); - ((Sequence< Reference< XInterface > >*)pData)->getArray()[ nLen ] = rListener; + sal_Int32 nLen = aData.pAsSequence->getLength(); + realloc( *aData.pAsSequence, nLen +1 ); + aData.pAsSequence->getArray()[ nLen ] = rListener; return nLen +1; } - else if( pData ) + else if( aData.pAsInterface ) { Sequence< Reference< XInterface > > * pSeq = new Sequence< Reference< XInterface > >( 2 ); Reference * pArray = pSeq->getArray(); - pArray[0] = (XInterface *)pData; + pArray[0] = aData.pAsInterface; pArray[1] = rListener; - ((XInterface *)pData)->release(); - pData = pSeq; + aData.pAsInterface->release(); + aData.pAsSequence = pSeq; bIsList = sal_True; return 2; } else { - pData = rListener.get(); + aData.pAsInterface = rListener.get(); if( rListener.is() ) rListener->acquire(); return 1; @@ -276,8 +274,8 @@ sal_Int32 OInterfaceContainerHelper::removeInterface( const Reference * pL = ((const Sequence< Reference< XInterface > >*)pData)->getConstArray(); - sal_Int32 nLen = ((Sequence< Reference< XInterface > >*)pData)->getLength(); + const Reference * pL = aData.pAsSequence->getConstArray(); + sal_Int32 nLen = aData.pAsSequence->getLength(); sal_Int32 i; for( i = 0; i < nLen; i++ ) { @@ -285,7 +283,7 @@ sal_Int32 OInterfaceContainerHelper::removeInterface( const Reference >*)pData, i ); + sequenceRemoveElementAt( *aData.pAsSequence, i ); break; } } @@ -297,30 +295,30 @@ sal_Int32 OInterfaceContainerHelper::removeInterface( const Reference >*)pData, i ); + sequenceRemoveElementAt(*aData.pAsSequence, i ); break; } } } - if( ((Sequence< Reference< XInterface > >*)pData)->getLength() == 1 ) + if( aData.pAsSequence->getLength() == 1 ) { - XInterface * p = ((const Sequence< Reference< XInterface > >*)pData)->getConstArray()[0].get(); + XInterface * p = aData.pAsSequence->getConstArray()[0].get(); p->acquire(); - delete (Sequence< Reference< XInterface > >*)pData; - pData = p; + delete aData.pAsSequence; + aData.pAsInterface = p; bIsList = sal_False; return 1; } else - return ((Sequence< Reference< XInterface > >*)pData)->getLength(); + return aData.pAsSequence->getLength(); } - else if( pData && Reference( (XInterface*)pData ) == rListener ) + else if( aData.pAsInterface && Reference( aData.pAsInterface ) == rListener ) { - ((XInterface *)pData)->release(); - pData = 0; + aData.pAsInterface->release(); + aData.pAsInterface = 0; } - return pData ? 1 : 0; + return aData.pAsInterface ? 1 : 0; } void OInterfaceContainerHelper::disposeAndClear( const EventObject & rEvt ) SAL_THROW( () ) @@ -329,10 +327,10 @@ void OInterfaceContainerHelper::disposeAndClear( const EventObject & rEvt ) SAL_ OInterfaceIteratorHelper aIt( *this ); // Release container, in case new entries come while disposing OSL_ENSURE( !bIsList || bInUse, "OInterfaceContainerHelper not in use" ); - if( !bIsList && pData ) - ((XInterface *)pData)->release(); + if( !bIsList && aData.pAsInterface ) + aData.pAsInterface->release(); // set the member to null, use the iterator to delete the values - pData = NULL; + aData.pAsInterface = NULL; bIsList = sal_False; bInUse = sal_False; aGuard.clear(); @@ -359,10 +357,10 @@ void OInterfaceContainerHelper::clear() SAL_THROW( () ) OInterfaceIteratorHelper aIt( *this ); // Release container, in case new entries come while disposing OSL_ENSURE( !bIsList || bInUse, "OInterfaceContainerHelper not in use" ); - if( !bIsList && pData ) - ((XInterface *)pData)->release(); + if( !bIsList && aData.pAsInterface ) + aData.pAsInterface->release(); // set the member to null, use the iterator to delete the values - pData = 0; + aData.pAsInterface = 0; bIsList = sal_False; bInUse = sal_False; // release mutex before aIt destructor call -- cgit v1.2.3