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
This commit is contained in:
parent
b7d93b468a
commit
55e0ab1ad9
4 changed files with 23 additions and 6 deletions
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue