From 2de5b6dd871ee5a72e14347920bab8a359a07cd1 Mon Sep 17 00:00:00 2001 From: skypjack Date: Wed, 17 Jul 2024 16:11:13 +0200 Subject: [PATCH] meta: self assignment for meta any --- src/entt/meta/meta.hpp | 15 ++++++--- test/entt/meta/meta_any.cpp | 61 +++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+), 5 deletions(-) diff --git a/src/entt/meta/meta.hpp b/src/entt/meta/meta.hpp index 2262dbdc1..535ab1bb3 100644 --- a/src/entt/meta/meta.hpp +++ b/src/entt/meta/meta.hpp @@ -328,11 +328,14 @@ public: * @return This meta any object. */ meta_any &operator=(const meta_any &other) { - release(); - storage = other.storage; - ctx = other.ctx; - node = other.node; - vtable = other.vtable; + if(this != &other) { + release(); + storage = other.storage; + ctx = other.ctx; + node = other.node; + vtable = other.vtable; + } + return *this; } @@ -342,6 +345,8 @@ public: * @return This meta any object. */ meta_any &operator=(meta_any &&other) noexcept { + ENTT_ASSERT(this != &other, "Self move assignment"); + release(); storage = std::move(other.storage); ctx = other.ctx; diff --git a/test/entt/meta/meta_any.cpp b/test/entt/meta/meta_any.cpp index 462c84d52..738c96475 100644 --- a/test/entt/meta/meta_any.cpp +++ b/test/entt/meta/meta_any.cpp @@ -277,6 +277,19 @@ TEST_F(MetaAny, SBOCopyAssignment) { ASSERT_NE(other, entt::meta_any{0}); } +TEST_F(MetaAny, SBOSelfCopyAssignment) { + entt::meta_any any{3}; + + // avoid warnings due to self-assignment + any = *&any; + + ASSERT_TRUE(any); + ASSERT_FALSE(any.try_cast()); + ASSERT_EQ(any.cast(), 3); + ASSERT_EQ(any, entt::meta_any{3}); + ASSERT_NE(any, entt::meta_any{0}); +} + TEST_F(MetaAny, SBOMoveConstruction) { entt::meta_any any{3}; entt::meta_any other{std::move(any)}; @@ -306,6 +319,13 @@ TEST_F(MetaAny, SBOMoveAssignment) { ASSERT_NE(other, entt::meta_any{0}); } +ENTT_DEBUG_TEST_F(MetaAnyDeathTest, SBOSelfMoveAssignment) { + entt::meta_any any{3}; + + // avoid warnings due to self-assignment + ASSERT_DEATH(any = std::move(*&any), ""); +} + TEST_F(MetaAny, SBODirectAssignment) { entt::meta_any any{}; any = 3; @@ -547,6 +567,20 @@ TEST_F(MetaAny, NoSBOCopyAssignment) { ASSERT_NE(other, fat{}); } +TEST_F(MetaAny, NoSBOSelfCopyAssignment) { + const fat instance{.1, .2, .3, .4}; + entt::meta_any any{instance}; + + // avoid warnings due to self-assignment + any = *&any; + + ASSERT_TRUE(any); + ASSERT_FALSE(any.try_cast()); + ASSERT_EQ(any.cast(), instance); + ASSERT_EQ(any, entt::meta_any{instance}); + ASSERT_NE(any, fat{}); +} + TEST_F(MetaAny, NoSBOMoveConstruction) { const fat instance{.1, .2, .3, .4}; entt::meta_any any{instance}; @@ -578,6 +612,14 @@ TEST_F(MetaAny, NoSBOMoveAssignment) { ASSERT_NE(other, fat{}); } +ENTT_DEBUG_TEST_F(MetaAnyDeathTest, NoSBOSelfMoveAssignment) { + const fat instance{.1, .2, .3, .4}; + entt::meta_any any{instance}; + + // avoid warnings due to self-assignment + ASSERT_DEATH(any = std::move(*&any), ""); +} + TEST_F(MetaAny, NoSBODirectAssignment) { const fat instance{.1, .2, .3, .4}; entt::meta_any any{}; @@ -755,6 +797,18 @@ TEST_F(MetaAny, VoidCopyAssignment) { ASSERT_EQ(other, entt::meta_any{std::in_place_type}); } +TEST_F(MetaAny, VoidSelfCopyAssignment) { + entt::meta_any any{std::in_place_type}; + + // avoid warnings due to self-assignment + any = *&any; + + ASSERT_TRUE(any); + ASSERT_FALSE(any.try_cast()); + ASSERT_EQ(any.type(), entt::resolve()); + ASSERT_EQ(any, entt::meta_any{std::in_place_type}); +} + TEST_F(MetaAny, VoidMoveConstruction) { entt::meta_any any{std::in_place_type}; const entt::meta_any other{std::move(any)}; @@ -780,6 +834,13 @@ TEST_F(MetaAny, VoidMoveAssignment) { ASSERT_EQ(other, entt::meta_any{std::in_place_type}); } +ENTT_DEBUG_TEST_F(MetaAnyDeathTest, VoidSelfMoveAssignment) { + entt::meta_any any{std::in_place_type}; + + // avoid warnings due to self-assignment + ASSERT_DEATH(any = std::move(*&any), ""); +} + TEST_F(MetaAny, SBOMoveInvalidate) { entt::meta_any any{3}; entt::meta_any other{std::move(any)};