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,

Reply via email to