summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>2017-06-06 20:57:03 +0000
committerian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>2017-06-06 20:57:03 +0000
commitdb122cb9f301a8659577c928622f113e4ae536e0 (patch)
treeebc21445074d9318af7561d390a57dd6c06bd2ad
parent4792273361107396cc9678301de9af3f62aba5d4 (diff)
downloadgcc-db122cb9f301a8659577c928622f113e4ae536e0.tar.gz
compiler: typing fixes for Interface_mtable_expression
Interface_mtable_expression::do_type computes a type that incorporates Go type descriptors for the interface methods, whereas in order to have strict type agreement with the mtable data, the interface method fields need to be C function ptrs. Change the type recipe accordingly, and then update Interface_mtable_expression::do_get_backend to compute a revised backend type that uses the correct fcn types. Reviewed-on: https://go-review.googlesource.com/44750 git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@248934 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/go/gofrontend/MERGE2
-rw-r--r--gcc/go/gofrontend/expressions.cc47
-rw-r--r--gcc/go/gofrontend/expressions.h2
3 files changed, 40 insertions, 11 deletions
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index 33259da299f..df16770883e 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-e5870eac67d4d5b1f86bdbfb13dadf4d5723f71d
+7e3904e4370ccfd9062c2661c612476288244e17
The first line of this file holds the git revision number of the last
merge done from the gofrontend repository.
diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc
index fec206d4462..a656b0681a1 100644
--- a/gcc/go/gofrontend/expressions.cc
+++ b/gcc/go/gofrontend/expressions.cc
@@ -10156,9 +10156,13 @@ Call_expression::do_must_eval_in_order() const
Expression*
Call_expression::interface_method_function(
Interface_field_reference_expression* interface_method,
- Expression** first_arg_ptr)
+ Expression** first_arg_ptr,
+ Location location)
{
- *first_arg_ptr = interface_method->get_underlying_object();
+ Expression* object = interface_method->get_underlying_object();
+ Type* unsafe_ptr_type = Type::make_pointer_type(Type::make_void_type());
+ *first_arg_ptr =
+ Expression::make_unsafe_cast(unsafe_ptr_type, object, location);
return interface_method->get_function();
}
@@ -10267,7 +10271,8 @@ Call_expression::do_get_backend(Translate_context* context)
else
{
Expression* first_arg;
- fn = this->interface_method_function(interface_method, &first_arg);
+ fn = this->interface_method_function(interface_method, &first_arg,
+ location);
fn_args[0] = first_arg->get_backend(context);
}
@@ -15392,10 +15397,16 @@ Interface_mtable_expression::do_type()
Typed_identifier tid("__type_descriptor", Type::make_type_descriptor_ptr_type(),
this->location());
sfl->push_back(Struct_field(tid));
+ Type* unsafe_ptr_type = Type::make_pointer_type(Type::make_void_type());
for (Typed_identifier_list::const_iterator p = interface_methods->begin();
p != interface_methods->end();
++p)
- sfl->push_back(Struct_field(*p));
+ {
+ // We want C function pointers here, not func descriptors; model
+ // using void* pointers.
+ Typed_identifier method(p->name(), unsafe_ptr_type, p->location());
+ sfl->push_back(Struct_field(method));
+ }
Struct_type* st = Type::make_struct_type(sfl, this->location());
st->set_is_struct_incomparable();
this->method_table_type_ = st;
@@ -15456,11 +15467,18 @@ Interface_mtable_expression::do_get_backend(Translate_context* context)
else
td_type = Type::make_pointer_type(this->type_);
+ std::vector<Backend::Btyped_identifier> bstructfields;
+
// Build an interface method table for a type: a type descriptor followed by a
// list of function pointers, one for each interface method. This is used for
// interfaces.
Expression_list* svals = new Expression_list();
- svals->push_back(Expression::make_type_descriptor(td_type, loc));
+ Expression* tdescriptor = Expression::make_type_descriptor(td_type, loc);
+ svals->push_back(tdescriptor);
+
+ Btype* tdesc_btype = tdescriptor->type()->get_backend(gogo);
+ Backend::Btyped_identifier btd("_type", tdesc_btype, loc);
+ bstructfields.push_back(btd);
Named_type* nt = this->type_->named_type();
Struct_type* st = this->type_->struct_type();
@@ -15480,13 +15498,24 @@ Interface_mtable_expression::do_get_backend(Translate_context* context)
Named_object* no = m->named_object();
go_assert(no->is_function() || no->is_function_declaration());
+
+ Btype* fcn_btype = m->type()->get_backend_fntype(gogo);
+ Backend::Btyped_identifier bmtype(p->name(), fcn_btype, loc);
+ bstructfields.push_back(bmtype);
+
svals->push_back(Expression::make_func_code_reference(no, loc));
}
- Btype* btype = this->type()->get_backend(gogo);
- Expression* mtable = Expression::make_struct_composite_literal(this->type(),
- svals, loc);
- Bexpression* ctor = mtable->get_backend(context);
+ Btype *btype = gogo->backend()->struct_type(bstructfields);
+ std::vector<Bexpression*> ctor_bexprs;
+ for (Expression_list::const_iterator pe = svals->begin();
+ pe != svals->end();
+ ++pe)
+ {
+ ctor_bexprs.push_back((*pe)->get_backend(context));
+ }
+ Bexpression* ctor =
+ gogo->backend()->constructor_expression(btype, ctor_bexprs, loc);
bool is_public = has_hidden_methods && this->type_->named_type() != NULL;
std::string asm_name(go_selectively_encode_id(mangled_name));
diff --git a/gcc/go/gofrontend/expressions.h b/gcc/go/gofrontend/expressions.h
index 5567605b151..43fb854e8d1 100644
--- a/gcc/go/gofrontend/expressions.h
+++ b/gcc/go/gofrontend/expressions.h
@@ -2287,7 +2287,7 @@ class Call_expression : public Expression
Expression*
interface_method_function(Interface_field_reference_expression*,
- Expression**);
+ Expression**, Location);
Bexpression*
set_results(Translate_context*);