diff options
author | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-11-25 00:55:35 +0000 |
---|---|---|
committer | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-11-25 00:55:35 +0000 |
commit | f32b37002707734cb1a60b2d2aa9142615adbc23 (patch) | |
tree | eab3c0a2597a40c59a103891f915b0ff4e65c03c /gcc/go | |
parent | aa0371dffa848b5d29e5af9afd93f4ec8961e6f7 (diff) | |
download | gcc-f32b37002707734cb1a60b2d2aa9142615adbc23.tar.gz |
compiler: Don't use memcmp for equality if struct has trailing padding.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@193791 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/go')
-rw-r--r-- | gcc/go/gofrontend/types.cc | 28 | ||||
-rw-r--r-- | gcc/go/gofrontend/types.h | 32 |
2 files changed, 35 insertions, 25 deletions
diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc index 5e9e828d9d5..1990b03c3f8 100644 --- a/gcc/go/gofrontend/types.cc +++ b/gcc/go/gofrontend/types.cc @@ -2382,7 +2382,7 @@ class Error_type : public Type protected: bool - do_compare_is_identity(Gogo*) const + do_compare_is_identity(Gogo*) { return false; } Btype* @@ -2420,7 +2420,7 @@ class Void_type : public Type protected: bool - do_compare_is_identity(Gogo*) const + do_compare_is_identity(Gogo*) { return false; } Btype* @@ -2458,7 +2458,7 @@ class Boolean_type : public Type protected: bool - do_compare_is_identity(Gogo*) const + do_compare_is_identity(Gogo*) { return true; } Btype* @@ -3085,7 +3085,7 @@ class Sink_type : public Type protected: bool - do_compare_is_identity(Gogo*) const + do_compare_is_identity(Gogo*) { return false; } Btype* @@ -3963,7 +3963,7 @@ class Nil_type : public Type protected: bool - do_compare_is_identity(Gogo*) const + do_compare_is_identity(Gogo*) { return false; } Btype* @@ -4014,7 +4014,7 @@ class Call_multiple_result_type : public Type } bool - do_compare_is_identity(Gogo*) const + do_compare_is_identity(Gogo*) { return false; } Btype* @@ -4291,7 +4291,7 @@ Struct_type::struct_has_hidden_fields(const Named_type* within, // comparisons. 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_; if (fields == NULL) @@ -4323,6 +4323,16 @@ Struct_type::do_compare_is_identity(Gogo* gogo) const return false; 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; } @@ -5267,7 +5277,7 @@ Array_type::do_verify() // Whether we can use memcmp to compare this array. bool -Array_type::do_compare_is_identity(Gogo* gogo) const +Array_type::do_compare_is_identity(Gogo* gogo) { if (this->length_ == NULL) return false; @@ -7968,7 +7978,7 @@ Named_type::do_has_pointer() const // function. 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 // call base() later, and that will mess up if seen_ is set here. diff --git a/gcc/go/gofrontend/types.h b/gcc/go/gofrontend/types.h index cced68ddd68..a62a6cfbf97 100644 --- a/gcc/go/gofrontend/types.h +++ b/gcc/go/gofrontend/types.h @@ -576,7 +576,7 @@ class Type // identity function which gets nothing but a pointer to the value // and a size. bool - compare_is_identity(Gogo* gogo) const + compare_is_identity(Gogo* gogo) { return this->do_compare_is_identity(gogo); } // Return a hash code for this type for the method hash table. @@ -950,7 +950,7 @@ class Type { return false; } virtual bool - do_compare_is_identity(Gogo*) const = 0; + do_compare_is_identity(Gogo*) = 0; virtual unsigned int do_hash_for_method(Gogo*) const; @@ -1458,7 +1458,7 @@ class Integer_type : public Type protected: bool - do_compare_is_identity(Gogo*) const + do_compare_is_identity(Gogo*) { return true; } unsigned int @@ -1535,7 +1535,7 @@ class Float_type : public Type protected: bool - do_compare_is_identity(Gogo*) const + do_compare_is_identity(Gogo*) { return false; } unsigned int @@ -1604,7 +1604,7 @@ class Complex_type : public Type protected: bool - do_compare_is_identity(Gogo*) const + do_compare_is_identity(Gogo*) { return false; } unsigned int @@ -1664,7 +1664,7 @@ class String_type : public Type { return true; } bool - do_compare_is_identity(Gogo*) const + do_compare_is_identity(Gogo*) { return false; } Btype* @@ -1778,7 +1778,7 @@ class Function_type : public Type { return true; } bool - do_compare_is_identity(Gogo*) const + do_compare_is_identity(Gogo*) { return false; } unsigned int @@ -1853,7 +1853,7 @@ class Pointer_type : public Type { return true; } bool - do_compare_is_identity(Gogo*) const + do_compare_is_identity(Gogo*) { return true; } unsigned int @@ -2139,7 +2139,7 @@ class Struct_type : public Type do_has_pointer() const; bool - do_compare_is_identity(Gogo*) const; + do_compare_is_identity(Gogo*); unsigned int do_hash_for_method(Gogo*) const; @@ -2272,7 +2272,7 @@ class Array_type : public Type } bool - do_compare_is_identity(Gogo*) const; + do_compare_is_identity(Gogo*); unsigned int do_hash_for_method(Gogo*) const; @@ -2365,7 +2365,7 @@ class Map_type : public Type { return true; } bool - do_compare_is_identity(Gogo*) const + do_compare_is_identity(Gogo*) { return false; } unsigned int @@ -2451,7 +2451,7 @@ class Channel_type : public Type { return true; } bool - do_compare_is_identity(Gogo*) const + do_compare_is_identity(Gogo*) { return true; } unsigned int @@ -2582,7 +2582,7 @@ class Interface_type : public Type { return true; } bool - do_compare_is_identity(Gogo*) const + do_compare_is_identity(Gogo*) { return false; } unsigned int @@ -2865,7 +2865,7 @@ class Named_type : public Type do_has_pointer() const; bool - do_compare_is_identity(Gogo*) const; + do_compare_is_identity(Gogo*); unsigned int do_hash_for_method(Gogo*) const; @@ -2949,7 +2949,7 @@ class Named_type : public Type // function exits. mutable bool seen_; // 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. bool seen_in_get_backend_; }; @@ -3004,7 +3004,7 @@ class Forward_declaration_type : public Type { return this->real_type()->has_pointer(); } bool - do_compare_is_identity(Gogo* gogo) const + do_compare_is_identity(Gogo* gogo) { return this->real_type()->compare_is_identity(gogo); } unsigned int |