Clarify the use of untools::WeakReference
...which had been introduced in 78040af9ac
"loplugin:refcounting in sc" as a variation on css::uno::WeakReference from
include/cppuhelper/weakref.hxx, but without giving much of a rationale.
And, at least for --with-latest-c++ builds using a capable C++20 compiler,
ensure that the given interface_type is such that the static_cast and
dynamic_cast in the implementation of unotools::WeakReference::get are actually
sound: If interface_type could be a UNO interface type, that would imply that
the xInterface obtained from the underlying WeakReferenceHelper::get() could be
a proxy from the C++ UNO bridge, which could (a) be a proxy for only a subtype
of interface_type (e.g., just for XInterface), so that the static_cast would be
broken, and (b) be a proxy for which the vtable's RTTI slot is not set up (see
e.g. the ENABLE_RUNTIME_OPTIMIZATIONS code in
bridges::cpp_uno::shared::VtableFactory::initializeBlock in
bridges/source/cpp_uno/gcc3_linux_x86-64/cpp2uno.cxx), so that the dynamic_cast
could crash. (These issues can even happen when the given interface_type is a
C++ implementation class type, but the given object has been bridged over some
C++ to C++ UNO ("purpose") bridge, but lets leave it at that...)
This required adding some cppu::detail::isUnoInterfaceType predicate to the
include files generated by cppumaker, which can be useful in other places too.
(For the call to isUnoInterfaceType in the requires-clause of
unotools::WeakReference<interface_type>::get to give the correct answer, it is
important that interface_type is a complete type---i.e., the corresponding
codemaker-generated .hpp having been included if interface_type actually were a
UNO include type. But that is already nicely required by the call to
std::is_convertible_v in the implementation of that function, anyway.)
Change-Id: Ia5efd70085d2d6d45fa0995d00dc8def564bbe5f
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/143601
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
This commit is contained in:
@@ -1184,7 +1184,7 @@ void InterfaceType::dumpHppFile(
|
||||
out << "\n";
|
||||
addDefaultHxxIncludes(includes);
|
||||
includes.dump(out, &name_, !(m_cppuTypeLeak || m_cppuTypeDynamic));
|
||||
out << "\n";
|
||||
out << "\n#if defined LIBO_INTERNAL_ONLY\n#include <type_traits>\n#endif\n\n";
|
||||
dumpGetCppuType(out);
|
||||
out << "\n::css::uno::Type const & "
|
||||
<< codemaker::cpp::scopedCppName(u2b(name_))
|
||||
@@ -1194,7 +1194,15 @@ void InterfaceType::dumpHppFile(
|
||||
dumpType(out, name_, false, false, true);
|
||||
out << " >::get();\n";
|
||||
dec();
|
||||
out << "}\n\n#endif // "<< headerDefine << "\n";
|
||||
out << "}\n\n#if defined LIBO_INTERNAL_ONLY\nnamespace cppu::detail {\n";
|
||||
if (name_ == "com.sun.star.uno.XInterface") {
|
||||
out << "template<typename> struct IsUnoInterfaceType: ::std::false_type {};\n"
|
||||
"template<typename T> inline constexpr auto isUnoInterfaceType ="
|
||||
" IsUnoInterfaceType<T>::value;\n";
|
||||
}
|
||||
out << "template<> struct IsUnoInterfaceType<";
|
||||
dumpType(out, name_, false, false, true);
|
||||
out << ">: ::std::true_type {};\n}\n#endif\n\n#endif // "<< headerDefine << "\n";
|
||||
}
|
||||
|
||||
void InterfaceType::dumpAttributes(FileStream & out) const
|
||||
|
||||
@@ -42,7 +42,9 @@ namespace unotools
|
||||
behind it *is* thread-safe, so multiple threads can have their own
|
||||
WeakReferences to the same XWeak object.
|
||||
|
||||
@tparam interface_type type of interface
|
||||
@tparam interface_type Must be a C++ implementation class type, not a UNO interface type. (See
|
||||
the C++20 requires-clause on the get member. That clause is not put on the class as a whole to
|
||||
avoid overly tight requirements on when interface_type needs to be complete.)
|
||||
*/
|
||||
template <class interface_type>
|
||||
class SAL_WARN_UNUSED WeakReference : public com::sun::star::uno::WeakReferenceHelper
|
||||
@@ -113,6 +115,9 @@ public:
|
||||
@return hard reference or null, if the weakly referenced interface has gone
|
||||
*/
|
||||
rtl::Reference<interface_type> SAL_CALL get() const
|
||||
#if __cplusplus >= 202002L
|
||||
requires(!cppu::detail::isUnoInterfaceType<interface_type>)
|
||||
#endif
|
||||
{
|
||||
css::uno::Reference<css::uno::XInterface> xInterface = WeakReferenceHelper::get();
|
||||
// If XInterface is an ambiguous base of interface_type, we have to use dynamic_cast,
|
||||
|
||||
Reference in New Issue
Block a user