diff options
Diffstat (limited to 'gcc/go/go-gcc.cc')
-rw-r--r-- | gcc/go/go-gcc.cc | 16 |
1 files changed, 15 insertions, 1 deletions
diff --git a/gcc/go/go-gcc.cc b/gcc/go/go-gcc.cc index d47529c..18c7146 100644 --- a/gcc/go/go-gcc.cc +++ b/gcc/go/go-gcc.cc @@ -1656,6 +1656,7 @@ Gcc_backend::constructor_expression(Btype* btype, 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(Btype* btype, || 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(Btype* btype, 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); } |