This patch by Chris Manghane skips initializing zero-sized fields in constructor expressions. Initializing them tends to lead into GIMPLE errors when using map composite literals. Note that zero-sized fields are useful in maps, but of course the compiler should not crash. This is http://golang.org/issue/9406 . Bootstrapped and ran Go testsuite on x86_64-unknown-linux-gnu. Committed to mainline.
Ian 2015-01-06 Chris Manghane <cm...@google.com> * go-gcc.cc (constructor_expression): Don't initialize zero-sized fields, just evaluate the values for side effects.
Index: go-gcc.cc =================================================================== --- go-gcc.cc (revision 219261) +++ go-gcc.cc (working copy) @@ -1656,6 +1656,7 @@ Gcc_backend::constructor_expression(Btyp vec<constructor_elt, va_gc> *init; vec_alloc(init, vals.size()); + tree sink = NULL_TREE; bool is_constant = true; tree field = TYPE_FIELDS(type_tree); for (std::vector<Bexpression*>::const_iterator p = vals.begin(); @@ -1669,6 +1670,17 @@ Gcc_backend::constructor_expression(Btyp || TREE_TYPE(val) == error_mark_node) return this->error_expression(); + if (int_size_in_bytes(TREE_TYPE(field)) == 0) + { + // GIMPLE cannot represent indices of zero-sized types so + // trying to construct a map with zero-sized keys might lead + // to errors. Instead, we evaluate each expression that + // would have been added as a map element for its + // side-effects and construct an empty map. + append_to_statement_list(val, &sink); + continue; + } + constructor_elt empty = {NULL, NULL}; constructor_elt* elt = init->quick_push(empty); elt->index = field; @@ -1681,7 +1693,9 @@ Gcc_backend::constructor_expression(Btyp tree ret = build_constructor(type_tree, init); if (is_constant) TREE_CONSTANT(ret) = 1; - + if (sink != NULL_TREE) + ret = fold_build2_loc(location.gcc_location(), COMPOUND_EXPR, + type_tree, sink, ret); return this->make_expression(ret); }