compiler: fix spurious redefinition error for anon struct
authorIan Lance Taylor <ian@gcc.gnu.org>
Thu, 22 Dec 2016 23:05:02 +0000 (23:05 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Thu, 22 Dec 2016 23:05:02 +0000 (23:05 +0000)
    Change 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).

    Fixes golang/go#18414

    Reviewed-on: https://go-review.googlesource.com/34621

From-SVN: r243899

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

index b8468965dba6c6fd853013f987d0fb0237db0be6..b9c62808b6745dd9c46b4078e169a88041ec7078 100644 (file)
@@ -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 23d1f08a59a7fb966891aa669ae00a7da682c8a2..905f48d233db9e95cd80882491e37c43cb37f14e 100644 (file)
@@ -201,6 +201,27 @@ class Gogo
     return name.substr(1, name.rfind('.') - 1);
   }
 
+  // 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
index e03201e25227862a9b2e698ab5e6cd481d9358bd..93d7d807aa8e75e1c26a3329da6931f5e874d515 100644 (file)
@@ -1337,18 +1337,8 @@ Type::type_descriptor_var_name(Gogo* gogo, Named_type* nt)
        }
     }
 
-  // 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, std::string* ret) const
          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* gogo, std::string* ret) const
        {
          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()));