aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2011-01-26 19:48:47 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2011-01-26 19:48:47 +0000
commit01c599966bcea004fd37c6b1e6328d1ee5d27c5d (patch)
treee9c89bf845eb427a7d933ace41b34b9148b4bec3 /gcc
parente435f0985f7bd7155531d2c31ab2be113be12909 (diff)
downloadgcc-01c599966bcea004fd37c6b1e6328d1ee5d27c5d.zip
gcc-01c599966bcea004fd37c6b1e6328d1ee5d27c5d.tar.gz
gcc-01c599966bcea004fd37c6b1e6328d1ee5d27c5d.tar.bz2
Copy initializer to heap if it may contain pointers.
From-SVN: r169297
Diffstat (limited to 'gcc')
-rw-r--r--gcc/go/gofrontend/expressions.cc27
1 files changed, 17 insertions, 10 deletions
diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc
index 8eefaee..739032b 100644
--- a/gcc/go/gofrontend/expressions.cc
+++ b/gcc/go/gofrontend/expressions.cc
@@ -11138,7 +11138,15 @@ Open_array_construction_expression::do_get_tree(Translate_context* context)
return error_mark_node;
bool is_constant_initializer = TREE_CONSTANT(values);
- bool is_in_function = context->function() != NULL;
+
+ // We have to copy the initial values into heap memory if we are in
+ // a function or if the values are not constants. We also have to
+ // copy them if they may contain pointers in a non-constant context,
+ // as otherwise the garbage collector won't see them.
+ bool copy_to_heap = (context->function() != NULL
+ || !is_constant_initializer
+ || (element_type->has_pointer()
+ && !context->is_const()));
if (is_constant_initializer)
{
@@ -11148,12 +11156,12 @@ Open_array_construction_expression::do_get_tree(Translate_context* context)
TREE_PUBLIC(tmp) = 0;
TREE_STATIC(tmp) = 1;
DECL_ARTIFICIAL(tmp) = 1;
- if (is_in_function)
+ if (copy_to_heap)
{
- // If this is not a function, we will only initialize the
- // value once, so we can use this directly rather than
- // copying it. In that case we can't make it read-only,
- // because the program is permitted to change it.
+ // If we are not copying the value to the heap, we will only
+ // initialize the value once, so we can use this directly
+ // rather than copying it. In that case we can't make it
+ // read-only, because the program is permitted to change it.
TREE_READONLY(tmp) = 1;
TREE_CONSTANT(tmp) = 1;
}
@@ -11164,10 +11172,9 @@ Open_array_construction_expression::do_get_tree(Translate_context* context)
tree space;
tree set;
- if (!is_in_function && is_constant_initializer)
+ if (!copy_to_heap)
{
- // Outside of a function, we know the initializer will only run
- // once.
+ // the initializer will only run once.
space = build_fold_addr_expr(values);
set = NULL_TREE;
}
@@ -11214,7 +11221,7 @@ Open_array_construction_expression::do_get_tree(Translate_context* context)
tree constructor = build_constructor(type_tree, init);
if (constructor == error_mark_node)
return error_mark_node;
- if (!is_in_function && is_constant_initializer)
+ if (!copy_to_heap)
TREE_CONSTANT(constructor) = 1;
if (set == NULL_TREE)