Skip to content

Commit

Permalink
Fix Tencent#1700 (GCC9 break: trying to memcpy C++ objects)
Browse files Browse the repository at this point in the history
  • Loading branch information
Dieter Niklaus committed Feb 21, 2023
1 parent 012be85 commit 56b4e48
Showing 1 changed file with 15 additions and 13 deletions.
28 changes: 15 additions & 13 deletions include/rapidjson/document.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
#include "internal/strfunc.h"
#include "memorystream.h"
#include "encodedstream.h"

#include <algorithm>
#include <new> // placement new
#include <limits>
#ifdef __cpp_lib_three_way_comparison
Expand Down Expand Up @@ -119,6 +121,9 @@ class GenericDocument;
template <typename Encoding, typename Allocator>
class GenericMember {
public:
// Allow default construction as it is needed during copying.
GenericMember() = default;

GenericValue<Encoding, Allocator> name; //!< name of member (must be a string)
GenericValue<Encoding, Allocator> value; //!< value of member.

Expand Down Expand Up @@ -2402,9 +2407,11 @@ class GenericValue {
void SetArrayRaw(GenericValue* values, SizeType count, Allocator& allocator) {
data_.f.flags = kArrayFlag;
if (count) {
GenericValue* e = static_cast<GenericValue*>(allocator.Malloc(count * sizeof(GenericValue)));
SetElementsPointer(e);
std::memcpy(static_cast<void*>(e), values, count * sizeof(GenericValue));
auto arr = static_cast<GenericValue*>(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);
Expand All @@ -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<void*>(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<Member*>(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);
Expand Down

0 comments on commit 56b4e48

Please sign in to comment.