This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[gccgo] Always copy slice constructor in function
- From: Ian Lance Taylor <iant at google dot com>
- To: gcc-patches at gcc dot gnu dot org, gofrontend-dev at googlegroups dot com
- Date: Wed, 30 Jun 2010 14:53:06 -0700
- Subject: [gccgo] Always copy slice constructor in function
When a slice constructor is used in a function, as in a := []byte{0},
the program must always create a new copy even if the values are
constant. This is not necessary outside of a function, as in that case
the value will only be built once. This patch corrects gccgo to make a
copy when required. Committed to gccgo branch.
Ian
diff -r 7c31cf858582 go/expressions.cc
--- a/go/expressions.cc Wed Jun 30 14:29:56 2010 -0700
+++ b/go/expressions.cc Wed Jun 30 14:47:58 2010 -0700
@@ -11055,9 +11055,10 @@
if (values == error_mark_node)
return error_mark_node;
- tree space;
- tree set;
- if (TREE_CONSTANT(values))
+ bool is_constant_initializer = TREE_CONSTANT(values);
+ bool is_in_function = context->function() != NULL;
+
+ if (is_constant_initializer)
{
tree tmp = build_decl(this->location(), VAR_DECL,
create_tmp_var_name("C"), TREE_TYPE(values));
@@ -11065,11 +11066,27 @@
TREE_PUBLIC(tmp) = 0;
TREE_STATIC(tmp) = 1;
DECL_ARTIFICIAL(tmp) = 1;
- // We can't make the decl readonly, because the program can
- // change the values in the array.
+ if (is_in_function)
+ {
+ // 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.
+ TREE_READONLY(tmp) = 1;
+ TREE_CONSTANT(tmp) = 1;
+ }
DECL_INITIAL(tmp) = values;
rest_of_decl_compilation(tmp, 1, 0);
- space = build_fold_addr_expr(tmp);
+ values = tmp;
+ }
+
+ tree space;
+ tree set;
+ if (!is_in_function && is_constant_initializer)
+ {
+ // Outside of a function, we know the initializer will only run
+ // once.
+ space = build_fold_addr_expr(values);
set = NULL_TREE;
}
else
@@ -11109,7 +11126,7 @@
elt->value = fold_convert(TREE_TYPE(field), length_tree);
tree constructor = build_constructor(type_tree, init);
- if (TREE_CONSTANT(values))
+ if (!is_in_function && is_constant_initializer)
TREE_CONSTANT(constructor) = 1;
if (set == NULL_TREE)