aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2011-02-15 22:37:07 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2011-02-15 22:37:07 +0000
commitfdd6f94b11a377119dc23c679a1985737a2ae6d7 (patch)
tree655af659633c6288e1246526c2d3e83d0206ef53
parent69eb61d47a9c6dae5308134ee809d85882fbeb10 (diff)
downloadgcc-fdd6f94b11a377119dc23c679a1985737a2ae6d7.zip
gcc-fdd6f94b11a377119dc23c679a1985737a2ae6d7.tar.gz
gcc-fdd6f94b11a377119dc23c679a1985737a2ae6d7.tar.bz2
Don't crash on erroneous thunk call.
From-SVN: r170201
-rw-r--r--gcc/go/gofrontend/statements.cc31
1 files changed, 24 insertions, 7 deletions
diff --git a/gcc/go/gofrontend/statements.cc b/gcc/go/gofrontend/statements.cc
index 268c728..bb5a6a0 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