Commit d9930d55 by Ian Lance Taylor

Fix inheriting hidden methods with arguments of hidden type.

From-SVN: r178827
parent 61c4c150
...@@ -9239,7 +9239,13 @@ Call_expression::check_argument_type(int i, const Type* parameter_type, ...@@ -9239,7 +9239,13 @@ Call_expression::check_argument_type(int i, const Type* parameter_type,
bool issued_error) bool issued_error)
{ {
std::string reason; std::string reason;
if (!Type::are_assignable(parameter_type, argument_type, &reason)) bool ok;
if (this->are_hidden_fields_ok_)
ok = Type::are_assignable_hidden_ok(parameter_type, argument_type,
&reason);
else
ok = Type::are_assignable(parameter_type, argument_type, &reason);
if (!ok)
{ {
if (!issued_error) if (!issued_error)
{ {
......
...@@ -1198,8 +1198,9 @@ class Call_expression : public Expression ...@@ -1198,8 +1198,9 @@ class Call_expression : public Expression
source_location location) source_location location)
: Expression(EXPRESSION_CALL, location), : Expression(EXPRESSION_CALL, location),
fn_(fn), args_(args), type_(NULL), results_(NULL), tree_(NULL), fn_(fn), args_(args), type_(NULL), results_(NULL), tree_(NULL),
is_varargs_(is_varargs), varargs_are_lowered_(false), is_varargs_(is_varargs), are_hidden_fields_ok_(false),
types_are_determined_(false), is_deferred_(false), issued_error_(false) varargs_are_lowered_(false), types_are_determined_(false),
is_deferred_(false), issued_error_(false)
{ } { }
// The function to call. // The function to call.
...@@ -1249,6 +1250,12 @@ class Call_expression : public Expression ...@@ -1249,6 +1250,12 @@ class Call_expression : public Expression
set_varargs_are_lowered() set_varargs_are_lowered()
{ this->varargs_are_lowered_ = true; } { this->varargs_are_lowered_ = true; }
// Note that it is OK for this call to set hidden fields when
// passing arguments.
void
set_hidden_fields_are_ok()
{ this->are_hidden_fields_ok_ = true; }
// Whether this call is being deferred. // Whether this call is being deferred.
bool bool
is_deferred() const is_deferred() const
...@@ -1350,6 +1357,9 @@ class Call_expression : public Expression ...@@ -1350,6 +1357,9 @@ class Call_expression : public Expression
tree tree_; tree tree_;
// True if the last argument is a varargs argument (f(a...)). // True if the last argument is a varargs argument (f(a...)).
bool is_varargs_; bool is_varargs_;
// True if this statement may pass hidden fields in the arguments.
// This is used for generated method stubs.
bool are_hidden_fields_ok_;
// True if varargs have already been lowered. // True if varargs have already been lowered.
bool varargs_are_lowered_; bool varargs_are_lowered_;
// True if types have been determined. // True if types have been determined.
......
...@@ -490,8 +490,7 @@ class Temporary_statement : public Statement ...@@ -490,8 +490,7 @@ class Temporary_statement : public Statement
Type* Type*
type() const; type() const;
// Note that it is OK for this return statement to set hidden // Note that it is OK for this statement to set hidden fields.
// fields.
void void
set_hidden_fields_are_ok() set_hidden_fields_are_ok()
{ this->are_hidden_fields_ok_ = true; } { this->are_hidden_fields_ok_ = true; }
...@@ -533,8 +532,8 @@ class Temporary_statement : public Statement ...@@ -533,8 +532,8 @@ class Temporary_statement : public Statement
Expression* init_; Expression* init_;
// The backend representation of the temporary variable. // The backend representation of the temporary variable.
Bvariable* bvariable_; Bvariable* bvariable_;
// True if this statement may pass hidden fields in the return // True if this statement may set hidden fields when assigning the
// value. This is used for generated method stubs. // value to the temporary. This is used for generated method stubs.
bool are_hidden_fields_ok_; bool are_hidden_fields_ok_;
// True if something takes the address of this temporary variable. // True if something takes the address of this temporary variable.
bool is_address_taken_; bool is_address_taken_;
......
...@@ -7401,6 +7401,7 @@ Type::build_one_stub_method(Gogo* gogo, Method* method, ...@@ -7401,6 +7401,7 @@ Type::build_one_stub_method(Gogo* gogo, Method* method,
go_assert(func != NULL); go_assert(func != NULL);
Call_expression* call = Expression::make_call(func, arguments, is_varargs, Call_expression* call = Expression::make_call(func, arguments, is_varargs,
location); location);
call->set_hidden_fields_are_ok();
size_t count = call->result_count(); size_t count = call->result_count();
if (count == 0) if (count == 0)
gogo->add_statement(Statement::make_statement(call)); gogo->add_statement(Statement::make_statement(call));
......
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