diff options
author | Volker Hilsheimer <[email protected]> | 2024-06-12 09:40:44 +0200 |
---|---|---|
committer | Volker Hilsheimer <[email protected]> | 2024-06-20 03:53:32 +0200 |
commit | 691f6b5b0c9dc69f8d019abc53747e7a6bbf6ef8 (patch) | |
tree | 8549ede3d34c88568c8675ac0265d4a512906bf2 | |
parent | cf9b8b4633663d764325693ef7cd4e599a99e9ea (diff) |
JNI: don't inherit declared types from JObject
JObjectBase has a protected destructor, but JObject doesn't, so
inheriting from it might result in UB. Declare the Type as an alias to
JObject<TypeTag> instead. Specialize the traits for the TypeTag, and
add a partial specialization of the traits for JObject<T>.
Adjust the return type of the named constructors of JObject.
Pick-to: 6.8
Change-Id: Ibe74c3cd3b3a2a81779117dd2d228684c365a845
Reviewed-by: Assam Boudjelthia <[email protected]>
-rw-r--r-- | src/corelib/kernel/qjniobject.h | 22 | ||||
-rw-r--r-- | src/corelib/kernel/qjnitypes.h | 10 |
2 files changed, 22 insertions, 10 deletions
diff --git a/src/corelib/kernel/qjniobject.h b/src/corelib/kernel/qjniobject.h index af6c54e5aac..45f84afd0d6 100644 --- a/src/corelib/kernel/qjniobject.h +++ b/src/corelib/kernel/qjniobject.h @@ -720,7 +720,7 @@ public: ~JObject() = default; template<typename Arg, typename ...Args - , std::enable_if_t<!std::is_same_v<Arg, JObject>, bool> = true + , std::enable_if_t<!std::is_same_v<q20::remove_cvref_t<Arg>, JObject>, bool> = true , IfValidSignatureTypes<Arg, Args...> = true > explicit JObject(Arg && arg, Args &&...args) @@ -729,10 +729,19 @@ public: {} // named constructors avoid ambiguities - static Type fromJObject(jobject object) { return Type(object); } + static JObject fromJObject(jobject object) + { + return JObject(object); + } template <typename ...Args> - static Type construct(Args &&...args) { return Type(std::forward<Args>(args)...); } - static Type fromLocalRef(jobject lref) { return Type(QJniObject::fromLocalRef(lref)); } + static JObject construct(Args &&...args) + { + return JObject(std::forward<Args>(args)...); + } + static JObject fromLocalRef(jobject lref) + { + return JObject(QJniObject::fromLocalRef(lref)); + } static bool registerNativeMethods(std::initializer_list<JNINativeMethod> methods) { @@ -809,6 +818,11 @@ private: { return lhs.m_object == rhs.m_object; } Q_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE(JObject); }; + +template <typename T> struct Traits<JObject<T>> { + static constexpr auto signature() { return Traits<T>::signature(); } + static constexpr auto className() { return Traits<T>::className(); } +}; } // This cannot be included earlier as QJniArray is a QJniObject subclass, but it diff --git a/src/corelib/kernel/qjnitypes.h b/src/corelib/kernel/qjnitypes.h index 033445be6a7..5ad63badcd9 100644 --- a/src/corelib/kernel/qjnitypes.h +++ b/src/corelib/kernel/qjnitypes.h @@ -14,17 +14,15 @@ QT_BEGIN_NAMESPACE // QT_TECH_PREVIEW_API #define Q_DECLARE_JNI_TYPE_HELPER(Type) \ namespace QtJniTypes { \ -struct Type : JObject<Type> \ -{ \ - using JObject::JObject; \ -}; \ +struct Type##Tag { explicit Type##Tag() = default; }; \ +using Type = JObject<Type##Tag>; \ } \ // QT_TECH_PREVIEW_API #define Q_DECLARE_JNI_TYPE(Type, Signature) \ Q_DECLARE_JNI_TYPE_HELPER(Type) \ template<> \ -struct QtJniTypes::Traits<QtJniTypes::Type> { \ +struct QtJniTypes::Traits<QtJniTypes::Type##Tag> { \ static constexpr auto signature() \ { \ constexpr QtJniTypes::CTString sig(Signature); \ @@ -39,7 +37,7 @@ struct QtJniTypes::Traits<QtJniTypes::Type> { \ #define Q_DECLARE_JNI_CLASS(Type, Signature) \ Q_DECLARE_JNI_TYPE_HELPER(Type) \ template<> \ -struct QtJniTypes::Traits<QtJniTypes::Type> { \ +struct QtJniTypes::Traits<QtJniTypes::Type##Tag> { \ static constexpr auto className() \ { \ return QtJniTypes::CTString(Signature); \ |