summaryrefslogtreecommitdiff
path: root/codemaker/source
diff options
context:
space:
mode:
authorStephan Bergmann <sbergman@redhat.com>2022-12-02 17:01:02 +0100
committerStephan Bergmann <sbergman@redhat.com>2022-12-03 07:09:38 +0000
commit485c9d4f0e59e13e772da8f8a7975f0ddd77c33e (patch)
tree49771712d9488167ba69184e494eaafb470fad9b /codemaker/source
parent8f34b0d40e149b7274a1aa4ce0b33ddbf825ee52 (diff)
Clarify the use of untools::WeakReference
...which had been introduced in 78040af9acea0ab681aa54ff23844b647bc9b4f3 "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>
Diffstat (limited to 'codemaker/source')
-rw-r--r--codemaker/source/cppumaker/cpputype.cxx12
1 files changed, 10 insertions, 2 deletions
diff --git a/codemaker/source/cppumaker/cpputype.cxx b/codemaker/source/cppumaker/cpputype.cxx
index 03fcd033beca..2c8f938e6bb1 100644
--- a/codemaker/source/cppumaker/cpputype.cxx
+++ b/codemaker/source/cppumaker/cpputype.cxx
@@ -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