aboutsummaryrefslogtreecommitdiff
path: root/gcc/go
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@google.com>2012-11-25 00:55:35 +0000
committerIan Lance Taylor <iant@google.com>2012-11-25 00:55:35 +0000
commit1dad67c80175851dccbc89f49e88ec843f7b9b45 (patch)
treeeab3c0a2597a40c59a103891f915b0ff4e65c03c /gcc/go
parentc4ca85f1d8187a65a57d772187c0eae1447a5a0b (diff)
compiler: Don't use memcmp for equality if struct has trailing padding.
git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@193791 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/go')
-rw-r--r--gcc/go/gofrontend/types.cc28
-rw-r--r--gcc/go/gofrontend/types.h32
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