Commit 0799a08b by Ian Lance Taylor

compiler: rewrite Type::are_identical to use flags

    
    A single flags parameter replaces the Cmp_tags and errors_are_identical
    parameters. The existing behavior is unchanged.
    
    This is a simplification step for future work that will add a new flag.
    
    Reviewed-on: https://go-review.googlesource.com/c/143019

From-SVN: r265293
parent 28dd75a3
0494dc5737f0c89ad6f45e04e8313e4161678861 84531ef21230307773daa438a50bf095edcdbf93
The first line of this file holds the git revision number of the last The first line of this file holds the git revision number of the last
merge done from the gofrontend repository. merge done from the gofrontend repository.
...@@ -2077,7 +2077,8 @@ Escape_analysis_assign::call(Call_expression* call) ...@@ -2077,7 +2077,8 @@ Escape_analysis_assign::call(Call_expression* call)
else else
{ {
if (!Type::are_identical(fntype->receiver()->type(), if (!Type::are_identical(fntype->receiver()->type(),
(*p)->expr()->type(), true, NULL)) (*p)->expr()->type(), Type::COMPARE_TAGS,
NULL))
{ {
// This will be converted later, preemptively track it instead // This will be converted later, preemptively track it instead
// of its conversion expression which will show up in a later pass. // of its conversion expression which will show up in a later pass.
...@@ -2096,7 +2097,7 @@ Escape_analysis_assign::call(Call_expression* call) ...@@ -2096,7 +2097,7 @@ Escape_analysis_assign::call(Call_expression* call)
++pn, ++p) ++pn, ++p)
{ {
if (!Type::are_identical(pn->type(), (*p)->expr()->type(), if (!Type::are_identical(pn->type(), (*p)->expr()->type(),
true, NULL)) Type::COMPARE_TAGS, NULL))
{ {
// This will be converted later, preemptively track it instead // This will be converted later, preemptively track it instead
// of its conversion expression which will show up in a later pass. // of its conversion expression which will show up in a later pass.
......
...@@ -178,7 +178,10 @@ Expression::convert_for_assignment(Gogo*, Type* lhs_type, ...@@ -178,7 +178,10 @@ Expression::convert_for_assignment(Gogo*, Type* lhs_type,
|| rhs->is_error_expression()) || rhs->is_error_expression())
return Expression::make_error(location); return Expression::make_error(location);
bool are_identical = Type::are_identical(lhs_type, rhs_type, false, NULL); bool are_identical = Type::are_identical(lhs_type, rhs_type,
(Type::COMPARE_ERRORS
| Type::COMPARE_TAGS),
NULL);
if (!are_identical && lhs_type->interface_type() != NULL) if (!are_identical && lhs_type->interface_type() != NULL)
{ {
if (rhs_type->interface_type() == NULL) if (rhs_type->interface_type() == NULL)
...@@ -341,7 +344,9 @@ Expression::convert_interface_to_interface(Type *lhs_type, Expression* rhs, ...@@ -341,7 +344,9 @@ Expression::convert_interface_to_interface(Type *lhs_type, Expression* rhs,
bool for_type_guard, bool for_type_guard,
Location location) Location location)
{ {
if (Type::are_identical(lhs_type, rhs->type(), false, NULL)) if (Type::are_identical(lhs_type, rhs->type(),
Type::COMPARE_ERRORS | Type::COMPARE_TAGS,
NULL))
return rhs; return rhs;
Interface_type* lhs_interface_type = lhs_type->interface_type(); Interface_type* lhs_interface_type = lhs_type->interface_type();
...@@ -3389,7 +3394,9 @@ Type_conversion_expression::do_is_static_initializer() const ...@@ -3389,7 +3394,9 @@ Type_conversion_expression::do_is_static_initializer() const
if (!this->expr_->is_static_initializer()) if (!this->expr_->is_static_initializer())
return false; return false;
if (Type::are_identical(type, expr_type, false, NULL)) if (Type::are_identical(type, expr_type,
Type::COMPARE_ERRORS | Type::COMPARE_TAGS,
NULL))
return true; return true;
if (type->is_string_type() && expr_type->is_string_type()) if (type->is_string_type() && expr_type->is_string_type())
...@@ -3503,7 +3510,9 @@ Type_conversion_expression::do_get_backend(Translate_context* context) ...@@ -3503,7 +3510,9 @@ Type_conversion_expression::do_get_backend(Translate_context* context)
Btype* btype = type->get_backend(gogo); Btype* btype = type->get_backend(gogo);
Location loc = this->location(); Location loc = this->location();
if (Type::are_identical(type, expr_type, false, NULL)) if (Type::are_identical(type, expr_type,
Type::COMPARE_ERRORS | Type::COMPARE_TAGS,
NULL))
{ {
Bexpression* bexpr = this->expr_->get_backend(context); Bexpression* bexpr = this->expr_->get_backend(context);
return gogo->backend()->convert_expression(btype, bexpr, loc); return gogo->backend()->convert_expression(btype, bexpr, loc);
...@@ -5433,7 +5442,10 @@ Binary_expression::lower_struct_comparison(Gogo* gogo, ...@@ -5433,7 +5442,10 @@ Binary_expression::lower_struct_comparison(Gogo* gogo,
Struct_type* st2 = this->right_->type()->struct_type(); Struct_type* st2 = this->right_->type()->struct_type();
if (st2 == NULL) if (st2 == NULL)
return this; return this;
if (st != st2 && !Type::are_identical(st, st2, false, NULL)) if (st != st2
&& !Type::are_identical(st, st2,
Type::COMPARE_ERRORS | Type::COMPARE_TAGS,
NULL))
return this; return this;
if (!Type::are_compatible_for_comparison(true, this->left_->type(), if (!Type::are_compatible_for_comparison(true, this->left_->type(),
this->right_->type(), NULL)) this->right_->type(), NULL))
...@@ -5512,7 +5524,10 @@ Binary_expression::lower_array_comparison(Gogo* gogo, ...@@ -5512,7 +5524,10 @@ Binary_expression::lower_array_comparison(Gogo* gogo,
Array_type* at2 = this->right_->type()->array_type(); Array_type* at2 = this->right_->type()->array_type();
if (at2 == NULL) if (at2 == NULL)
return this; return this;
if (at != at2 && !Type::are_identical(at, at2, false, NULL)) if (at != at2
&& !Type::are_identical(at, at2,
Type::COMPARE_ERRORS | Type::COMPARE_TAGS,
NULL))
return this; return this;
if (!Type::are_compatible_for_comparison(true, this->left_->type(), if (!Type::are_compatible_for_comparison(true, this->left_->type(),
this->right_->type(), NULL)) this->right_->type(), NULL))
...@@ -6902,7 +6917,7 @@ Bound_method_expression::do_check_types(Gogo*) ...@@ -6902,7 +6917,7 @@ Bound_method_expression::do_check_types(Gogo*)
? this->expr_type_ ? this->expr_type_
: this->expr_->type()); : this->expr_->type());
etype = etype->deref(); etype = etype->deref();
if (!Type::are_identical(rtype, etype, true, NULL)) if (!Type::are_identical(rtype, etype, Type::COMPARE_TAGS, NULL))
this->report_error(_("method type does not match object type")); this->report_error(_("method type does not match object type"));
} }
...@@ -8404,7 +8419,9 @@ Builtin_call_expression::do_numeric_constant_value(Numeric_constant* nc) const ...@@ -8404,7 +8419,9 @@ Builtin_call_expression::do_numeric_constant_value(Numeric_constant* nc) const
&& !rnc.type()->is_abstract() && !rnc.type()->is_abstract()
&& inc.type() != NULL && inc.type() != NULL
&& !inc.type()->is_abstract() && !inc.type()->is_abstract()
&& !Type::are_identical(rnc.type(), inc.type(), false, NULL)) && !Type::are_identical(rnc.type(), inc.type(),
Type::COMPARE_ERRORS | Type::COMPARE_TAGS,
NULL))
return false; return false;
mpfr_t r; mpfr_t r;
...@@ -8885,7 +8902,7 @@ Builtin_call_expression::do_check_types(Gogo*) ...@@ -8885,7 +8902,7 @@ Builtin_call_expression::do_check_types(Gogo*)
if (arg2_type->is_slice_type()) if (arg2_type->is_slice_type())
{ {
Type* e2 = arg2_type->array_type()->element_type(); Type* e2 = arg2_type->array_type()->element_type();
if (!Type::are_identical(e1, e2, true, NULL)) if (!Type::are_identical(e1, e2, Type::COMPARE_TAGS, NULL))
this->report_error(_("element types must be the same")); this->report_error(_("element types must be the same"));
} }
else if (arg2_type->is_string_type()) else if (arg2_type->is_string_type())
...@@ -9023,7 +9040,8 @@ Builtin_call_expression::do_check_types(Gogo*) ...@@ -9023,7 +9040,8 @@ Builtin_call_expression::do_check_types(Gogo*)
|| args->back()->type()->is_error()) || args->back()->type()->is_error())
this->set_is_error(); this->set_is_error();
else if (!Type::are_identical(args->front()->type(), else if (!Type::are_identical(args->front()->type(),
args->back()->type(), true, NULL)) args->back()->type(),
Type::COMPARE_TAGS, NULL))
this->report_error(_("complex arguments must have identical types")); this->report_error(_("complex arguments must have identical types"));
else if (args->front()->type()->float_type() == NULL) else if (args->front()->type()->float_type() == NULL)
this->report_error(_("complex arguments must have " this->report_error(_("complex arguments must have "
...@@ -9935,7 +9953,8 @@ Call_expression::do_flatten(Gogo* gogo, Named_object*, ...@@ -9935,7 +9953,8 @@ Call_expression::do_flatten(Gogo* gogo, Named_object*,
for (; pa != this->args_->end(); ++pa, ++pp) for (; pa != this->args_->end(); ++pa, ++pp)
{ {
go_assert(pp != fntype->parameters()->end()); go_assert(pp != fntype->parameters()->end());
if (Type::are_identical(pp->type(), (*pa)->type(), true, NULL)) if (Type::are_identical(pp->type(), (*pa)->type(),
Type::COMPARE_TAGS, NULL))
args->push_back(*pa); args->push_back(*pa);
else else
{ {
...@@ -11630,7 +11649,9 @@ Map_index_expression::do_flatten(Gogo* gogo, Named_object*, ...@@ -11630,7 +11649,9 @@ Map_index_expression::do_flatten(Gogo* gogo, Named_object*,
return Expression::make_error(loc); return Expression::make_error(loc);
} }
if (!Type::are_identical(mt->key_type(), this->index_->type(), false, NULL)) if (!Type::are_identical(mt->key_type(), this->index_->type(),
Type::COMPARE_ERRORS | Type::COMPARE_TAGS,
NULL))
{ {
if (this->index_->type()->interface_type() != NULL if (this->index_->type()->interface_type() != NULL
&& !this->index_->is_variable()) && !this->index_->is_variable())
...@@ -15948,7 +15969,8 @@ Type* ...@@ -15948,7 +15969,8 @@ Type*
Conditional_expression::do_type() Conditional_expression::do_type()
{ {
Type* result_type = Type::make_void_type(); Type* result_type = Type::make_void_type();
if (Type::are_identical(this->then_->type(), this->else_->type(), false, if (Type::are_identical(this->then_->type(), this->else_->type(),
Type::COMPARE_ERRORS | Type::COMPARE_TAGS,
NULL)) NULL))
result_type = this->then_->type(); result_type = this->then_->type();
else if (this->then_->is_nil_expression() else if (this->then_->is_nil_expression()
......
...@@ -6492,7 +6492,8 @@ Variable::flatten_init_expression(Gogo* gogo, Named_object* function, ...@@ -6492,7 +6492,8 @@ Variable::flatten_init_expression(Gogo* gogo, Named_object* function,
// If an interface conversion is needed, we need a temporary // If an interface conversion is needed, we need a temporary
// variable. // variable.
if (this->type_ != NULL if (this->type_ != NULL
&& !Type::are_identical(this->type_, this->init_->type(), false, && !Type::are_identical(this->type_, this->init_->type(),
Type::COMPARE_ERRORS | Type::COMPARE_TAGS,
NULL) NULL)
&& this->init_->type()->interface_type() != NULL && this->init_->type()->interface_type() != NULL
&& !this->init_->is_variable()) && !this->init_->is_variable())
......
...@@ -472,7 +472,9 @@ Temporary_statement::do_flatten(Gogo*, Named_object*, Block*, ...@@ -472,7 +472,9 @@ Temporary_statement::do_flatten(Gogo*, Named_object*, Block*,
if (this->type_ != NULL if (this->type_ != NULL
&& this->init_ != NULL && this->init_ != NULL
&& !Type::are_identical(this->type_, this->init_->type(), false, NULL) && !Type::are_identical(this->type_, this->init_->type(),
Type::COMPARE_ERRORS | Type::COMPARE_TAGS,
NULL)
&& this->init_->type()->interface_type() != NULL && this->init_->type()->interface_type() != NULL
&& !this->init_->is_variable()) && !this->init_->is_variable())
{ {
...@@ -841,7 +843,8 @@ Assignment_statement::do_flatten(Gogo*, Named_object*, Block*, ...@@ -841,7 +843,8 @@ Assignment_statement::do_flatten(Gogo*, Named_object*, Block*,
if (!this->lhs_->is_sink_expression() if (!this->lhs_->is_sink_expression()
&& !Type::are_identical(this->lhs_->type(), this->rhs_->type(), && !Type::are_identical(this->lhs_->type(), this->rhs_->type(),
false, NULL) Type::COMPARE_ERRORS | Type::COMPARE_TAGS,
NULL)
&& this->rhs_->type()->interface_type() != NULL && this->rhs_->type()->interface_type() != NULL
&& !this->rhs_->is_variable()) && !this->rhs_->is_variable())
{ {
...@@ -4384,7 +4387,9 @@ Send_statement::do_flatten(Gogo*, Named_object*, Block*, ...@@ -4384,7 +4387,9 @@ Send_statement::do_flatten(Gogo*, Named_object*, Block*,
} }
Type* element_type = this->channel_->type()->channel_type()->element_type(); Type* element_type = this->channel_->type()->channel_type()->element_type();
if (!Type::are_identical(element_type, this->val_->type(), false, NULL) if (!Type::are_identical(element_type, this->val_->type(),
Type::COMPARE_ERRORS | Type::COMPARE_TAGS,
NULL)
&& this->val_->type()->interface_type() != NULL && this->val_->type()->interface_type() != NULL
&& !this->val_->is_variable()) && !this->val_->is_variable())
{ {
......
...@@ -563,29 +563,22 @@ class Type ...@@ -563,29 +563,22 @@ class Type
verify() verify()
{ return this->do_verify(); } { return this->do_verify(); }
// Return true if two types are identical. If ERRORS_ARE_IDENTICAL, // Bit flags to pass to are_identical and friends.
// returns that an erroneous type is identical to any other type;
// this is used to avoid cascading errors. If this returns false,
// and REASON is not NULL, it may set *REASON.
static bool
are_identical(const Type* lhs, const Type* rhs, bool errors_are_identical,
std::string* reason);
// An argument to are_identical_cmp_tags, indicating whether or not // Treat error types as their own distinct type. Sometimes we
// to compare struct field tags. // ignore error types--treat them as identical to every other
enum Cmp_tags { // type--to avoid cascading errors.
COMPARE_TAGS, static const int COMPARE_ERRORS = 1;
IGNORE_TAGS
}; // Compare struct field tags when comparing structs. We ignore
// struct field tags for purposes of type conversion.
static const int COMPARE_TAGS = 2;
// Return true if two types are identical. This is like the // Return true if two types are identical. If this returns false,
// are_identical function, but also takes a CMP_TAGS argument // and REASON is not NULL, it may set *REASON.
// indicating whether to compare struct tags. Otherwise the
// parameters are as for are_identical.
static bool static bool
are_identical_cmp_tags(const Type* lhs, const Type* rhs, are_identical(const Type* lhs, const Type* rhs, int flags,
Cmp_tags, bool errors_are_identical, std::string* reason);
std::string* reason);
// Return true if two types are compatible for use in a binary // Return true if two types are compatible for use in a binary
// operation, other than a shift, comparison, or channel send. This // operation, other than a shift, comparison, or channel send. This
...@@ -648,7 +641,7 @@ class Type ...@@ -648,7 +641,7 @@ class Type
// Types which are equivalent according to are_identical will have // Types which are equivalent according to are_identical will have
// the same hash code. // the same hash code.
unsigned int unsigned int
hash_for_method(Gogo*) const; hash_for_method(Gogo*, int) const;
// Return the type classification. // Return the type classification.
Type_classification Type_classification
...@@ -1082,7 +1075,7 @@ class Type ...@@ -1082,7 +1075,7 @@ class Type
{ return true; } { return true; }
virtual unsigned int virtual unsigned int
do_hash_for_method(Gogo*) const; do_hash_for_method(Gogo*, int) const;
virtual Btype* virtual Btype*
do_get_backend(Gogo*) = 0; do_get_backend(Gogo*) = 0;
...@@ -1381,14 +1374,18 @@ class Type ...@@ -1381,14 +1374,18 @@ class Type
bool in_heap_; bool in_heap_;
}; };
// Type hash table operations. // Type hash table operations, treating aliases as identical to the
// types that they alias.
class Type_hash_identical class Type_hash_identical
{ {
public: public:
unsigned int unsigned int
operator()(const Type* type) const operator()(const Type* type) const
{ return type->hash_for_method(NULL); } {
return type->hash_for_method(NULL,
Type::COMPARE_ERRORS | Type::COMPARE_TAGS);
}
}; };
class Type_identical class Type_identical
...@@ -1396,7 +1393,11 @@ class Type_identical ...@@ -1396,7 +1393,11 @@ class Type_identical
public: public:
bool bool
operator()(const Type* t1, const Type* t2) const operator()(const Type* t1, const Type* t2) const
{ return Type::are_identical(t1, t2, false, NULL); } {
return Type::are_identical(t1, t2,
Type::COMPARE_ERRORS | Type::COMPARE_TAGS,
NULL);
}
}; };
// An identifier with a type. // An identifier with a type.
...@@ -1724,7 +1725,7 @@ protected: ...@@ -1724,7 +1725,7 @@ protected:
{ return true; } { return true; }
unsigned int unsigned int
do_hash_for_method(Gogo*) const; do_hash_for_method(Gogo*, int) const;
Btype* Btype*
do_get_backend(Gogo*); do_get_backend(Gogo*);
...@@ -1810,7 +1811,7 @@ class Float_type : public Type ...@@ -1810,7 +1811,7 @@ class Float_type : public Type
{ return true; } { return true; }
unsigned int unsigned int
do_hash_for_method(Gogo*) const; do_hash_for_method(Gogo*, int) const;
Btype* Btype*
do_get_backend(Gogo*); do_get_backend(Gogo*);
...@@ -1888,7 +1889,7 @@ class Complex_type : public Type ...@@ -1888,7 +1889,7 @@ class Complex_type : public Type
{ return true; } { return true; }
unsigned int unsigned int
do_hash_for_method(Gogo*) const; do_hash_for_method(Gogo*, int) const;
Btype* Btype*
do_get_backend(Gogo*); do_get_backend(Gogo*);
...@@ -2036,8 +2037,8 @@ class Function_type : public Type ...@@ -2036,8 +2037,8 @@ class Function_type : public Type
// Whether this type is the same as T. // Whether this type is the same as T.
bool bool
is_identical(const Function_type* t, bool ignore_receiver, is_identical(const Function_type* t, bool ignore_receiver, int flags,
Cmp_tags, bool errors_are_identical, std::string*) const; std::string*) const;
// Record that this is a varargs function. // Record that this is a varargs function.
void void
...@@ -2102,7 +2103,7 @@ class Function_type : public Type ...@@ -2102,7 +2103,7 @@ class Function_type : public Type
{ return false; } { return false; }
unsigned int unsigned int
do_hash_for_method(Gogo*) const; do_hash_for_method(Gogo*, int) const;
Btype* Btype*
do_get_backend(Gogo*); do_get_backend(Gogo*);
...@@ -2231,7 +2232,7 @@ class Pointer_type : public Type ...@@ -2231,7 +2232,7 @@ class Pointer_type : public Type
{ return true; } { return true; }
unsigned int unsigned int
do_hash_for_method(Gogo*) const; do_hash_for_method(Gogo*, int) const;
Btype* Btype*
do_get_backend(Gogo*); do_get_backend(Gogo*);
...@@ -2478,8 +2479,7 @@ class Struct_type : public Type ...@@ -2478,8 +2479,7 @@ class Struct_type : public Type
// Whether this type is identical with T. // Whether this type is identical with T.
bool bool
is_identical(const Struct_type* t, Cmp_tags, is_identical(const Struct_type* t, int) const;
bool errors_are_identical) const;
// Return whether NAME is a local field which is not exported. This // Return whether NAME is a local field which is not exported. This
// is only used for better error reporting. // is only used for better error reporting.
...@@ -2498,7 +2498,7 @@ class Struct_type : public Type ...@@ -2498,7 +2498,7 @@ class Struct_type : public Type
has_any_methods() const has_any_methods() const
{ return this->all_methods_ != NULL; } { return this->all_methods_ != NULL; }
// Return the methods for tihs type. This should only be called // Return the methods for this type. This should only be called
// after the finalize_methods pass. // after the finalize_methods pass.
const Methods* const Methods*
methods() const methods() const
...@@ -2590,7 +2590,7 @@ class Struct_type : public Type ...@@ -2590,7 +2590,7 @@ class Struct_type : public Type
do_in_heap(); do_in_heap();
unsigned int unsigned int
do_hash_for_method(Gogo*) const; do_hash_for_method(Gogo*, int) const;
Btype* Btype*
do_get_backend(Gogo*); do_get_backend(Gogo*);
...@@ -2684,8 +2684,7 @@ class Array_type : public Type ...@@ -2684,8 +2684,7 @@ class Array_type : public Type
// Whether this type is identical with T. // Whether this type is identical with T.
bool bool
is_identical(const Array_type* t, Cmp_tags, is_identical(const Array_type* t, int) const;
bool errors_are_identical) const;
// Return an expression for the pointer to the values in an array. // Return an expression for the pointer to the values in an array.
Expression* Expression*
...@@ -2767,7 +2766,7 @@ class Array_type : public Type ...@@ -2767,7 +2766,7 @@ class Array_type : public Type
{ return this->length_ == NULL || this->element_type_->in_heap(); } { return this->length_ == NULL || this->element_type_->in_heap(); }
unsigned int unsigned int
do_hash_for_method(Gogo*) const; do_hash_for_method(Gogo*, int) const;
Btype* Btype*
do_get_backend(Gogo*); do_get_backend(Gogo*);
...@@ -2850,8 +2849,7 @@ class Map_type : public Type ...@@ -2850,8 +2849,7 @@ class Map_type : public Type
// Whether this type is identical with T. // Whether this type is identical with T.
bool bool
is_identical(const Map_type* t, Cmp_tags, is_identical(const Map_type* t, int) const;
bool errors_are_identical) const;
// Import a map type. // Import a map type.
static Map_type* static Map_type*
...@@ -2885,7 +2883,7 @@ class Map_type : public Type ...@@ -2885,7 +2883,7 @@ class Map_type : public Type
} }
unsigned int unsigned int
do_hash_for_method(Gogo*) const; do_hash_for_method(Gogo*, int) const;
Btype* Btype*
do_get_backend(Gogo*); do_get_backend(Gogo*);
...@@ -2970,8 +2968,7 @@ class Channel_type : public Type ...@@ -2970,8 +2968,7 @@ class Channel_type : public Type
// Whether this type is identical with T. // Whether this type is identical with T.
bool bool
is_identical(const Channel_type* t, Cmp_tags, is_identical(const Channel_type* t, int) const;
bool errors_are_identical) const;
// Import a channel type. // Import a channel type.
static Channel_type* static Channel_type*
...@@ -3000,7 +2997,7 @@ class Channel_type : public Type ...@@ -3000,7 +2997,7 @@ class Channel_type : public Type
{ return true; } { return true; }
unsigned int unsigned int
do_hash_for_method(Gogo*) const; do_hash_for_method(Gogo*, int) const;
Btype* Btype*
do_get_backend(Gogo*); do_get_backend(Gogo*);
...@@ -3090,8 +3087,7 @@ class Interface_type : public Type ...@@ -3090,8 +3087,7 @@ class Interface_type : public Type
// Whether this type is identical with T. REASON is as in // Whether this type is identical with T. REASON is as in
// implements_interface. // implements_interface.
bool bool
is_identical(const Interface_type* t, Cmp_tags, is_identical(const Interface_type* t, int) const;
bool errors_are_identical) const;
// Whether we can assign T to this type. is_identical is known to // Whether we can assign T to this type. is_identical is known to
// be false. // be false.
...@@ -3151,7 +3147,7 @@ class Interface_type : public Type ...@@ -3151,7 +3147,7 @@ class Interface_type : public Type
{ return true; } { return true; }
unsigned int unsigned int
do_hash_for_method(Gogo*) const; do_hash_for_method(Gogo*, int) const;
Btype* Btype*
do_get_backend(Gogo*); do_get_backend(Gogo*);
...@@ -3476,7 +3472,7 @@ class Named_type : public Type ...@@ -3476,7 +3472,7 @@ class Named_type : public Type
{ return this->in_heap_ && this->type_->in_heap(); } { return this->in_heap_ && this->type_->in_heap(); }
unsigned int unsigned int
do_hash_for_method(Gogo*) const; do_hash_for_method(Gogo*, int) const;
Btype* Btype*
do_get_backend(Gogo*); do_get_backend(Gogo*);
...@@ -3639,8 +3635,8 @@ class Forward_declaration_type : public Type ...@@ -3639,8 +3635,8 @@ class Forward_declaration_type : public Type
{ return this->real_type()->in_heap(); } { return this->real_type()->in_heap(); }
unsigned int unsigned int
do_hash_for_method(Gogo* gogo) const do_hash_for_method(Gogo* gogo, int flags) const
{ return this->real_type()->hash_for_method(gogo); } { return this->real_type()->hash_for_method(gogo, flags); }
Btype* Btype*
do_get_backend(Gogo* gogo); do_get_backend(Gogo* gogo);
......
...@@ -777,7 +777,9 @@ Gogo::assign_with_write_barrier(Function* function, Block* enclosing, ...@@ -777,7 +777,9 @@ Gogo::assign_with_write_barrier(Function* function, Block* enclosing,
inserter->insert(lhs_temp); inserter->insert(lhs_temp);
lhs = Expression::make_temporary_reference(lhs_temp, loc); lhs = Expression::make_temporary_reference(lhs_temp, loc);
if (!Type::are_identical(type, rhs->type(), false, NULL) if (!Type::are_identical(type, rhs->type(),
Type::COMPARE_ERRORS | Type::COMPARE_TAGS,
NULL)
&& rhs->type()->interface_type() != NULL && rhs->type()->interface_type() != NULL
&& !rhs->is_variable()) && !rhs->is_variable())
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment