Comments
Patch
@@ -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)
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