]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
compiler: Fix handling of hidden methods for unnamed types.
authorIan Lance Taylor <ian@gcc.gnu.org>
Fri, 11 Oct 2013 22:53:17 +0000 (22:53 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Fri, 11 Oct 2013 22:53:17 +0000 (22:53 +0000)
If an interface has hidden methods, we must make the interface
table comdat if it is for an unnamed type.

When we create a stub method for an unnamed type, don't make
it publically visible.

From-SVN: r203468

gcc/go/gofrontend/gogo-tree.cc
gcc/go/gofrontend/gogo.cc
gcc/go/gofrontend/gogo.h
gcc/go/gofrontend/types.cc

index fbc46526ef0d684dd951e76da5101f9c560b0cf3..ca80869da6ad1b02a272789d21e93ea891dd6048 100644 (file)
@@ -2154,10 +2154,11 @@ Gogo::interface_method_table_for_type(const Interface_type* interface,
   TREE_CONSTANT(decl) = 1;
   DECL_INITIAL(decl) = constructor;
 
-  // If the interface type has hidden methods, then this is the only
-  // definition of the table.  Otherwise it is a comdat table which
-  // may be defined in multiple packages.
-  if (has_hidden_methods)
+  // If the interface type has hidden methods, and the table is for a
+  // named type, then this is the only definition of the table.
+  // Otherwise it is a comdat table which may be defined in multiple
+  // packages.
+  if (has_hidden_methods && type->named_type() != NULL)
     TREE_PUBLIC(decl) = 1;
   else
     {
index 0796caaa94ca8e3b032ab85ebf4ae75018758159..eebb75377fae537fa5331f6b5f1d802daeaa1db5 100644 (file)
@@ -3320,7 +3320,8 @@ Function::Function(Function_type* type, Function* enclosing, Block* block,
     closure_var_(NULL), block_(block), location_(location), labels_(),
     local_type_count_(0), descriptor_(NULL), fndecl_(NULL), defer_stack_(NULL),
     is_sink_(false), results_are_named_(false), nointerface_(false),
-    calls_recover_(false), is_recover_thunk_(false), has_recover_thunk_(false),
+    is_unnamed_type_stub_method_(false), calls_recover_(false),
+    is_recover_thunk_(false), has_recover_thunk_(false),
     in_unique_section_(false)
 {
 }
@@ -3844,7 +3845,8 @@ Function::get_or_make_decl(Gogo* gogo, Named_object* no)
       else if (!Gogo::is_hidden_name(no->name())
                || this->type_->is_method())
         {
-          is_visible = true;
+         if (!this->is_unnamed_type_stub_method_)
+           is_visible = true;
           std::string pkgpath = gogo->pkgpath_symbol();
           if (this->type_->is_method()
               && Gogo::is_hidden_name(no->name())
index 8c4ccf981797aaf00395a23f6786dfe3be36a5b6..31b258d62d6e3e17399af7706980780f55e021c5 100644 (file)
@@ -953,6 +953,15 @@ class Function
     this->nointerface_ = true;
   }
 
+  // Record that this function is a stub method created for an unnamed
+  // type.
+  void
+  set_is_unnamed_type_stub_method()
+  {
+    go_assert(this->is_method());
+    this->is_unnamed_type_stub_method_ = true;
+  }
+
   // Add a new field to the closure variable.
   void
   add_closure_field(Named_object* var, Location loc)
@@ -1178,6 +1187,9 @@ class Function
   bool results_are_named_ : 1;
   // True if this method should not be included in the type descriptor.
   bool nointerface_ : 1;
+  // True if this function is a stub method created for an unnamed
+  // type.
+  bool is_unnamed_type_stub_method_ : 1;
   // True if this function calls the predeclared recover function.
   bool calls_recover_ : 1;
   // True if this a thunk built for a function which calls recover.
index f73ca7ae6f6c98777a98ae5fe37298b42902062b..69e3e99c1ff03e31bcdaf8f235ef950443104869 100644 (file)
@@ -9031,6 +9031,8 @@ Type::build_stub_methods(Gogo* gogo, const Type* type, const Methods* methods,
                                      fntype->is_varargs(), location);
          gogo->finish_function(fntype->location());
 
+         if (type->named_type() == NULL && stub->is_function())
+           stub->func_value()->set_is_unnamed_type_stub_method();
          if (m->nointerface() && stub->is_function())
            stub->func_value()->set_nointerface();
        }