Go patch committed: Don't crash on erroneous thunk call

Submitted by Ian Taylor on Feb. 15, 2011, 10:37 p.m.

Details

Message ID mcroc6c53hm.fsf@google.com
State New
Headers show

Commit Message

Ian Taylor Feb. 15, 2011, 10:37 p.m.
This patch to the Go frontend avoids crashing on an erroneous thunk
call.  This treats the calls built for thunks more like regular calls,
and runs the usual type checking pass on them.  Bootstrapped and ran Go
testsuite on x86_64-unknown-linux-gnu.  Committed to mainline.

Ian

Patch hide | download patch | download mbox

diff -r b511d4c035b7 go/statements.cc
--- a/go/statements.cc	Tue Feb 15 11:52:43 2011 -0800
+++ b/go/statements.cc	Tue Feb 15 14:34:31 2011 -0800
@@ -2215,6 +2215,8 @@ 
   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 @@ 
       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 @@ 
   // 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