From fdd6f94b11a377119dc23c679a1985737a2ae6d7 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor <ian@gcc.gnu.org> Date: Tue, 15 Feb 2011 22:37:07 +0000 Subject: [PATCH] Don't crash on erroneous thunk call. From-SVN: r170201 --- gcc/go/gofrontend/statements.cc | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/gcc/go/gofrontend/statements.cc b/gcc/go/gofrontend/statements.cc index 268c7284c4da..bb5a6a09d0b5 100644 --- a/gcc/go/gofrontend/statements.cc +++ b/gcc/go/gofrontend/statements.cc @@ -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 -- GitLab