On Tue, Jan 10, 2017 at 11:45 AM, Rainer Orth <r...@cebitec.uni-bielefeld.de> wrote: > >> Drop the size arguments for the hash/equal functions stored in type >> descriptors. Types know what size they are. To make this work, >> generate hash/equal functions for types that can use an identity >> comparison but are not a standard size and alignment. >> >> Drop the multiplications by 33 in the generated hash code and the >> reflect package hash code. They are not necessary since we started >> passing a seed value around, as the seed includes the hash of the >> earlier values. >> >> Copy the algorithms for standard types from the Go 1.7 runtime, >> replacing the C functions. >> >> Bootstrapped and ran Go testsuite on x86_64-pc-linux-gnu. Committed >> to mainline. > > this patch broke Solaris/SPARC bootstrap, it seems: building > debug/dwarf.lo ICEs like this: > > go1: internal compiler error: in write_specific_type_functions, at > go/gofrontend/types.cc:1993 > 0x4bc50b Type::write_specific_type_functions(Gogo*, Named_type*, long long, > std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > const&, Function_type*, std::__cxx11::basic_string<char, > std::char_traits<char>, std::allocator<char> > const&, Function_type*) > /vol/gcc/src/hg/trunk/local/gcc/go/gofrontend/types.cc:1993
Thanks. Looks like 32-bit SPARC requires a padding field in the bucket struct created for some map type. The compiler then tries to generate type functions for the type descriptor, and fails due to a phase ordering problem--at that point all type functions are expected to have been created. It worked previously because it used the standard functions for types that can use an identity comparison, but that is no longer the case for types with unusual sizes. Fixed by this patch, which marks compiler-created arrays and structs non-comparable, meaning that no type functions are created. Bootstrapped and ran Go testsuite on x86_64-pc-linux-gnu. Committed to mainline. Ian
Index: gcc/go/gofrontend/MERGE =================================================================== --- gcc/go/gofrontend/MERGE (revision 244291) +++ gcc/go/gofrontend/MERGE (working copy) @@ -1,4 +1,4 @@ -d3725d876496f2cca3d6ce538e98b58c85d90bfb +6be46149636c3533389e62c6dc76f0a7ff461080 The first line of this file holds the git revision number of the last merge done from the gofrontend repository. Index: gcc/go/gofrontend/expressions.cc =================================================================== --- gcc/go/gofrontend/expressions.cc (revision 244256) +++ gcc/go/gofrontend/expressions.cc (working copy) @@ -6741,8 +6741,9 @@ Bound_method_expression::create_thunk(Go sfl->push_back(Struct_field(Typed_identifier("val.1", orig_fntype->receiver()->type(), loc))); - Type* closure_type = Type::make_struct_type(sfl, loc); - closure_type = Type::make_pointer_type(closure_type); + Struct_type* st = Type::make_struct_type(sfl, loc); + st->set_is_struct_incomparable(); + Type* closure_type = Type::make_pointer_type(st); Function_type* new_fntype = orig_fntype->copy_with_names(); @@ -6896,6 +6897,7 @@ Bound_method_expression::do_flatten(Gogo loc))); fields->push_back(Struct_field(Typed_identifier("val.1", val->type(), loc))); Struct_type* st = Type::make_struct_type(fields, loc); + st->set_is_struct_incomparable(); Expression_list* vals = new Expression_list(); vals->push_back(Expression::make_func_code_reference(thunk, loc)); @@ -9683,6 +9685,7 @@ Call_expression::do_flatten(Gogo* gogo, } Struct_type* st = Type::make_struct_type(sfl, loc); + st->set_is_struct_incomparable(); this->call_temp_ = Statement::make_temporary(st, NULL, loc); inserter->insert(this->call_temp_); } @@ -11565,7 +11568,8 @@ Field_reference_expression::do_lower(Gog Expression* length_expr = Expression::make_integer_ul(s.length(), NULL, loc); Type* byte_type = gogo->lookup_global("byte")->type_value(); - Type* array_type = Type::make_array_type(byte_type, length_expr); + Array_type* array_type = Type::make_array_type(byte_type, length_expr); + array_type->set_is_array_incomparable(); Expression_list* bytes = new Expression_list(); for (std::string::const_iterator p = s.begin(); p != s.end(); p++) @@ -11843,8 +11847,9 @@ Interface_field_reference_expression::cr Type* vt = Type::make_pointer_type(Type::make_void_type()); sfl->push_back(Struct_field(Typed_identifier("fn.0", vt, loc))); sfl->push_back(Struct_field(Typed_identifier("val.1", type, loc))); - Type* closure_type = Type::make_struct_type(sfl, loc); - closure_type = Type::make_pointer_type(closure_type); + Struct_type* st = Type::make_struct_type(sfl, loc); + st->set_is_struct_incomparable(); + Type* closure_type = Type::make_pointer_type(st); Function_type* new_fntype = orig_fntype->copy_with_names(); @@ -11943,6 +11948,7 @@ Interface_field_reference_expression::do this->expr_->type(), loc))); Struct_type* st = Type::make_struct_type(fields, loc); + st->set_is_struct_incomparable(); Expression_list* vals = new Expression_list(); vals->push_back(Expression::make_func_code_reference(thunk, loc)); @@ -12930,7 +12936,9 @@ Slice_construction_expression::Slice_con Type* int_type = Type::lookup_integer_type("int"); length = Expression::make_integer_ul(lenval, int_type, location); Type* element_type = type->array_type()->element_type(); - this->valtype_ = Type::make_array_type(element_type, length); + Array_type* array_type = Type::make_array_type(element_type, length); + array_type->set_is_array_incomparable(); + this->valtype_ = array_type; } // Traversal. @@ -13161,8 +13169,9 @@ Map_construction_expression::do_flatten( } Expression* element_count = Expression::make_integer_ul(i, NULL, loc); - Type* ctor_type = + Array_type* ctor_type = Type::make_array_type(this->element_type_, element_count); + ctor_type->set_is_array_incomparable(); Expression* constructor = new Fixed_array_construction_expression(ctor_type, NULL, value_pairs, loc); @@ -14863,7 +14872,9 @@ Interface_info_expression::do_type() sfl->push_back(Struct_field(Typed_identifier(fname, mft, loc))); } - Pointer_type *pt = Type::make_pointer_type(Type::make_struct_type(sfl, loc)); + Struct_type* st = Type::make_struct_type(sfl, loc); + st->set_is_struct_incomparable(); + Pointer_type *pt = Type::make_pointer_type(st); result_types[itype] = pt; return pt; } @@ -15097,7 +15108,9 @@ Interface_mtable_expression::do_type() p != interface_methods->end(); ++p) sfl->push_back(Struct_field(*p)); - this->method_table_type_ = Type::make_struct_type(sfl, this->location()); + Struct_type* st = Type::make_struct_type(sfl, this->location()); + st->set_is_struct_incomparable(); + this->method_table_type_ = st; return this->method_table_type_; } Index: gcc/go/gofrontend/gogo.cc =================================================================== --- gcc/go/gofrontend/gogo.cc (revision 244256) +++ gcc/go/gofrontend/gogo.cc (working copy) @@ -744,6 +744,7 @@ Gogo::register_gc_vars(const std::vector Expression* length = Expression::make_integer_ul(roots_len, NULL, builtin_loc); Array_type* root_array_type = Type::make_array_type(root_type, length); + root_array_type->set_is_array_incomparable(); Type* ptdt = Type::make_type_descriptor_ptr_type(); Struct_type* root_list_type = Type::make_builtin_struct_type(2, @@ -4833,7 +4834,8 @@ Function::closure_var() // we find them. Location loc = this->type_->location(); Struct_field_list* sfl = new Struct_field_list; - Type* struct_type = Type::make_struct_type(sfl, loc); + Struct_type* struct_type = Type::make_struct_type(sfl, loc); + struct_type->set_is_struct_incomparable(); Variable* var = new Variable(Type::make_pointer_type(struct_type), NULL, false, false, false, loc); var->set_is_used(); Index: gcc/go/gofrontend/runtime.cc =================================================================== --- gcc/go/gofrontend/runtime.cc (revision 244166) +++ gcc/go/gofrontend/runtime.cc (working copy) @@ -190,27 +190,47 @@ runtime_function_type(Runtime_function_t break; case RFT_ARRAY2STRING: - t = Type::make_array_type(Type::make_string_type(), + { + Array_type* at = + Type::make_array_type(Type::make_string_type(), Expression::make_integer_ul(2, NULL, bloc)); + at->set_is_array_incomparable(); + t = at; + } break; case RFT_ARRAY3STRING: - t = Type::make_array_type(Type::make_string_type(), + { + Array_type* at = + Type::make_array_type(Type::make_string_type(), Expression::make_integer_ul(3, NULL, bloc)); + at->set_is_array_incomparable(); + t = at; + } break; case RFT_ARRAY4STRING: - t = Type::make_array_type(Type::make_string_type(), + { + Array_type* at = + Type::make_array_type(Type::make_string_type(), Expression::make_integer_ul(4, NULL, bloc)); + at->set_is_array_incomparable(); + t = at; + } break; case RFT_ARRAY5STRING: - t = Type::make_array_type(Type::make_string_type(), + { + Array_type* at = + Type::make_array_type(Type::make_string_type(), Expression::make_integer_ul(5, NULL, bloc)); + at->set_is_array_incomparable(); + t = at; + } break; } Index: gcc/go/gofrontend/types.cc =================================================================== --- gcc/go/gofrontend/types.cc (revision 244256) +++ gcc/go/gofrontend/types.cc (working copy) @@ -2500,6 +2500,7 @@ Type::gc_symbol_constructor(Gogo* gogo) Expression* len = Expression::make_integer_ul(vals->size(), NULL, bloc); Array_type* gc_symbol_type = Type::make_array_type(uintptr_t, len); + gc_symbol_type->set_is_array_incomparable(); return Expression::make_array_composite_literal(gc_symbol_type, vals, bloc); } @@ -4037,6 +4038,7 @@ Function_type::get_backend_fntype(Gogo* } Struct_type* st = Type::make_struct_type(sfl, this->location()); + st->set_is_struct_incomparable(); ins.first->second = st->get_backend(gogo); } bresult_struct = ins.first->second; @@ -7209,7 +7211,8 @@ Map_type::fat_zero_value(Gogo* gogo) // The final type will be set in backend_zero_value. Type* uint8_type = Type::lookup_integer_type("uint8"); Expression* size = Expression::make_integer_ul(0, NULL, bloc); - Type* array_type = Type::make_array_type(uint8_type, size); + Array_type* array_type = Type::make_array_type(uint8_type, size); + array_type->set_is_array_incomparable(); Variable* var = new Variable(array_type, NULL, true, false, false, bloc); Map_type::zero_value = Named_object::make_variable("go$zerovalue", NULL, var); @@ -7619,7 +7622,8 @@ Map_type::bucket_type(Gogo* gogo, int64_ Expression* pad_expr = Expression::make_integer_ul(pad, NULL, this->location_); - Type* pad_type = Type::make_array_type(uint8_type, pad_expr); + Array_type* pad_type = Type::make_array_type(uint8_type, pad_expr); + pad_type->set_is_array_incomparable(); ret = make_builtin_struct_type(5, "topbits", topbits_type,