diff options
author | Ian Lance Taylor <ian@gcc.gnu.org> | 2011-02-24 03:01:22 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2011-02-24 03:01:22 +0000 |
commit | 76ace672dcbf704b27833e25c753298bd08af956 (patch) | |
tree | 51d6fb9452fd188f5ba831a740a8e56b7c188709 /gcc/go | |
parent | 63cc9deb7cad1672212fc84df0ca48900af236e6 (diff) | |
download | gcc-76ace672dcbf704b27833e25c753298bd08af956.zip gcc-76ace672dcbf704b27833e25c753298bd08af956.tar.gz gcc-76ace672dcbf704b27833e25c753298bd08af956.tar.bz2 |
Don't crash if a map index is used outside of a function.
From-SVN: r170453
Diffstat (limited to 'gcc/go')
-rw-r--r-- | gcc/go/gofrontend/expressions.cc | 46 |
1 files changed, 37 insertions, 9 deletions
diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc index e9a26a0..2e31e80 100644 --- a/gcc/go/gofrontend/expressions.cc +++ b/gcc/go/gofrontend/expressions.cc @@ -9888,12 +9888,39 @@ Map_index_expression::get_value_pointer(Translate_context* context, // We need to pass in a pointer to the key, so stuff it into a // variable. - tree tmp = create_tmp_var(TREE_TYPE(index_tree), get_name(index_tree)); - DECL_IGNORED_P(tmp) = 0; - DECL_INITIAL(tmp) = index_tree; - tree make_tmp = build1(DECL_EXPR, void_type_node, tmp); - tree tmpref = fold_convert(const_ptr_type_node, build_fold_addr_expr(tmp)); - TREE_ADDRESSABLE(tmp) = 1; + tree tmp; + tree make_tmp; + if (current_function_decl != NULL) + { + tmp = create_tmp_var(TREE_TYPE(index_tree), get_name(index_tree)); + DECL_IGNORED_P(tmp) = 0; + DECL_INITIAL(tmp) = index_tree; + make_tmp = build1(DECL_EXPR, void_type_node, tmp); + TREE_ADDRESSABLE(tmp) = 1; + } + else + { + tmp = build_decl(this->location(), VAR_DECL, create_tmp_var_name("M"), + TREE_TYPE(index_tree)); + DECL_EXTERNAL(tmp) = 0; + TREE_PUBLIC(tmp) = 0; + TREE_STATIC(tmp) = 1; + DECL_ARTIFICIAL(tmp) = 1; + if (!TREE_CONSTANT(index_tree)) + make_tmp = fold_build2_loc(this->location(), INIT_EXPR, void_type_node, + tmp, index_tree); + else + { + TREE_READONLY(tmp) = 1; + TREE_CONSTANT(tmp) = 1; + DECL_INITIAL(tmp) = index_tree; + make_tmp = NULL_TREE; + } + rest_of_decl_compilation(tmp, 1, 0); + } + tree tmpref = fold_convert_loc(this->location(), const_ptr_type_node, + build_fold_addr_expr_loc(this->location(), + tmp)); static tree map_index_fndecl; tree call = Gogo::call_builtin(&map_index_fndecl, @@ -9920,9 +9947,10 @@ Map_index_expression::get_value_pointer(Translate_context* context, return error_mark_node; tree ptr_val_type_tree = build_pointer_type(val_type_tree); - return build2(COMPOUND_EXPR, ptr_val_type_tree, - make_tmp, - fold_convert(ptr_val_type_tree, call)); + tree ret = fold_convert_loc(this->location(), ptr_val_type_tree, call); + if (make_tmp != NULL_TREE) + ret = build2(COMPOUND_EXPR, ptr_val_type_tree, make_tmp, ret); + return ret; } // Make a map index expression. |