From 56b4e480be533f997469314f8e76b504b430c0c1 Mon Sep 17 00:00:00 2001 From: Dieter Niklaus Date: Tue, 21 Feb 2023 11:49:46 +0100 Subject: [PATCH] Fix Tencent/rapidjson#1700 (GCC9 break: trying to memcpy C++ objects) --- include/rapidjson/document.h | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/include/rapidjson/document.h b/include/rapidjson/document.h index 2cd9a70a6..49bdf5a68 100644 --- a/include/rapidjson/document.h +++ b/include/rapidjson/document.h @@ -22,6 +22,8 @@ #include "internal/strfunc.h" #include "memorystream.h" #include "encodedstream.h" + +#include #include // placement new #include #ifdef __cpp_lib_three_way_comparison @@ -119,6 +121,9 @@ class GenericDocument; template class GenericMember { public: + // Allow default construction as it is needed during copying. + GenericMember() = default; + GenericValue name; //!< name of member (must be a string) GenericValue value; //!< value of member. @@ -2402,9 +2407,11 @@ class GenericValue { void SetArrayRaw(GenericValue* values, SizeType count, Allocator& allocator) { data_.f.flags = kArrayFlag; if (count) { - GenericValue* e = static_cast(allocator.Malloc(count * sizeof(GenericValue))); - SetElementsPointer(e); - std::memcpy(static_cast(e), values, count * sizeof(GenericValue)); + auto arr = static_cast(allocator.Malloc(count * sizeof(GenericValue))); + for (SizeType idx = 0; idx < count; ++idx) + new (arr + idx) GenericValue; + SetElementsPointer(arr); + std::copy_n(values, count, arr); } else SetElementsPointer(0); @@ -2415,16 +2422,11 @@ class GenericValue { void SetObjectRaw(Member* members, SizeType count, Allocator& allocator) { data_.f.flags = kObjectFlag; if (count) { - Member* m = DoAllocMembers(count, allocator); - SetMembersPointer(m); - std::memcpy(static_cast(m), members, count * sizeof(Member)); -#if RAPIDJSON_USE_MEMBERSMAP - Map* &map = GetMap(m); - MapIterator* mit = GetMapIterators(map); - for (SizeType i = 0; i < count; i++) { - new (&mit[i]) MapIterator(map->insert(MapPair(m[i].name.data_, i))); - } -#endif + auto arr = static_cast(allocator.Malloc(count * sizeof(Member))); + for (SizeType idx = 0; idx < count; ++idx) + new (arr + idx) Member; + SetMembersPointer(arr); + std::copy_n(members, count, arr); } else SetMembersPointer(0);