compiler: don't export embedded builtins.
authorIan Lance Taylor <ian@gcc.gnu.org>
Fri, 23 Aug 2013 21:04:40 +0000 (21:04 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Fri, 23 Aug 2013 21:04:40 +0000 (21:04 +0000)
The panic in test/fixedbugs/bug461.go was caused by the fact that
reflect expects unexported fields in a struct to have a valid
package path. If a struct field is an embedded built-in type, it is
now given the package name of the currently compiling package, so it
remains unexported for purposes of reflect.

Fixed Issue 25.

From-SVN: r201951

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

index 0a86d4720626578997b4fd64056a146dc8389e47..b32c0587e6cdac181126775b56cfd8bcf97a13e1 100644 (file)
@@ -4221,6 +4221,22 @@ Struct_field::is_field_name(const std::string& name) const
     }
 }
 
+// Return whether this field is an embedded built-in type.
+
+bool
+Struct_field::is_embedded_builtin(Gogo* gogo) const
+{
+  const std::string& name(this->field_name());
+  // We know that a field is an embedded type if it is anonymous.
+  // We can decide if it is a built-in type by checking to see if it is
+  // registered globally under the field's name.
+  // This allows us to distinguish between embedded built-in types and
+  // embedded types that are aliases to built-in types.
+  return (this->is_anonymous()
+          && !Gogo::is_hidden_name(name)
+          && gogo->lookup_global(name.c_str()) != NULL);
+}
+
 // Class Struct_type.
 
 // A hash table used to find identical unnamed structs so that they
@@ -4835,11 +4851,16 @@ Struct_type::do_type_descriptor(Gogo* gogo, Named_type* name)
 
       ++q;
       go_assert(q->is_field_name("pkgPath"));
-      if (!Gogo::is_hidden_name(pf->field_name()))
-       fvals->push_back(Expression::make_nil(bloc));
+      bool is_embedded_builtin = pf->is_embedded_builtin(gogo);
+      if (!Gogo::is_hidden_name(pf->field_name()) && !is_embedded_builtin)
+        fvals->push_back(Expression::make_nil(bloc));
       else
        {
-         std::string n = Gogo::hidden_name_pkgpath(pf->field_name());
+         std::string n;
+          if (is_embedded_builtin)
+            n = gogo->package_name();
+          else
+            n = Gogo::hidden_name_pkgpath(pf->field_name());
          Expression* s = Expression::make_string(n, bloc);
          fvals->push_back(Expression::make_unary(OPERATOR_AND, s, bloc));
        }
index 56626f1960e2a84e38ef85a292c00b7b5a6f636c..8bc022eb8243398fa7db71dfef12ac9d0b6ddc1c 100644 (file)
@@ -1926,6 +1926,10 @@ class Struct_field
   bool
   is_field_name(const std::string& name) const;
 
+  // Return whether this struct field is an embedded built-in type.
+  bool
+  is_embedded_builtin(Gogo*) const;
+
   // The field type.
   Type*
   type() const