From 3e2ae7cc782051dff8cee4270686c78e88533968 Mon Sep 17 00:00:00 2001
From: Takatoshi Kondo <redboltz@gmail.com>
Date: Mon, 11 Nov 2013 09:51:04 +0000
Subject: [PATCH 1/2] Fixed issue #37. It seems to be gcc's bug.
 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58416

---
 src/unpack.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/src/unpack.c b/src/unpack.c
index 4afc05e2..974b4cfc 100644
--- a/src/unpack.c
+++ b/src/unpack.c
@@ -111,7 +111,11 @@ static inline int template_callback_array(unpack_user* u, unsigned int n, msgpac
 }
 
 static inline int template_callback_array_item(unpack_user* u, msgpack_object* c, msgpack_object o)
-{ c->via.array.ptr[c->via.array.size++] = o; return 0; }
+{
+	memcpy(&c->via.array.ptr[c->via.array.size], &o, sizeof(msgpack_object));
+	++c->via.array.size;
+	return 0;
+}
 
 static inline int template_callback_map(unpack_user* u, unsigned int n, msgpack_object* o)
 {
@@ -124,8 +128,8 @@ static inline int template_callback_map(unpack_user* u, unsigned int n, msgpack_
 
 static inline int template_callback_map_item(unpack_user* u, msgpack_object* c, msgpack_object k, msgpack_object v)
 {
-	c->via.map.ptr[c->via.map.size].key = k;
-	c->via.map.ptr[c->via.map.size].val = v;
+	memcpy(&c->via.map.ptr[c->via.map.size].key, &k, sizeof(msgpack_object));
+	memcpy(&c->via.map.ptr[c->via.map.size].val, &v, sizeof(msgpack_object));
 	++c->via.map.size;
 	return 0;
 }

From b774c07d199291103b2d6d9273b0b3423b695e87 Mon Sep 17 00:00:00 2001
From: Takatoshi Kondo <redboltz@gmail.com>
Date: Mon, 16 Dec 2013 13:09:57 +0900
Subject: [PATCH 2/2] When the compiler is gcc, use memcpy, otherwise use an
 assignment operator. The memcpy approach is a workaround for gcc's bug. The
 speed performance on gcc is the same between both approach. But on clang, the
 memcpy approach is 10% slower than an assignment approach. Hence I added the
 switching approach code using compiler checked macro.

Note: __GNUC__ is defined both gcc and clang. So I use __GNUC__ && !__clang__
---
 src/unpack.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/src/unpack.c b/src/unpack.c
index 974b4cfc..1561313d 100644
--- a/src/unpack.c
+++ b/src/unpack.c
@@ -112,7 +112,11 @@ static inline int template_callback_array(unpack_user* u, unsigned int n, msgpac
 
 static inline int template_callback_array_item(unpack_user* u, msgpack_object* c, msgpack_object o)
 {
+#if defined(__GNUC__) && !defined(__clang__)
 	memcpy(&c->via.array.ptr[c->via.array.size], &o, sizeof(msgpack_object));
+#else  /* __GNUC__ && !__clang__ */
+	c->via.array.ptr[c->via.array.size] = o;
+#endif /* __GNUC__ && !__clang__ */
 	++c->via.array.size;
 	return 0;
 }
@@ -128,8 +132,13 @@ static inline int template_callback_map(unpack_user* u, unsigned int n, msgpack_
 
 static inline int template_callback_map_item(unpack_user* u, msgpack_object* c, msgpack_object k, msgpack_object v)
 {
+#if defined(__GNUC__) && !defined(__clang__)
 	memcpy(&c->via.map.ptr[c->via.map.size].key, &k, sizeof(msgpack_object));
 	memcpy(&c->via.map.ptr[c->via.map.size].val, &v, sizeof(msgpack_object));
+#else  /* __GNUC__ && !__clang__ */
+	c->via.map.ptr[c->via.map.size].key = k;
+	c->via.map.ptr[c->via.map.size].val = v;
+#endif /* __GNUC__ && !__clang__ */
 	++c->via.map.size;
 	return 0;
 }