Patchwork Go patch committed: Don't crash on erroneous return statement

login
register
mail settings
Submitter Ian Taylor
Date Dec. 21, 2010, 6:13 a.m.
Message ID <mcr1v5bpsap.fsf@google.com>
Download mbox | patch
Permalink /patch/76261/
State New
Headers show

Comments

Ian Taylor - Dec. 21, 2010, 6:13 a.m.
This patch to the Go frontend avoids crashing on an erroneous return
statement.  Bootstrapped and ran Go testsuite on
x86_64-unknown-linux-gnu.  Committed to mainline.

Ian

Patch

diff -r 674433f32c65 go/statements.cc
--- a/go/statements.cc	Fri Dec 17 19:00:58 2010 -0800
+++ b/go/statements.cc	Mon Dec 20 17:35:22 2010 -0800
@@ -2567,6 +2567,8 @@ 
 {
   Function* function = context->function()->func_value();
   tree fndecl = function->get_decl();
+  if (fndecl == error_mark_node || DECL_RESULT(fndecl) == error_mark_node)
+    return error_mark_node;
 
   const Typed_identifier_list* results = this->results_;
 
@@ -2580,6 +2582,8 @@ 
       tree set;
       if (retval == NULL_TREE)
 	set = NULL_TREE;
+      else if (retval == error_mark_node)
+	return error_mark_node;
       else
 	set = fold_build2_loc(this->location(), MODIFY_EXPR, void_type_node,
 			      DECL_RESULT(fndecl), retval);
@@ -2591,13 +2595,13 @@ 
     {
       gcc_assert(!VOID_TYPE_P(TREE_TYPE(TREE_TYPE(fndecl))));
       tree val = (*this->vals_->begin())->get_tree(context);
-      if (val == error_mark_node)
-	return error_mark_node;
       gcc_assert(results != NULL && results->size() == 1);
       val = Expression::convert_for_assignment(context,
 					       results->begin()->type(),
 					       (*this->vals_->begin())->type(),
 					       val, this->location());
+      if (val == error_mark_node)
+	return error_mark_node;
       tree set = build2(MODIFY_EXPR, void_type_node,
 			DECL_RESULT(fndecl), val);
       SET_EXPR_LOCATION(set, this->location());
@@ -2618,11 +2622,11 @@ 
 	{
 	  gcc_assert(pv != this->vals_->end());
 	  tree val = (*pv)->get_tree(context);
-	  if (val == error_mark_node)
-	    return error_mark_node;
 	  val = Expression::convert_for_assignment(context, pr->type(),
 						   (*pv)->type(), val,
 						   this->location());
+	  if (val == error_mark_node)
+	    return error_mark_node;
 	  tree set = build2(MODIFY_EXPR, void_type_node,
 			    build3(COMPONENT_REF, TREE_TYPE(field),
 				   retvar, field, NULL_TREE),