diff options
author | Stephan Bergmann <sbergman@redhat.com> | 2015-12-15 16:52:19 +0100 |
---|---|---|
committer | Andras Timar <andras.timar@collabora.com> | 2015-12-21 13:16:07 +0100 |
commit | 17581e166a20d8433b5c22ab3bc4902c3eb633bd (patch) | |
tree | 0533ad26459d42affa9a200b3c8ee46a07b8d524 /bridges | |
parent | 8d42566b24aa9bcd54075531189a37432a752f9c (diff) |
tdf#95903: Fix return value handling in msvc_win32_x86-64 bridge
...where a return value was double-deleted if it was "complex" (i.e., generated
by callee into caller-provided memory) but not related to UNO interface types
(so doesn't need any mapping, like sequence<css.beans.Property> returned by
css.beans.XPropertySetInfo.getProperties).
Change-Id: I4cfc16ba63022686afd016ef5b64419e8dee53a4
(cherry picked from commit 27f5679c84602713e74c947d88e72cfafc02fbc8)
Reviewed-on: https://gerrit.libreoffice.org/20723
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Michael Stahl <mstahl@redhat.com>
(cherry picked from commit 80acb57d5c60abd3a07b2674d1c30f926d311513)
Diffstat (limited to 'bridges')
-rw-r--r-- | bridges/source/cpp_uno/msvc_win32_x86-64/uno2cpp.cxx | 44 |
1 files changed, 30 insertions, 14 deletions
diff --git a/bridges/source/cpp_uno/msvc_win32_x86-64/uno2cpp.cxx b/bridges/source/cpp_uno/msvc_win32_x86-64/uno2cpp.cxx index 35ca9ebd22e6..ada36234eefd 100644 --- a/bridges/source/cpp_uno/msvc_win32_x86-64/uno2cpp.cxx +++ b/bridges/source/cpp_uno/msvc_win32_x86-64/uno2cpp.cxx @@ -17,6 +17,9 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ +#include <sal/config.h> + +#include <cassert> #include <malloc.h> @@ -77,16 +80,21 @@ static bool cpp_call( void * pAdjustedThisPtr = (void **)( pThis->getCppI() ) + aVtableSlot.offset; aCppParams[nCppParamIndex++].p = pAdjustedThisPtr; - bool bSimpleReturn = true; - if ( pReturnTD ) - { - if ( !bridges::cpp_uno::shared::isSimpleType( pReturnTD ) ) + enum class ReturnKind { Void, Simple, Complex, ComplexConvert }; + ReturnKind retKind; + if (pUnoReturn == nullptr) { + retKind = ReturnKind::Void; + } else { + assert(pReturnTD != nullptr); + if (bridges::cpp_uno::shared::isSimpleType(pReturnTD)) { + retKind = ReturnKind::Simple; + } else if (bridges::cpp_uno::shared::relatesToInterfaceType(pReturnTD)) { - // Complex return via ptr - bSimpleReturn = false; - aCppParams[nCppParamIndex++].p = - bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTD )? - alloca( pReturnTD->nSize ) : pUnoReturn; + retKind = ReturnKind::ComplexConvert; + aCppParams[nCppParamIndex++].p = alloca(pReturnTD->nSize); + } else { + retKind = ReturnKind::Complex; + aCppParams[nCppParamIndex++].p = pUnoReturn; } } @@ -267,16 +275,24 @@ static bool cpp_call( } // Return value - if ( !bSimpleReturn ) - { + switch (retKind) { + case ReturnKind::Void: + break; + case ReturnKind::Simple: + *(sal_Int64*)pUnoReturn = uRetVal.i; + break; + case ReturnKind::Complex: + assert(uRetVal.p == pUnoReturn); + break; + case ReturnKind::ComplexConvert: + assert(uRetVal.p == aCppParams[1].p); ::uno_copyAndConvertData( pUnoReturn, uRetVal.p, pReturnTD, pThis->getBridge()->getCpp2Uno() ); ::uno_destructData( - aCppParams[1].p, pReturnTD, cpp_release ); + uRetVal.p, pReturnTD, cpp_release ); + break; } - else if ( pUnoReturn ) - *(sal_Int64*)pUnoReturn = uRetVal.i; if ( pReturnTD ) TYPELIB_DANGER_RELEASE( pReturnTD ); |