Don't crash on erroneous receiver or parameters.
authorIan Lance Taylor <ian@gcc.gnu.org>
Tue, 14 Dec 2010 19:35:58 +0000 (19:35 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Tue, 14 Dec 2010 19:35:58 +0000 (19:35 +0000)
From-SVN: r167812

gcc/go/gofrontend/gogo-tree.cc

index 09f0d7cbd8cac744c12c93f9db8471a5b6873eaa..d9bf69af0b52706936692b01001b8942c870387c 100644 (file)
@@ -1388,6 +1388,8 @@ Function_declaration::get_or_make_decl(Gogo* gogo, Named_object* no, tree id)
 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 @@ Function::make_receiver_parm_decl(Gogo* gogo, Named_object* no, tree var_decl)
     {
       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 @@ Function::make_receiver_parm_decl(Gogo* gogo, Named_object* no, tree var_decl)
 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 @@ Function::build_tree(Gogo* gogo, Named_object* named_function)
              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 @@ Function::build_tree(Gogo* gogo, Named_object* named_function)
              // 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;
            }