This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Go patch committed: Fix identical unnamed structs with methods


When gccgo saw multiple identical unnamed structs with methods assigned
to interfaces that used those methods, it would emit multiple copies of
the interface method table, causing a duplicate symbol error from the
assembler.  This patch fixes the bug.  I added a test case to the master
testsuite that will be copied in the gccgo testsuite in due course.
Bootstrapped and ran Go testsuite on x86_64-unknown-linux-gnu.
Committed to mainline and 4.8 branch.

Ian

diff -r 6791d7b7151c go/types.cc
--- a/go/types.cc	Wed Sep 18 11:34:51 2013 -0700
+++ b/go/types.cc	Wed Sep 18 14:50:19 2013 -0700
@@ -4229,6 +4229,11 @@
 
 Struct_type::Identical_structs Struct_type::identical_structs;
 
+// A hash table used to merge method sets for identical unnamed
+// structs.
+
+Struct_type::Struct_method_tables Struct_type::struct_method_tables;
+
 // Traversal.
 
 int
@@ -4693,9 +4698,24 @@
 				    const Interface_type* interface,
 				    bool is_pointer)
 {
+  std::pair<Struct_type*, Struct_type::Struct_method_table_pair*>
+    val(this, NULL);
+  std::pair<Struct_type::Struct_method_tables::iterator, bool> ins =
+    Struct_type::struct_method_tables.insert(val);
+
+  Struct_method_table_pair* smtp;
+  if (!ins.second)
+    smtp = ins.first->second;
+  else
+    {
+      smtp = new Struct_method_table_pair();
+      smtp->first = NULL;
+      smtp->second = NULL;
+      ins.first->second = smtp;
+    }
+
   return Type::interface_method_table(gogo, this, interface, is_pointer,
-				      &this->interface_method_tables_,
-				      &this->pointer_interface_method_tables_);
+				      &smtp->first, &smtp->second);
 }
 
 // Convert struct fields to the backend representation.  This is not
diff -r 6791d7b7151c go/types.h
--- a/go/types.h	Wed Sep 18 11:34:51 2013 -0700
+++ b/go/types.h	Wed Sep 18 14:50:19 2013 -0700
@@ -2041,8 +2041,7 @@
  public:
   Struct_type(Struct_field_list* fields, Location location)
     : Type(TYPE_STRUCT),
-      fields_(fields), location_(location), all_methods_(NULL),
-      interface_method_tables_(NULL), pointer_interface_method_tables_(NULL)
+      fields_(fields), location_(location), all_methods_(NULL)
   { }
 
   // Return the field NAME.  This only looks at local fields, not at
@@ -2200,6 +2199,16 @@
 
   static Identical_structs identical_structs;
 
+  // Used to manage method tables for identical unnamed structs.
+  typedef std::pair<Interface_method_tables*, Interface_method_tables*>
+    Struct_method_table_pair;
+
+  typedef Unordered_map_hash(Struct_type*, Struct_method_table_pair*,
+			     Type_hash_identical, Type_identical)
+    Struct_method_tables;
+
+  static Struct_method_tables struct_method_tables;
+
   // Used to avoid infinite loops in field_reference_depth.
   struct Saw_named_type
   {
@@ -2218,13 +2227,6 @@
   Location location_;
   // If this struct is unnamed, a list of methods.
   Methods* all_methods_;
-  // A mapping from interfaces to the associated interface method
-  // tables for this type.  Only used if this struct is unnamed.
-  Interface_method_tables* interface_method_tables_;
-  // A mapping from interfaces to the associated interface method
-  // tables for pointers to this type.  Only used if this struct is
-  // unnamed.
-  Interface_method_tables* pointer_interface_method_tables_;
 };
 
 // The type of an array.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]