-cd422bacf0505e9656661d97a571668ad1bde0fe
+91169ab206266361624236f0137668162ee8cb9b
The first line of this file holds the git revision number of the last
merge done from the gofrontend repository.
// Check types of an array index.
void
-Array_index_expression::do_check_types(Gogo* gogo)
+Array_index_expression::do_check_types(Gogo*)
{
Numeric_constant nc;
unsigned long v;
if (!this->array_->is_addressable())
this->report_error(_("slice of unaddressable value"));
else
- {
- bool escapes = true;
-
- // When compiling the runtime, a slice operation does not
- // cause local variables to escape. When escape analysis
- // becomes the default, this should be changed to make it an
- // error if we have a slice operation that escapes.
- if (gogo->compiling_runtime() && gogo->package_name() == "runtime")
- escapes = false;
-
- this->array_->address_taken(escapes);
- }
+ // Set the array address taken but not escape. The escape
+ // analysis will make it escape to heap when needed.
+ this->array_->address_taken(false);
}
}
Unary_expression* ue = expr->unary_expression();
if (ue != NULL)
ue->check_operand_address_taken(this->gogo_);
+
+ Array_index_expression* aie = expr->array_index_expression();
+ if (aie != NULL
+ && aie->end() != NULL
+ && !aie->array()->type()->is_slice_type())
+ {
+ // Slice of an array. The escape analysis models this with
+ // a child Node representing the address of the array.
+ bool escapes = false;
+ if (!this->gogo_->compiling_runtime()
+ || this->gogo_->package_name() != "runtime")
+ {
+ Node* n = Node::make_node(expr);
+ if (n->child() == NULL
+ || (n->child()->encoding() & ESCAPE_MASK) != Node::ESCAPE_NONE)
+ escapes = true;
+ }
+ aie->array()->address_taken(escapes);
+ }
return TRAVERSE_CONTINUE;
}