From 363e6fa172f787e970c8abc8f631b6d60d571248 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sat, 17 Mar 2018 18:31:21 +0800 Subject: Codegen C - Work around GCC5 bug by emitting a single-field struct instead of a union Fixes #63 --- src/trans/codegen_c.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/trans/codegen_c.cpp b/src/trans/codegen_c.cpp index 3eff24a0..87d96abb 100644 --- a/src/trans/codegen_c.cpp +++ b/src/trans/codegen_c.cpp @@ -1124,8 +1124,19 @@ namespace { m_of << "// enum " << p << "\n"; m_of << "struct e_" << Trans_Mangle(p) << " {\n"; + // HACK: For NonZero optimised enums, emit a struct with a single field + // - This avoids a bug in GCC5 where it would generate incorrect code if there's a union here. + if( const auto* ve = repr->variants.opt_NonZero() ) + { + m_of << "\tstruct {\n"; + m_of << "\t\t"; + unsigned idx = 1 - ve->zero_variant; + emit_ctype(repr->fields.at(idx).ty, FMT_CB(os, os << "var_" << idx)); + m_of << ";\n"; + m_of << "\t} DATA;"; + } // If there multiple fields with the same offset, they're the data variants - if( union_fields.size() > 0 ) + else if( union_fields.size() > 0 ) { assert(1 + union_fields.size() + 1 >= repr->fields.size()); // Make the union! -- cgit v1.2.3