aboutsummaryrefslogtreecommitdiff
path: root/gcc/go
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2010-12-14 19:35:58 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2010-12-14 19:35:58 +0000
commit5b0e99c90ea5815453c746368d9f66e485b40680 (patch)
treeb2c04d7ab2a859d213441783890952236d901ce4 /gcc/go
parentcd96b4e2dbe471bbf3e743cd571b9a16f002a8a7 (diff)
downloadgcc-5b0e99c90ea5815453c746368d9f66e485b40680.zip
gcc-5b0e99c90ea5815453c746368d9f66e485b40680.tar.gz
gcc-5b0e99c90ea5815453c746368d9f66e485b40680.tar.bz2
Don't crash on erroneous receiver or parameters.
From-SVN: r167812
Diffstat (limited to 'gcc/go')
-rw-r--r--gcc/go/gofrontend/gogo-tree.cc34
1 files changed, 26 insertions, 8 deletions
diff --git a/gcc/go/gofrontend/gogo-tree.cc b/gcc/go/gofrontend/gogo-tree.cc
index 09f0d7c..d9bf69a 100644
--- a/gcc/go/gofrontend/gogo-tree.cc
+++ b/gcc/go/gofrontend/gogo-tree.cc
@@ -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;
}