OSDN Git Service

compiler: Don't use memcmp for equality if struct has trailing padding.
authorian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 25 Nov 2012 00:55:57 +0000 (00:55 +0000)
committerian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 25 Nov 2012 00:55:57 +0000 (00:55 +0000)
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-4_7-branch@193792 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/go/gofrontend/types.cc
gcc/go/gofrontend/types.h

index 90856a0..6abf102 100644 (file)
@@ -2391,7 +2391,7 @@ class Error_type : public Type
 
  protected:
   bool
-  do_compare_is_identity(Gogo*) const
+  do_compare_is_identity(Gogo*)
   { return false; }
 
   Btype*
@@ -2429,7 +2429,7 @@ class Void_type : public Type
 
  protected:
   bool
-  do_compare_is_identity(Gogo*) const
+  do_compare_is_identity(Gogo*)
   { return false; }
 
   Btype*
@@ -2467,7 +2467,7 @@ class Boolean_type : public Type
 
  protected:
   bool
-  do_compare_is_identity(Gogo*) const
+  do_compare_is_identity(Gogo*)
   { return true; }
 
   Btype*
@@ -3090,7 +3090,7 @@ class Sink_type : public Type
 
  protected:
   bool
-  do_compare_is_identity(Gogo*) const
+  do_compare_is_identity(Gogo*)
   { return false; }
 
   Btype*
@@ -3968,7 +3968,7 @@ class Nil_type : public Type
 
  protected:
   bool
-  do_compare_is_identity(Gogo*) const
+  do_compare_is_identity(Gogo*)
   { return false; }
 
   Btype*
@@ -4019,7 +4019,7 @@ class Call_multiple_result_type : public Type
   }
 
   bool
-  do_compare_is_identity(Gogo*) const
+  do_compare_is_identity(Gogo*)
   { return false; }
 
   Btype*
@@ -4296,7 +4296,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)
@@ -4328,6 +4328,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;
 }
 
@@ -5272,7 +5282,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;
@@ -7967,7 +7977,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.
index cced68d..a62a6cf 100644 (file)
@@ -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