From 25e15acf8cf0b7dc54367cb491c5f2d772199efb Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Wed, 11 Jan 2017 17:41:49 +0000 Subject: [PATCH] compiler: mark generated struct/array types as incomparable The recent change to generate type functions for more types with identity comparisons caused us to generate some unnecessary functions, and even caused a compiler crash on Solaris due to phase ordering. Avoid this by marking all generated and uncompared struct and array types as incomparable, so that we don't try to generate type functions for them. Reviewed-on: https://go-review.googlesource.com/35110 From-SVN: r244327 --- gcc/go/gofrontend/MERGE | 2 +- gcc/go/gofrontend/expressions.cc | 31 ++++++++++++++++++++++--------- gcc/go/gofrontend/gogo.cc | 4 +++- gcc/go/gofrontend/runtime.cc | 28 ++++++++++++++++++++++++---- gcc/go/gofrontend/types.cc | 8 ++++++-- 5 files changed, 56 insertions(+), 17 deletions(-) diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 4cf7fc9eaa2..457bba8879d 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -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. diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc index da721030e88..473a7788a12 100644 --- a/gcc/go/gofrontend/expressions.cc +++ b/gcc/go/gofrontend/expressions.cc @@ -6741,8 +6741,9 @@ Bound_method_expression::create_thunk(Gogo* gogo, const Method* method, 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* gogo, Named_object*, 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, Named_object*, } 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(Gogo* gogo, Named_object* function, 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::create_thunk(Gogo* gogo, 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_get_backend(Translate_context* context) 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_construction_expression( 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(Gogo* gogo, Named_object*, } 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_; } diff --git a/gcc/go/gofrontend/gogo.cc b/gcc/go/gofrontend/gogo.cc index 4e2d6b46ad0..ffe51b35d09 100644 --- a/gcc/go/gofrontend/gogo.cc +++ b/gcc/go/gofrontend/gogo.cc @@ -744,6 +744,7 @@ Gogo::register_gc_vars(const std::vector& var_gc, 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(); diff --git a/gcc/go/gofrontend/runtime.cc b/gcc/go/gofrontend/runtime.cc index 77c48ecbaaf..a9214498022 100644 --- a/gcc/go/gofrontend/runtime.cc +++ b/gcc/go/gofrontend/runtime.cc @@ -190,27 +190,47 @@ runtime_function_type(Runtime_function_type bft) 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; } diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc index 0b394c96de7..ace23d0c27b 100644 --- a/gcc/go/gofrontend/types.cc +++ b/gcc/go/gofrontend/types.cc @@ -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* 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_t keysize, int64_t valsize) 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, -- 2.30.2