re PR go/65755 (incorrect reflection of struct fields with gccgo)
authorIan Lance Taylor <ian@gcc.gnu.org>
Fri, 17 Apr 2015 18:19:44 +0000 (18:19 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Fri, 17 Apr 2015 18:19:44 +0000 (18:19 +0000)
PR go/65755
compiler, runtime, reflect: Use reflection string for type comparisons.

Change the runtime and reflect libraries to always use only
the type reflection string to determine whether two types are
equal.  It previously used the PkgPath and Name values for a
type name, but that required a PkgPath that did not match the
gc compiler.

Change the compiler to use the same PkgPath value as the gc
compiler in all cases.

Change the compiler to put the receiver type in the reflection
string for a type defined inside a method.

From-SVN: r222194

gcc/go/gofrontend/types.cc
libgo/go/reflect/type.go
libgo/runtime/go-typedesc-equal.c

index e93c6811d08f169eb04f0ab3ded05eadca69e8be..7a7a1039be16e3ef48bdef19f56f1510c482e094 100644 (file)
@@ -2253,22 +2253,7 @@ Type::uncommon_type_constructor(Gogo* gogo, Type* uncommon_type,
          const std::string& pkgpath(package == NULL
                                     ? gogo->pkgpath()
                                     : package->pkgpath());
-         n.assign(pkgpath);
-         unsigned int index;
-         const Named_object* in_function = name->in_function(&index);
-         if (in_function != NULL)
-           {
-             n.append(1, '.');
-             n.append(Gogo::unpack_hidden_name(in_function->name()));
-             if (index > 0)
-               {
-                 char buf[30];
-                 snprintf(buf, sizeof buf, "%u", index);
-                 n.append(1, '.');
-                 n.append(buf);
-               }
-           }
-         s = Expression::make_string(n, bloc);
+         s = Expression::make_string(pkgpath, bloc);
          vals->push_back(Expression::make_unary(OPERATOR_AND, s, bloc));
        }
     }
@@ -9102,22 +9087,17 @@ Named_type::do_reflection(Gogo* gogo, std::string* ret) const
     }
   if (!this->is_builtin())
     {
-      // We handle -fgo-prefix and -fgo-pkgpath differently here for
-      // compatibility with how the compiler worked before
-      // -fgo-pkgpath was introduced.  When -fgo-pkgpath is specified,
-      // we use it to make a unique reflection string, so that the
-      // type canonicalization in the reflect package will work.  In
-      // order to be compatible with the gc compiler, we put tabs into
-      // the package path, so that the reflect methods can discard it.
+      // When -fgo-pkgpath or -fgo-prefix is specified, we use it to
+      // make a unique reflection string, so that the type
+      // canonicalization in the reflect package will work.  In order
+      // to be compatible with the gc compiler, we put tabs into the
+      // package path, so that the reflect methods can discard it.
       const Package* package = this->named_object_->package();
-      if (gogo->pkgpath_from_option())
-       {
-         ret->push_back('\t');
-         ret->append(package != NULL
-                     ? package->pkgpath_symbol()
-                     : gogo->pkgpath_symbol());
-         ret->push_back('\t');
-       }
+      ret->push_back('\t');
+      ret->append(package != NULL
+                 ? package->pkgpath_symbol()
+                 : gogo->pkgpath_symbol());
+      ret->push_back('\t');
       ret->append(package != NULL
                  ? package->package_name()
                  : gogo->package_name());
@@ -9126,6 +9106,14 @@ Named_type::do_reflection(Gogo* gogo, std::string* ret) const
   if (this->in_function_ != NULL)
     {
       ret->push_back('\t');
+      const Typed_identifier* rcvr =
+       this->in_function_->func_value()->type()->receiver();
+      if (rcvr != NULL)
+       {
+         Named_type* rcvr_type = rcvr->type()->deref()->named_type();
+         ret->append(Gogo::unpack_hidden_name(rcvr_type->name()));
+         ret->push_back('.');
+       }
       ret->append(Gogo::unpack_hidden_name(this->in_function_->name()));
       ret->push_back('$');
       if (this->in_function_index_ > 0)
index 5cbf7e577a3338c883b9402ec47fdbe9c77eb436..7f0c6a85a0dde3fe187b39c8ab5bd3cb74040f2d 100644 (file)
@@ -1940,13 +1940,7 @@ func canonicalize(t Type) Type {
        if t == nil {
                return nil
        }
-       u := t.uncommon()
-       var s string
-       if u == nil || u.PkgPath() == "" {
-               s = t.rawString()
-       } else {
-               s = u.PkgPath() + "." + u.Name()
-       }
+       s := t.rawString()
        canonicalTypeLock.RLock()
        if r, ok := canonicalType[s]; ok {
                canonicalTypeLock.RUnlock()
index f8474fc9f6c64eab9ab036bc9d3ab7e50ebfab6e..90079f2202750ea16b79a8995b5e25efab500d47 100644 (file)
@@ -24,16 +24,5 @@ __go_type_descriptors_equal (const struct __go_type_descriptor *td1,
     return 0;
   if (td1->__code != td2->__code || td1->__hash != td2->__hash)
     return 0;
-  if (td1->__uncommon != NULL && td1->__uncommon->__name != NULL)
-    {
-      if (td2->__uncommon == NULL || td2->__uncommon->__name == NULL)
-       return 0;
-      return (__go_ptr_strings_equal (td1->__uncommon->__name,
-                                     td2->__uncommon->__name)
-             && __go_ptr_strings_equal (td1->__uncommon->__pkg_path,
-                                        td2->__uncommon->__pkg_path));
-    }
-  if (td2->__uncommon != NULL && td2->__uncommon->__name != NULL)
-    return 0;
   return __go_ptr_strings_equal (td1->__reflection, td2->__reflection);
 }