diff mbox

Go patch committed: Fix spurious redefinition error

Message ID CAOyqgcV9YyuOUjovPR_OPmDbHWfhu+-B6J_ppTmm7kJD4FemgQ@mail.gmail.com
State New
Headers show

Commit Message

Ian Lance Taylor Dec. 22, 2016, 11:05 p.m. UTC
This patch to the Go frontend by Than McIntosh changes
Struct_type::do_mangled_name to incorporate the field names even for
hidden symbols. This is needed in cases where a package imports a type
"S" that has an anonymous struct, e.g.

  // imported from some other package
  type S struct {
    X struct{ _ struct{} }
  }

and then defines a local type that uses a structurally identical
anonymous struct, e.g.

  // defined locally
  type T struct {
    U struct{ _ struct{} }
  }

In the case above both types triggered the creation of hash/equal
methods, but the method names were clashing (since both structs had
the same mangled name).

This fixes https://golang.org/issue/18414.

Bootstrapped and ran Go testsuite on x86_64-pc-linux-gnu.  Committed
to mainline.

Ian
diff mbox

Patch

Index: gcc/go/gofrontend/MERGE
===================================================================
--- gcc/go/gofrontend/MERGE	(revision 243805)
+++ gcc/go/gofrontend/MERGE	(working copy)
@@ -1,4 +1,4 @@ 
-4a0bb435bbb1d1516b486d1998e8dc184576db61
+9a89f32811e6b3a29e22dda46e9c23811f562876
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
Index: gcc/go/gofrontend/gogo.h
===================================================================
--- gcc/go/gofrontend/gogo.h	(revision 243766)
+++ gcc/go/gofrontend/gogo.h	(working copy)
@@ -202,6 +202,27 @@  class Gogo
   }
 
   // Given a name which may or may not have been hidden, return the
+  // name to use within a mangled symbol name.
+  static std::string
+  mangle_possibly_hidden_name(const std::string& name)
+  { 
+    // FIXME: This adds in pkgpath twice for hidden symbols, which is
+    // less than ideal.
+    std::string n;
+    if (!Gogo::is_hidden_name(name))
+      n = name;
+    else
+      {
+        n = ".";
+        std::string pkgpath = Gogo::hidden_name_pkgpath(name);
+        n.append(Gogo::pkgpath_for_symbol(pkgpath));
+        n.append(1, '.');
+        n.append(Gogo::unpack_hidden_name(name));
+      }
+    return n;
+  }
+
+  // Given a name which may or may not have been hidden, return the
   // name to use in an error message.
   static std::string
   message_name(const std::string& name);
Index: gcc/go/gofrontend/types.cc
===================================================================
--- gcc/go/gofrontend/types.cc	(revision 243735)
+++ gcc/go/gofrontend/types.cc	(working copy)
@@ -1337,18 +1337,8 @@  Type::type_descriptor_var_name(Gogo* gog
 	}
     }
 
-  // FIXME: This adds in pkgpath twice for hidden symbols, which is
-  // pointless.
-  const std::string& name(no->name());
-  if (!Gogo::is_hidden_name(name))
-    ret.append(name);
-  else
-    {
-      ret.append(1, '.');
-      ret.append(Gogo::pkgpath_for_symbol(Gogo::hidden_name_pkgpath(name)));
-      ret.append(1, '.');
-      ret.append(Gogo::unpack_hidden_name(name));
-    }
+  std::string mname(Gogo::mangle_possibly_hidden_name(no->name()));
+  ret.append(mname);
 
   return ret;
 }
@@ -5638,8 +5628,9 @@  Struct_type::do_mangled_name(Gogo* gogo,
 	  if (p->is_anonymous())
 	    ret->append("0_");
 	  else
-	    {
-	      std::string n = Gogo::unpack_hidden_name(p->field_name());
+            {
+
+              std::string n(Gogo::mangle_possibly_hidden_name(p->field_name()));
 	      char buf[20];
 	      snprintf(buf, sizeof buf, "%u_",
 		       static_cast<unsigned int>(n.length()));
@@ -8712,17 +8703,7 @@  Interface_type::do_mangled_name(Gogo* go
 	{
 	  if (!p->name().empty())
 	    {
-	      std::string n;
-	      if (!Gogo::is_hidden_name(p->name()))
-		n = p->name();
-	      else
-		{
-		  n = ".";
-		  std::string pkgpath = Gogo::hidden_name_pkgpath(p->name());
-		  n.append(Gogo::pkgpath_for_symbol(pkgpath));
-		  n.append(1, '.');
-		  n.append(Gogo::unpack_hidden_name(p->name()));
-		}
+	      std::string n(Gogo::mangle_possibly_hidden_name(p->name()));
 	      char buf[20];
 	      snprintf(buf, sizeof buf, "%u_",
 		       static_cast<unsigned int>(n.length()));