Don't crash on erroneous thunk call.

From-SVN: r170201
This commit is contained in:
Ian Lance Taylor 2011-02-15 22:37:07 +00:00
parent 69eb61d47a
commit fdd6f94b11
1 changed files with 24 additions and 7 deletions

View File

@ -2215,6 +2215,8 @@ Thunk_statement::build_thunk(Gogo* gogo, const std::string& thunk_name,
Struct_field_list::const_iterator p = fields->begin();
for (unsigned int i = 0; i < next_index; ++i)
++p;
bool is_recover_call = ce->is_recover_call();
Expression* recover_arg = NULL;
for (; p != fields->end(); ++p, ++next_index)
{
Expression* thunk_param = Expression::make_var_reference(named_parameter,
@ -2224,19 +2226,28 @@ Thunk_statement::build_thunk(Gogo* gogo, const std::string& thunk_name,
Expression* param = Expression::make_field_reference(thunk_param,
next_index,
location);
call_params->push_back(param);
if (!is_recover_call)
call_params->push_back(param);
else
{
gcc_assert(call_params->empty());
recover_arg = param;
}
}
if (call_params->empty())
{
delete call_params;
call_params = NULL;
}
Expression* call = Expression::make_call(func_to_call, call_params, false,
location);
// We need to lower in case this is a builtin function.
call = call->lower(gogo, function, -1);
if (may_call_recover)
{
Call_expression* ce = call->call_expression();
if (ce != NULL)
ce->set_is_deferred();
}
Call_expression* call_ce = call->call_expression();
if (call_ce != NULL && may_call_recover)
call_ce->set_is_deferred();
Statement* call_statement = Statement::make_statement(call);
@ -2244,6 +2255,12 @@ Thunk_statement::build_thunk(Gogo* gogo, const std::string& thunk_name,
// just for this statement now.
call_statement->determine_types();
// Sanity check.
call->check_types(gogo);
if (call_ce != NULL && recover_arg != NULL)
call_ce->set_recover_arg(recover_arg);
gogo->add_statement(call_statement);
// If this is a defer statement, the label comes immediately after