Kaynağa Gözat

meta: avoid a (maybe) UB in meta_any

Michele Caini 4 yıl önce
ebeveyn
işleme
5b3fd7537e
1 değiştirilmiş dosya ile 23 ekleme ve 19 silme
  1. 23 19
      src/entt/meta/meta.hpp

+ 23 - 19
src/entt/meta/meta.hpp

@@ -155,7 +155,7 @@ class meta_any {
     using vtable_type = void(const operation, const any &, void *);
 
     template<typename Type>
-    static void basic_vtable([[maybe_unused]] const operation op, [[maybe_unused]] const any &from, [[maybe_unused]] void *to) {
+    static void basic_vtable([[maybe_unused]] const operation op, [[maybe_unused]] const any &value, [[maybe_unused]] void *other) {
         static_assert(std::is_same_v<std::remove_reference_t<std::remove_const_t<Type>>, Type>, "Invalid type");
 
         if constexpr(!std::is_void_v<Type>) {
@@ -163,21 +163,21 @@ class meta_any {
             case operation::deref:
                 if constexpr(is_meta_pointer_like_v<Type>) {
                     if constexpr(std::is_function_v<std::remove_const_t<typename std::pointer_traits<Type>::element_type>>) {
-                        *static_cast<meta_any *>(to) = any_cast<Type>(from);
+                        *static_cast<meta_any *>(other) = any_cast<Type>(value);
                     } else if constexpr(!std::is_same_v<std::remove_const_t<typename std::pointer_traits<Type>::element_type>, void>) {
-                        using in_place_type = decltype(adl_meta_pointer_like<Type>::dereference(any_cast<const Type &>(from)));
-                        static_cast<meta_any *>(to)->emplace<in_place_type>(adl_meta_pointer_like<Type>::dereference(any_cast<const Type &>(from)));
+                        using in_place_type = decltype(adl_meta_pointer_like<Type>::dereference(any_cast<const Type &>(value)));
+                        static_cast<meta_any *>(other)->emplace<in_place_type>(adl_meta_pointer_like<Type>::dereference(any_cast<const Type &>(value)));
                     }
                 }
                 break;
             case operation::seq:
                 if constexpr(is_complete_v<meta_sequence_container_traits<Type>>) {
-                    *static_cast<meta_sequence_container *>(to) = {std::in_place_type<Type>, std::move(const_cast<any &>(from))};
+                    *static_cast<meta_sequence_container *>(other) = {std::in_place_type<Type>, std::move(const_cast<any &>(value))};
                 }
                 break;
             case operation::assoc:
                 if constexpr(is_complete_v<meta_associative_container_traits<Type>>) {
-                    *static_cast<meta_associative_container *>(to) = {std::in_place_type<Type>, std::move(const_cast<any &>(from))};
+                    *static_cast<meta_associative_container *>(other) = {std::in_place_type<Type>, std::move(const_cast<any &>(value))};
                 }
                 break;
             }
@@ -509,15 +509,17 @@ public:
      * @return A sequence container proxy for the underlying object.
      */
     [[nodiscard]] meta_sequence_container as_sequence_container() ENTT_NOEXCEPT {
+        any detached = storage.as_ref();
         meta_sequence_container proxy;
-        vtable(operation::seq, storage.as_ref(), &proxy);
+        vtable(operation::seq, detached, &proxy);
         return proxy;
     }
 
     /*! @copydoc as_sequence_container */
     [[nodiscard]] meta_sequence_container as_sequence_container() const ENTT_NOEXCEPT {
+        any detached = storage.as_ref();
         meta_sequence_container proxy;
-        vtable(operation::seq, storage.as_ref(), &proxy);
+        vtable(operation::seq, detached, &proxy);
         return proxy;
     }
 
@@ -526,15 +528,17 @@ public:
      * @return An associative container proxy for the underlying object.
      */
     [[nodiscard]] meta_associative_container as_associative_container() ENTT_NOEXCEPT {
+        any detached = storage.as_ref();
         meta_associative_container proxy;
-        vtable(operation::assoc, storage.as_ref(), &proxy);
+        vtable(operation::assoc, detached, &proxy);
         return proxy;
     }
 
     /*! @copydoc as_associative_container */
     [[nodiscard]] meta_associative_container as_associative_container() const ENTT_NOEXCEPT {
+        any detached = storage.as_ref();
         meta_associative_container proxy;
-        vtable(operation::assoc, storage.as_ref(), &proxy);
+        vtable(operation::assoc, detached, &proxy);
         return proxy;
     }
 
@@ -1463,13 +1467,13 @@ class meta_sequence_container::meta_iterator {
     using vtable_type = void(const operation, const any &, void *);
 
     template<typename It>
-    static void basic_vtable(const operation op, const any &from, void *to) {
+    static void basic_vtable(const operation op, const any &value, void *other) {
         switch(op) {
         case operation::incr:
-            ++any_cast<It &>(const_cast<any &>(from));
+            ++any_cast<It &>(const_cast<any &>(value));
             break;
         case operation::deref:
-            static_cast<meta_any *>(to)->emplace<typename std::iterator_traits<It>::reference>(*any_cast<const It &>(from));
+            static_cast<meta_any *>(other)->emplace<typename std::iterator_traits<It>::reference>(*any_cast<const It &>(value));
             break;
         }
     }
@@ -1663,18 +1667,18 @@ class meta_associative_container::meta_iterator {
     using vtable_type = void(const operation, const any &, void *);
 
     template<bool KeyOnly, typename It>
-    static void basic_vtable(const operation op, const any &from, void *to) {
+    static void basic_vtable(const operation op, const any &value, void *other) {
         switch(op) {
         case operation::incr:
-            ++any_cast<It &>(const_cast<any &>(from));
+            ++any_cast<It &>(const_cast<any &>(value));
             break;
         case operation::deref:
-            const auto &it = any_cast<const It &>(from);
+            const auto &it = any_cast<const It &>(value);
             if constexpr(KeyOnly) {
-                static_cast<std::pair<meta_any, meta_any> *>(to)->first.emplace<decltype(*it)>(*it);
+                static_cast<std::pair<meta_any, meta_any> *>(other)->first.emplace<decltype(*it)>(*it);
             } else {
-                static_cast<std::pair<meta_any, meta_any> *>(to)->first.emplace<decltype((it->first))>(it->first);
-                static_cast<std::pair<meta_any, meta_any> *>(to)->second.emplace<decltype((it->second))>(it->second);
+                static_cast<std::pair<meta_any, meta_any> *>(other)->first.emplace<decltype((it->first))>(it->first);
+                static_cast<std::pair<meta_any, meta_any> *>(other)->second.emplace<decltype((it->second))>(it->second);
             }
             break;
         }