Commit 99303b32 by Ian Lance Taylor

compiler: Don't use memcmp for equality if struct has trailing padding.

From-SVN: r193791
parent 489a33f9
...@@ -2382,7 +2382,7 @@ class Error_type : public Type ...@@ -2382,7 +2382,7 @@ class Error_type : public Type
protected: protected:
bool bool
do_compare_is_identity(Gogo*) const do_compare_is_identity(Gogo*)
{ return false; } { return false; }
Btype* Btype*
...@@ -2420,7 +2420,7 @@ class Void_type : public Type ...@@ -2420,7 +2420,7 @@ class Void_type : public Type
protected: protected:
bool bool
do_compare_is_identity(Gogo*) const do_compare_is_identity(Gogo*)
{ return false; } { return false; }
Btype* Btype*
...@@ -2458,7 +2458,7 @@ class Boolean_type : public Type ...@@ -2458,7 +2458,7 @@ class Boolean_type : public Type
protected: protected:
bool bool
do_compare_is_identity(Gogo*) const do_compare_is_identity(Gogo*)
{ return true; } { return true; }
Btype* Btype*
...@@ -3085,7 +3085,7 @@ class Sink_type : public Type ...@@ -3085,7 +3085,7 @@ class Sink_type : public Type
protected: protected:
bool bool
do_compare_is_identity(Gogo*) const do_compare_is_identity(Gogo*)
{ return false; } { return false; }
Btype* Btype*
...@@ -3963,7 +3963,7 @@ class Nil_type : public Type ...@@ -3963,7 +3963,7 @@ class Nil_type : public Type
protected: protected:
bool bool
do_compare_is_identity(Gogo*) const do_compare_is_identity(Gogo*)
{ return false; } { return false; }
Btype* Btype*
...@@ -4014,7 +4014,7 @@ class Call_multiple_result_type : public Type ...@@ -4014,7 +4014,7 @@ class Call_multiple_result_type : public Type
} }
bool bool
do_compare_is_identity(Gogo*) const do_compare_is_identity(Gogo*)
{ return false; } { return false; }
Btype* Btype*
...@@ -4291,7 +4291,7 @@ Struct_type::struct_has_hidden_fields(const Named_type* within, ...@@ -4291,7 +4291,7 @@ Struct_type::struct_has_hidden_fields(const Named_type* within,
// comparisons. // comparisons.
bool bool
Struct_type::do_compare_is_identity(Gogo* gogo) const Struct_type::do_compare_is_identity(Gogo* gogo)
{ {
const Struct_field_list* fields = this->fields_; const Struct_field_list* fields = this->fields_;
if (fields == NULL) if (fields == NULL)
...@@ -4323,6 +4323,16 @@ Struct_type::do_compare_is_identity(Gogo* gogo) const ...@@ -4323,6 +4323,16 @@ Struct_type::do_compare_is_identity(Gogo* gogo) const
return false; return false;
offset += field_size; offset += field_size;
} }
unsigned int struct_size;
if (!this->backend_type_size(gogo, &struct_size))
return false;
if (offset != struct_size)
{
// Trailing padding may not be zero when on the stack.
return false;
}
return true; return true;
} }
...@@ -5267,7 +5277,7 @@ Array_type::do_verify() ...@@ -5267,7 +5277,7 @@ Array_type::do_verify()
// Whether we can use memcmp to compare this array. // Whether we can use memcmp to compare this array.
bool bool
Array_type::do_compare_is_identity(Gogo* gogo) const Array_type::do_compare_is_identity(Gogo* gogo)
{ {
if (this->length_ == NULL) if (this->length_ == NULL)
return false; return false;
...@@ -7968,7 +7978,7 @@ Named_type::do_has_pointer() const ...@@ -7968,7 +7978,7 @@ Named_type::do_has_pointer() const
// function. // function.
bool bool
Named_type::do_compare_is_identity(Gogo* gogo) const Named_type::do_compare_is_identity(Gogo* gogo)
{ {
// We don't use this->seen_ here because compare_is_identity may // We don't use this->seen_ here because compare_is_identity may
// call base() later, and that will mess up if seen_ is set here. // call base() later, and that will mess up if seen_ is set here.
......
...@@ -576,7 +576,7 @@ class Type ...@@ -576,7 +576,7 @@ class Type
// identity function which gets nothing but a pointer to the value // identity function which gets nothing but a pointer to the value
// and a size. // and a size.
bool bool
compare_is_identity(Gogo* gogo) const compare_is_identity(Gogo* gogo)
{ return this->do_compare_is_identity(gogo); } { return this->do_compare_is_identity(gogo); }
// Return a hash code for this type for the method hash table. // Return a hash code for this type for the method hash table.
...@@ -950,7 +950,7 @@ class Type ...@@ -950,7 +950,7 @@ class Type
{ return false; } { return false; }
virtual bool virtual bool
do_compare_is_identity(Gogo*) const = 0; do_compare_is_identity(Gogo*) = 0;
virtual unsigned int virtual unsigned int
do_hash_for_method(Gogo*) const; do_hash_for_method(Gogo*) const;
...@@ -1458,7 +1458,7 @@ class Integer_type : public Type ...@@ -1458,7 +1458,7 @@ class Integer_type : public Type
protected: protected:
bool bool
do_compare_is_identity(Gogo*) const do_compare_is_identity(Gogo*)
{ return true; } { return true; }
unsigned int unsigned int
...@@ -1535,7 +1535,7 @@ class Float_type : public Type ...@@ -1535,7 +1535,7 @@ class Float_type : public Type
protected: protected:
bool bool
do_compare_is_identity(Gogo*) const do_compare_is_identity(Gogo*)
{ return false; } { return false; }
unsigned int unsigned int
...@@ -1604,7 +1604,7 @@ class Complex_type : public Type ...@@ -1604,7 +1604,7 @@ class Complex_type : public Type
protected: protected:
bool bool
do_compare_is_identity(Gogo*) const do_compare_is_identity(Gogo*)
{ return false; } { return false; }
unsigned int unsigned int
...@@ -1664,7 +1664,7 @@ class String_type : public Type ...@@ -1664,7 +1664,7 @@ class String_type : public Type
{ return true; } { return true; }
bool bool
do_compare_is_identity(Gogo*) const do_compare_is_identity(Gogo*)
{ return false; } { return false; }
Btype* Btype*
...@@ -1778,7 +1778,7 @@ class Function_type : public Type ...@@ -1778,7 +1778,7 @@ class Function_type : public Type
{ return true; } { return true; }
bool bool
do_compare_is_identity(Gogo*) const do_compare_is_identity(Gogo*)
{ return false; } { return false; }
unsigned int unsigned int
...@@ -1853,7 +1853,7 @@ class Pointer_type : public Type ...@@ -1853,7 +1853,7 @@ class Pointer_type : public Type
{ return true; } { return true; }
bool bool
do_compare_is_identity(Gogo*) const do_compare_is_identity(Gogo*)
{ return true; } { return true; }
unsigned int unsigned int
...@@ -2139,7 +2139,7 @@ class Struct_type : public Type ...@@ -2139,7 +2139,7 @@ class Struct_type : public Type
do_has_pointer() const; do_has_pointer() const;
bool bool
do_compare_is_identity(Gogo*) const; do_compare_is_identity(Gogo*);
unsigned int unsigned int
do_hash_for_method(Gogo*) const; do_hash_for_method(Gogo*) const;
...@@ -2272,7 +2272,7 @@ class Array_type : public Type ...@@ -2272,7 +2272,7 @@ class Array_type : public Type
} }
bool bool
do_compare_is_identity(Gogo*) const; do_compare_is_identity(Gogo*);
unsigned int unsigned int
do_hash_for_method(Gogo*) const; do_hash_for_method(Gogo*) const;
...@@ -2365,7 +2365,7 @@ class Map_type : public Type ...@@ -2365,7 +2365,7 @@ class Map_type : public Type
{ return true; } { return true; }
bool bool
do_compare_is_identity(Gogo*) const do_compare_is_identity(Gogo*)
{ return false; } { return false; }
unsigned int unsigned int
...@@ -2451,7 +2451,7 @@ class Channel_type : public Type ...@@ -2451,7 +2451,7 @@ class Channel_type : public Type
{ return true; } { return true; }
bool bool
do_compare_is_identity(Gogo*) const do_compare_is_identity(Gogo*)
{ return true; } { return true; }
unsigned int unsigned int
...@@ -2582,7 +2582,7 @@ class Interface_type : public Type ...@@ -2582,7 +2582,7 @@ class Interface_type : public Type
{ return true; } { return true; }
bool bool
do_compare_is_identity(Gogo*) const do_compare_is_identity(Gogo*)
{ return false; } { return false; }
unsigned int unsigned int
...@@ -2865,7 +2865,7 @@ class Named_type : public Type ...@@ -2865,7 +2865,7 @@ class Named_type : public Type
do_has_pointer() const; do_has_pointer() const;
bool bool
do_compare_is_identity(Gogo*) const; do_compare_is_identity(Gogo*);
unsigned int unsigned int
do_hash_for_method(Gogo*) const; do_hash_for_method(Gogo*) const;
...@@ -2949,7 +2949,7 @@ class Named_type : public Type ...@@ -2949,7 +2949,7 @@ class Named_type : public Type
// function exits. // function exits.
mutable bool seen_; mutable bool seen_;
// Like seen_, but used only by do_compare_is_identity. // Like seen_, but used only by do_compare_is_identity.
mutable bool seen_in_compare_is_identity_; bool seen_in_compare_is_identity_;
// Like seen_, but used only by do_get_backend. // Like seen_, but used only by do_get_backend.
bool seen_in_get_backend_; bool seen_in_get_backend_;
}; };
...@@ -3004,7 +3004,7 @@ class Forward_declaration_type : public Type ...@@ -3004,7 +3004,7 @@ class Forward_declaration_type : public Type
{ return this->real_type()->has_pointer(); } { return this->real_type()->has_pointer(); }
bool bool
do_compare_is_identity(Gogo* gogo) const do_compare_is_identity(Gogo* gogo)
{ return this->real_type()->compare_is_identity(gogo); } { return this->real_type()->compare_is_identity(gogo); }
unsigned int unsigned int
......
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