aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2017-06-06 20:57:03 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2017-06-06 20:57:03 +0000
commitf788537d682b78a5496276da4e35c8462317175f (patch)
treeebc21445074d9318af7561d390a57dd6c06bd2ad
parentbbf974160054c4b8aa3f0f49084bb46521195a51 (diff)
downloadgcc-f788537d682b78a5496276da4e35c8462317175f.zip
gcc-f788537d682b78a5496276da4e35c8462317175f.tar.gz
gcc-f788537d682b78a5496276da4e35c8462317175f.tar.bz2
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 From-SVN: r248934
-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 33259da..df16770 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 fec206d..a656b06 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 5567605..43fb854 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*);