From 7d6b6e78744a97943cacadc76a811a37ea528736 Mon Sep 17 00:00:00 2001 From: acki-m <acki-m@users.noreply.github.com> Date: Wed, 21 Nov 2018 22:59:41 +0100 Subject: [PATCH] Fix crash for unloading plugins base types (#204) The base type was removed first and was not removed from the list of base types on every other type. This lead to a crash. fixes #199 --- src/rttr/detail/type/type_register.cpp | 14 ++++++++++++++ src/rttr/detail/type/type_register_p.h | 3 +++ 2 files changed, 17 insertions(+) diff --git a/src/rttr/detail/type/type_register.cpp b/src/rttr/detail/type/type_register.cpp index ace82b7b..25181117 100644 --- a/src/rttr/detail/type/type_register.cpp +++ b/src/rttr/detail/type/type_register.cpp @@ -589,6 +589,19 @@ void type_register_private::remove_derived_types_from_base_classes(type& t, cons ///////////////////////////////////////////////////////////////////////////////////////// +void type_register_private::remove_base_types_from_derived_classes(type& t, const std::vector<type>& derived_types) +{ + // here we get from all base types, the derived types list and remove the given type "t" + for (auto data : derived_types) + { + auto& class_data = data.m_type_data->m_class_data; + auto& base_types = class_data.m_base_types; + base_types.erase(std::remove_if(base_types.begin(), base_types.end(), [t](type base_t) { return base_t == t; })); + } +} + +///////////////////////////////////////////////////////////////////////////////////////// + void type_register_private::unregister_type(type_data* info) RTTR_NOEXCEPT { // REMARK: the base_types has to be provided as argument explicitely and cannot be retrieve via the type_data itself, @@ -613,6 +626,7 @@ void type_register_private::unregister_type(type_data* info) RTTR_NOEXCEPT type obj_t(info); remove_container_item(m_type_list, obj_t); remove_derived_types_from_base_classes(obj_t, info->m_class_data.m_base_types); + remove_base_types_from_derived_classes(obj_t, info->m_class_data.m_derived_types); m_orig_name_to_id.erase(info->type_name); m_custom_name_to_id.erase(info->name); } diff --git a/src/rttr/detail/type/type_register_p.h b/src/rttr/detail/type/type_register_p.h index 9cc28505..93188251 100644 --- a/src/rttr/detail/type/type_register_p.h +++ b/src/rttr/detail/type/type_register_p.h @@ -203,6 +203,9 @@ class RTTR_LOCAL type_register_private //! This will remove from all base classes the derived types (e.g. because of type unloaded) void remove_derived_types_from_base_classes(type& t, const std::vector<type>& base_types); + //! This will remove from all derived classes the base types (e.g. because of type unloaded) + void remove_base_types_from_derived_classes(type& t, const std::vector<type>& derived_types); + /*! A helper class to register the registration managers. * This class is needed in order to avoid that the registration_manager instance's * are trying to deregister its content, although the RTTR library is already unloaded.