Patchwork Go patch committed: Don't crash on invalid receiver or parameters

login
register
mail settings
Submitter Ian Taylor
Date Dec. 14, 2010, 7:36 p.m.
Message ID <mcrmxo887vh.fsf@google.com>
Download mbox | patch
Permalink /patch/75527/
State New
Headers show

Comments

Ian Taylor - Dec. 14, 2010, 7:36 p.m.
This patch to the Go frontend avoids crashing on invalid function
receiver or parameters.  Bootstrapped and ran Go testsuite on
x86_64-unknown-linux-gnu.  Committed to mainline.

This is Go issue 1347.

Ian

Patch

diff -r 177a6b3ab2e4 go/gogo-tree.cc
--- a/go/gogo-tree.cc	Tue Dec 14 11:25:01 2010 -0800
+++ b/go/gogo-tree.cc	Tue Dec 14 11:33:07 2010 -0800
@@ -1388,6 +1388,8 @@ 
 tree
 Function::make_receiver_parm_decl(Gogo* gogo, Named_object* no, tree var_decl)
 {
+  if (var_decl == error_mark_node)
+    return error_mark_node;
   // If the function takes the address of a receiver which is passed
   // by value, then we will have an INDIRECT_REF here.  We need to get
   // the real variable.
@@ -1402,6 +1404,8 @@ 
     {
       gcc_assert(is_in_heap);
       var_decl = TREE_OPERAND(var_decl, 0);
+      if (var_decl == error_mark_node)
+	return error_mark_node;
       gcc_assert(POINTER_TYPE_P(TREE_TYPE(var_decl)));
       val_type = TREE_TYPE(TREE_TYPE(var_decl));
     }
@@ -1460,9 +1464,14 @@ 
 tree
 Function::copy_parm_to_heap(Gogo* gogo, Named_object* no, tree ref)
 {
+  if (ref == error_mark_node)
+    return error_mark_node;
+
   gcc_assert(TREE_CODE(ref) == INDIRECT_REF);
 
   tree var_decl = TREE_OPERAND(ref, 0);
+  if (var_decl == error_mark_node)
+    return error_mark_node;
   gcc_assert(TREE_CODE(var_decl) == VAR_DECL);
   source_location loc = DECL_SOURCE_LOCATION(var_decl);
 
@@ -1523,9 +1532,12 @@ 
 	      tree var = *pp;
 	      if (TREE_CODE(var) == INDIRECT_REF)
 		var = TREE_OPERAND(var, 0);
-	      gcc_assert(TREE_CODE(var) == VAR_DECL);
-	      DECL_CHAIN(var) = declare_vars;
-	      declare_vars = var;
+	      if (var != error_mark_node)
+		{
+		  gcc_assert(TREE_CODE(var) == VAR_DECL);
+		  DECL_CHAIN(var) = declare_vars;
+		  declare_vars = var;
+		}
 	      *pp = parm_decl;
 	    }
 	  else if ((*p)->var_value()->is_in_heap())
@@ -1533,11 +1545,17 @@ 
 	      // If we take the address of a parameter, then we need
 	      // to copy it into the heap.
 	      tree parm_decl = this->copy_parm_to_heap(gogo, *p, *pp);
-	      gcc_assert(TREE_CODE(*pp) == INDIRECT_REF);
-	      tree var_decl = TREE_OPERAND(*pp, 0);
-	      gcc_assert(TREE_CODE(var_decl) == VAR_DECL);
-	      DECL_CHAIN(var_decl) = declare_vars;
-	      declare_vars = var_decl;
+	      if (*pp != error_mark_node)
+		{
+		  gcc_assert(TREE_CODE(*pp) == INDIRECT_REF);
+		  tree var_decl = TREE_OPERAND(*pp, 0);
+		  if (var_decl != error_mark_node)
+		    {
+		      gcc_assert(TREE_CODE(var_decl) == VAR_DECL);
+		      DECL_CHAIN(var_decl) = declare_vars;
+		      declare_vars = var_decl;
+		    }
+		}
 	      *pp = parm_decl;
 	    }