Commit 55e0ab1a by Ian Lance Taylor

compiler: Fix handling of hidden methods for unnamed types.

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
parent b7d93b46
...@@ -2154,10 +2154,11 @@ Gogo::interface_method_table_for_type(const Interface_type* interface, ...@@ -2154,10 +2154,11 @@ Gogo::interface_method_table_for_type(const Interface_type* interface,
TREE_CONSTANT(decl) = 1; TREE_CONSTANT(decl) = 1;
DECL_INITIAL(decl) = constructor; DECL_INITIAL(decl) = constructor;
// If the interface type has hidden methods, then this is the only // If the interface type has hidden methods, and the table is for a
// definition of the table. Otherwise it is a comdat table which // named type, then this is the only definition of the table.
// may be defined in multiple packages. // Otherwise it is a comdat table which may be defined in multiple
if (has_hidden_methods) // packages.
if (has_hidden_methods && type->named_type() != NULL)
TREE_PUBLIC(decl) = 1; TREE_PUBLIC(decl) = 1;
else else
{ {
......
...@@ -3320,7 +3320,8 @@ Function::Function(Function_type* type, Function* enclosing, Block* block, ...@@ -3320,7 +3320,8 @@ Function::Function(Function_type* type, Function* enclosing, Block* block,
closure_var_(NULL), block_(block), location_(location), labels_(), closure_var_(NULL), block_(block), location_(location), labels_(),
local_type_count_(0), descriptor_(NULL), fndecl_(NULL), defer_stack_(NULL), local_type_count_(0), descriptor_(NULL), fndecl_(NULL), defer_stack_(NULL),
is_sink_(false), results_are_named_(false), nointerface_(false), 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) in_unique_section_(false)
{ {
} }
...@@ -3844,7 +3845,8 @@ Function::get_or_make_decl(Gogo* gogo, Named_object* no) ...@@ -3844,7 +3845,8 @@ Function::get_or_make_decl(Gogo* gogo, Named_object* no)
else if (!Gogo::is_hidden_name(no->name()) else if (!Gogo::is_hidden_name(no->name())
|| this->type_->is_method()) || this->type_->is_method())
{ {
is_visible = true; if (!this->is_unnamed_type_stub_method_)
is_visible = true;
std::string pkgpath = gogo->pkgpath_symbol(); std::string pkgpath = gogo->pkgpath_symbol();
if (this->type_->is_method() if (this->type_->is_method()
&& Gogo::is_hidden_name(no->name()) && Gogo::is_hidden_name(no->name())
......
...@@ -953,6 +953,15 @@ class Function ...@@ -953,6 +953,15 @@ class Function
this->nointerface_ = true; 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. // Add a new field to the closure variable.
void void
add_closure_field(Named_object* var, Location loc) add_closure_field(Named_object* var, Location loc)
...@@ -1178,6 +1187,9 @@ class Function ...@@ -1178,6 +1187,9 @@ class Function
bool results_are_named_ : 1; bool results_are_named_ : 1;
// True if this method should not be included in the type descriptor. // True if this method should not be included in the type descriptor.
bool nointerface_ : 1; 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. // True if this function calls the predeclared recover function.
bool calls_recover_ : 1; bool calls_recover_ : 1;
// True if this a thunk built for a function which calls recover. // True if this a thunk built for a function which calls recover.
......
...@@ -9031,6 +9031,8 @@ Type::build_stub_methods(Gogo* gogo, const Type* type, const Methods* methods, ...@@ -9031,6 +9031,8 @@ Type::build_stub_methods(Gogo* gogo, const Type* type, const Methods* methods,
fntype->is_varargs(), location); fntype->is_varargs(), location);
gogo->finish_function(fntype->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()) if (m->nointerface() && stub->is_function())
stub->func_value()->set_nointerface(); stub->func_value()->set_nointerface();
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment