summaryrefslogtreecommitdiff
path: root/gcc/go
diff options
context:
space:
mode:
authorian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>2013-10-11 22:53:17 +0000
committerian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>2013-10-11 22:53:17 +0000
commitc3865819fdb914e38b00f10c42ad6e1b16ac75f9 (patch)
tree34dffec5bc928bd0f98e09d5dc441034f6eb6c68 /gcc/go
parent97267c3983ecd410a708559b403af8ad764fc92e (diff)
downloadgcc-c3865819fdb914e38b00f10c42ad6e1b16ac75f9.tar.gz
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@203468 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/go')
-rw-r--r--gcc/go/gofrontend/gogo-tree.cc9
-rw-r--r--gcc/go/gofrontend/gogo.cc6
-rw-r--r--gcc/go/gofrontend/gogo.h12
-rw-r--r--gcc/go/gofrontend/types.cc2
4 files changed, 23 insertions, 6 deletions
diff --git a/gcc/go/gofrontend/gogo-tree.cc b/gcc/go/gofrontend/gogo-tree.cc
index fbc46526ef0..ca80869da6a 100644
--- a/gcc/go/gofrontend/gogo-tree.cc
+++ b/gcc/go/gofrontend/gogo-tree.cc
@@ -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
{
diff --git a/gcc/go/gofrontend/gogo.cc b/gcc/go/gofrontend/gogo.cc
index 0796caaa94c..eebb75377fa 100644
--- a/gcc/go/gofrontend/gogo.cc
+++ b/gcc/go/gofrontend/gogo.cc
@@ -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())
diff --git a/gcc/go/gofrontend/gogo.h b/gcc/go/gofrontend/gogo.h
index 8c4ccf98179..31b258d62d6 100644
--- a/gcc/go/gofrontend/gogo.h
+++ b/gcc/go/gofrontend/gogo.h
@@ -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.
diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc
index f73ca7ae6f6..69e3e99c1ff 100644
--- a/gcc/go/gofrontend/types.cc
+++ b/gcc/go/gofrontend/types.cc
@@ -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();
}