Init cs_detail (#1205)

* Update init of cs_detail for AArch64

as @aquynh requested in #1125

* Update init of cs_detail for ARM

as @aquynh requested in #1125

* Update init of cs_detail for EVM

as @aquynh requested in #1125

* Update init of cs_detail for M680X

as @aquynh requested in #1125

* Update init of cs_detail for M68K

as @aquynh requested in #1125

* Update init of cs_detail for Mips

as @aquynh requested in #1125

* Update init of cs_detail for PowerPC

as @aquynh requested in #1125

* Update init of cs_detail for Sparc

as @aquynh requested in #1125

* Update init of cs_detail for SystemZ

as @aquynh requested in #1125

* Update init of cs_detail for TMS320C64x

as @aquynh requested in #1125

* Update init of cs_detail for XCore

as @aquynh requested in #1125

* Comment on init of cs_detail

* wrap long lines
diff --git a/arch/AArch64/AArch64Disassembler.c b/arch/AArch64/AArch64Disassembler.c
index 22880ef..e6e0ef1 100644
--- a/arch/AArch64/AArch64Disassembler.c
+++ b/arch/AArch64/AArch64Disassembler.c
@@ -233,7 +233,7 @@
 	}
 
 	if (MI->flat_insn->detail) {
-		memset(MI->flat_insn->detail, 0, sizeof(cs_detail));
+		memset(MI->flat_insn->detail, 0, offsetof(cs_detail, arm64)+sizeof(cs_arm64));
 		for (i = 0; i < ARR_SIZE(MI->flat_insn->detail->arm64.operands); i++)
 			MI->flat_insn->detail->arm64.operands[i].vector_index = -1;
 	}
diff --git a/arch/ARM/ARMDisassembler.c b/arch/ARM/ARMDisassembler.c
index 2851e0c..08b25f3 100644
--- a/arch/ARM/ARMDisassembler.c
+++ b/arch/ARM/ARMDisassembler.c
@@ -475,7 +475,7 @@
 		return MCDisassembler_Fail;
 
 	if (MI->flat_insn->detail) {
-		memset(&MI->flat_insn->detail->arm, 0, sizeof(cs_arm));
+		memset(MI->flat_insn->detail, 0, offsetof(cs_detail, arm)+sizeof(cs_arm));
 		for (i = 0; i < ARR_SIZE(MI->flat_insn->detail->arm.operands); i++) {
 			MI->flat_insn->detail->arm.operands[i].vector_index = -1;
 			MI->flat_insn->detail->arm.operands[i].neon_lane = -1;
@@ -718,7 +718,7 @@
 		return MCDisassembler_Fail;
 
 	if (MI->flat_insn->detail) {
-		memset(&MI->flat_insn->detail->arm, 0, sizeof(cs_arm));
+		memset(MI->flat_insn->detail, 0, offsetof(cs_detail, arm)+sizeof(cs_arm));
 		for (i = 0; i < ARR_SIZE(MI->flat_insn->detail->arm.operands); i++) {
 			MI->flat_insn->detail->arm.operands[i].vector_index = -1;
 			MI->flat_insn->detail->arm.operands[i].neon_lane = -1;
diff --git a/arch/EVM/EVMDisassembler.c b/arch/EVM/EVMDisassembler.c
index 5cc8ff0..8f8c72d 100644
--- a/arch/EVM/EVMDisassembler.c
+++ b/arch/EVM/EVMDisassembler.c
@@ -2,6 +2,8 @@
 /* By Nguyen Anh Quynh, 2018 */
 
 #include <string.h>
+#include <stddef.h> // offsetof macro
+                    // alternatively #include "../../utils.h" like everyone else
 
 #include "EVMDisassembler.h"
 #include "EVMMapping.h"
@@ -296,13 +298,9 @@
 		*size = 1;
 
 	if (MI->flat_insn->detail) {
-		memset(&MI->flat_insn->detail->evm, 0, sizeof(cs_evm));
+		memset(MI->flat_insn->detail, 0, offsetof(cs_detail, evm)+sizeof(cs_evm));
 		EVM_get_insn_id((cs_struct *)ud, MI->flat_insn, opcode);
 
-		MI->flat_insn->detail->regs_read_count = 0;
-		MI->flat_insn->detail->regs_write_count = 0;
-		MI->flat_insn->detail->groups_count = 0;
-
 		if (MI->flat_insn->detail->evm.pop) {
 			MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = EVM_GRP_STACK_READ;
 			MI->flat_insn->detail->groups_count++;
diff --git a/arch/M680X/M680XDisassembler.c b/arch/M680X/M680XDisassembler.c
index 202eb26..cfe88d3 100644
--- a/arch/M680X/M680XDisassembler.c
+++ b/arch/M680X/M680XDisassembler.c
@@ -1802,9 +1802,7 @@
 	e_access_mode access_mode;
 
 	if (detail != NULL) {
-		detail->regs_read_count = 0;
-		detail->regs_write_count = 0;
-		detail->groups_count = 0;
+		memset(detail, 0, offsetof(cs_detail, m680x)+sizeof(cs_m680x));
 	}
 
 	memset(&insn_description, 0, sizeof(insn_description));
diff --git a/arch/M68K/M68KDisassembler.c b/arch/M68K/M68KDisassembler.c
index 9511444..4ff84b8 100644
--- a/arch/M68K/M68KDisassembler.c
+++ b/arch/M68K/M68KDisassembler.c
@@ -4061,6 +4061,10 @@
 		return false;
 	}
 
+	if (instr->flat_insn->detail) {
+		memset(instr->flat_insn->detail, 0, offsetof(cs_detail, m68k)+sizeof(cs_m68k));
+	}
+
 	info->groups_count = 0;
 	info->regs_read_count = 0;
 	info->regs_write_count = 0;
diff --git a/arch/Mips/MipsDisassembler.c b/arch/Mips/MipsDisassembler.c
index f374d27..5ff97a6 100644
--- a/arch/Mips/MipsDisassembler.c
+++ b/arch/Mips/MipsDisassembler.c
@@ -412,7 +412,7 @@
 	DecodeStatus Result;
 
 	if (instr->flat_insn->detail) {
-		memset(instr->flat_insn->detail, 0, sizeof(cs_detail));
+		memset(instr->flat_insn->detail, 0, offsetof(cs_detail, mips)+sizeof(cs_mips));
 	}
 
 	if (mode & CS_MODE_MICRO) {
diff --git a/arch/PowerPC/PPCDisassembler.c b/arch/PowerPC/PPCDisassembler.c
index 12e59eb..bdb302b 100644
--- a/arch/PowerPC/PPCDisassembler.c
+++ b/arch/PowerPC/PPCDisassembler.c
@@ -371,7 +371,7 @@
 			(code[1] <<  8) | (code[0] <<  0);
 
 	if (MI->flat_insn->detail) {
-		memset(MI->flat_insn->detail, 0, sizeof(cs_detail));
+		memset(MI->flat_insn->detail, 0, offsetof(cs_detail, ppc)+sizeof(cs_ppc));
 	}
 
 	if (MI->csh->mode & CS_MODE_QPX) {
diff --git a/arch/Sparc/SparcDisassembler.c b/arch/Sparc/SparcDisassembler.c
index e5e8f1d..a230534 100644
--- a/arch/Sparc/SparcDisassembler.c
+++ b/arch/Sparc/SparcDisassembler.c
@@ -228,7 +228,7 @@
 		return false;
 
 	if (MI->flat_insn->detail) {
-		memset(MI->flat_insn->detail, 0, sizeof(cs_detail));
+		memset(MI->flat_insn->detail, 0, offsetof(cs_detail, sparc)+sizeof(cs_sparc));
 	}
 
 	Result = decodeInstruction_4(DecoderTableSparc32, MI, Insn, address,
diff --git a/arch/SystemZ/SystemZDisassembler.c b/arch/SystemZ/SystemZDisassembler.c
index e3f8563..e9db9ec 100644
--- a/arch/SystemZ/SystemZDisassembler.c
+++ b/arch/SystemZ/SystemZDisassembler.c
@@ -321,7 +321,7 @@
 		return false;
 
 	if (MI->flat_insn->detail) {
-		memset(MI->flat_insn->detail, 0, sizeof(cs_detail));
+		memset(MI->flat_insn->detail, 0, offsetof(cs_detail, sysz)+sizeof(cs_sysz));
 	}
 
 	// Construct the instruction.
diff --git a/arch/TMS320C64x/TMS320C64xDisassembler.c b/arch/TMS320C64x/TMS320C64xDisassembler.c
index 836d513..52d74f4 100644
--- a/arch/TMS320C64x/TMS320C64xDisassembler.c
+++ b/arch/TMS320C64x/TMS320C64xDisassembler.c
@@ -592,7 +592,7 @@
 	}
 
 	if(MI->flat_insn->detail)
-		memset(MI->flat_insn->detail, 0, sizeof(cs_detail));
+		memset(MI->flat_insn->detail, 0, offsetof(cs_detail, tms320c64x)+sizeof(cs_tms320c64x));
 
 	insn = (code[3] << 0) | (code[2] << 8) | (code[1] << 16) | (code[0] << 24);
 	result = decodeInstruction_4(DecoderTable32, MI, insn, address, info, 0);
diff --git a/arch/XCore/XCoreDisassembler.c b/arch/XCore/XCoreDisassembler.c
index 1d983f8..46e885a 100644
--- a/arch/XCore/XCoreDisassembler.c
+++ b/arch/XCore/XCoreDisassembler.c
@@ -738,7 +738,7 @@
 	}
 
 	if (MI->flat_insn->detail) {
-		memset(MI->flat_insn->detail, 0, sizeof(cs_detail));
+		memset(MI->flat_insn->detail, 0, offsetof(cs_detail, xcore)+sizeof(cs_xcore));
 	}
 
 	// Calling the auto-generated decoder function.
diff --git a/include/capstone/capstone.h b/include/capstone/capstone.h
index 39b18c9..71dfeb0 100644
--- a/include/capstone/capstone.h
+++ b/include/capstone/capstone.h
@@ -278,6 +278,10 @@
 #include "evm.h"
 
 // NOTE: All information in cs_detail is only available when CS_OPT_DETAIL = CS_OPT_ON
+// Initialized as memset(., 0, offsetof(cs_detail, ARCH)+sizeof(cs_ARCH))
+// by ARCH_getInstruction in arch/ARCH/ARCHDisassembler.c
+// if cs_detail changes, in particular if a field is added after the union,
+// then update arch/ARCH/ARCHDisassembler.c accordingly
 typedef struct cs_detail {
 	uint16_t regs_read[12]; // list of implicit registers read by this insn
 	uint8_t regs_read_count; // number of implicit registers read by this insn