diff options
author | Ian Lance Taylor <ian@gcc.gnu.org> | 2012-05-15 22:54:28 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2012-05-15 22:54:28 +0000 |
commit | df4ddb118ad80db541a25d90b6a025fa003c0104 (patch) | |
tree | 6572c3944eaba251d6b52e5f938129e814e8c364 | |
parent | 8345ae9343d696fdbfbd4c6b72928c6aa5ac695d (diff) | |
download | gcc-df4ddb118ad80db541a25d90b6a025fa003c0104.zip gcc-df4ddb118ad80db541a25d90b6a025fa003c0104.tar.gz gcc-df4ddb118ad80db541a25d90b6a025fa003c0104.tar.bz2 |
compiler: Fix taking address of constant outside of function.
From-SVN: r187565
-rw-r--r-- | gcc/go/gofrontend/expressions.cc | 49 |
1 files changed, 40 insertions, 9 deletions
diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc index b328548..1585150 100644 --- a/gcc/go/gofrontend/expressions.cc +++ b/gcc/go/gofrontend/expressions.cc @@ -4048,15 +4048,46 @@ Unary_expression::do_get_tree(Translate_context* context) && TREE_CODE(expr) != INDIRECT_REF && TREE_CODE(expr) != COMPONENT_REF) { - tree tmp = create_tmp_var(TREE_TYPE(expr), get_name(expr)); - DECL_IGNORED_P(tmp) = 1; - DECL_INITIAL(tmp) = expr; - TREE_ADDRESSABLE(tmp) = 1; - return build2_loc(loc.gcc_location(), COMPOUND_EXPR, - build_pointer_type(TREE_TYPE(expr)), - build1_loc(loc.gcc_location(), DECL_EXPR, - void_type_node, tmp), - build_fold_addr_expr_loc(loc.gcc_location(), tmp)); + if (current_function_decl != NULL) + { + tree tmp = create_tmp_var(TREE_TYPE(expr), get_name(expr)); + DECL_IGNORED_P(tmp) = 1; + DECL_INITIAL(tmp) = expr; + TREE_ADDRESSABLE(tmp) = 1; + return build2_loc(loc.gcc_location(), COMPOUND_EXPR, + build_pointer_type(TREE_TYPE(expr)), + build1_loc(loc.gcc_location(), DECL_EXPR, + void_type_node, tmp), + build_fold_addr_expr_loc(loc.gcc_location(), + tmp)); + } + else + { + tree tmp = build_decl(loc.gcc_location(), VAR_DECL, + create_tmp_var_name("A"), TREE_TYPE(expr)); + DECL_EXTERNAL(tmp) = 0; + TREE_PUBLIC(tmp) = 0; + TREE_STATIC(tmp) = 1; + DECL_ARTIFICIAL(tmp) = 1; + TREE_ADDRESSABLE(tmp) = 1; + tree make_tmp; + if (!TREE_CONSTANT(expr)) + make_tmp = fold_build2_loc(loc.gcc_location(), INIT_EXPR, + void_type_node, tmp, expr); + else + { + TREE_READONLY(tmp) = 1; + TREE_CONSTANT(tmp) = 1; + DECL_INITIAL(tmp) = expr; + make_tmp = NULL_TREE; + } + rest_of_decl_compilation(tmp, 1, 0); + tree addr = build_fold_addr_expr_loc(loc.gcc_location(), tmp); + if (make_tmp == NULL_TREE) + return addr; + return build2_loc(loc.gcc_location(), COMPOUND_EXPR, + TREE_TYPE(addr), make_tmp, addr); + } } return build_fold_addr_expr_loc(loc.gcc_location(), expr); |