===================================================================
@@ -1,4 +1,4 @@
-2c62d5223e814887801b1540162c72b90299d910
+7fa4eb4b7a32953c2e838f1b0c684a6733172b43
The first line of this file holds the git revision number of the last
merge done from the gofrontend repository.
===================================================================
@@ -3878,35 +3878,54 @@ Unary_expression::do_is_static_initializ
if (this->op_ == OPERATOR_MULT)
return false;
else if (this->op_ == OPERATOR_AND)
- {
- // The address of a global variable can used as a static
- // initializer.
- Var_expression* ve = this->expr_->var_expression();
- if (ve != NULL)
- {
- Named_object* no = ve->named_object();
- return no->is_variable() && no->var_value()->is_global();
- }
-
- // The address of a composite literal can be used as a static
- // initializer if the composite literal is itself usable as a
- // static initializer.
- if (this->expr_->is_composite_literal()
- && this->expr_->is_static_initializer())
- return true;
-
- // The address of a string constant can be used as a static
- // initializer. This can not be written in Go itself but this
- // is used when building a type descriptor.
- if (this->expr_->string_expression() != NULL)
- return true;
-
- return false;
- }
+ return Unary_expression::base_is_static_initializer(this->expr_);
else
return this->expr_->is_static_initializer();
}
+// Return whether the address of EXPR can be used as a static
+// initializer.
+
+bool
+Unary_expression::base_is_static_initializer(Expression* expr)
+{
+ // The address of a field reference can be a static initializer if
+ // the base can be a static initializer.
+ Field_reference_expression* fre = expr->field_reference_expression();
+ if (fre != NULL)
+ return Unary_expression::base_is_static_initializer(fre->expr());
+
+ // The address of an index expression can be a static initializer if
+ // the base can be a static initializer and the index is constant.
+ Array_index_expression* aind = expr->array_index_expression();
+ if (aind != NULL)
+ return (aind->end() == NULL
+ && aind->start()->is_constant()
+ && Unary_expression::base_is_static_initializer(aind->array()));
+
+ // The address of a global variable can be a static initializer.
+ Var_expression* ve = expr->var_expression();
+ if (ve != NULL)
+ {
+ Named_object* no = ve->named_object();
+ return no->is_variable() && no->var_value()->is_global();
+ }
+
+ // The address of a composite literal can be used as a static
+ // initializer if the composite literal is itself usable as a
+ // static initializer.
+ if (expr->is_composite_literal() && expr->is_static_initializer())
+ return true;
+
+ // The address of a string constant can be used as a static
+ // initializer. This can not be written in Go itself but this is
+ // used when building a type descriptor.
+ if (expr->string_expression() != NULL)
+ return true;
+
+ return false;
+}
+
// Apply unary opcode OP to UNC, setting NC. Return true if this
// could be done, false if not. On overflow, issues an error and sets
// *ISSUED_ERROR.
@@ -12460,6 +12479,17 @@ Struct_construction_expression::do_is_st
if (*pv != NULL && !(*pv)->is_static_initializer())
return false;
}
+
+ const Struct_field_list* fields = this->type_->struct_type()->fields();
+ for (Struct_field_list::const_iterator pf = fields->begin();
+ pf != fields->end();
+ ++pf)
+ {
+ // There are no constant constructors for interfaces.
+ if (pf->type()->interface_type() != NULL)
+ return false;
+ }
+
return true;
}
@@ -12550,7 +12580,7 @@ Struct_construction_expression::do_flatt
return this;
// If this is a constant struct, we don't need temporaries.
- if (this->is_constant_struct())
+ if (this->is_constant_struct() || this->is_static_initializer())
return this;
Location loc = this->location();
@@ -12701,6 +12731,11 @@ Array_construction_expression::do_is_sta
{
if (this->vals() == NULL)
return true;
+
+ // There are no constant constructors for interfaces.
+ if (this->type_->array_type()->element_type()->interface_type() != NULL)
+ return false;
+
for (Expression_list::const_iterator pv = this->vals()->begin();
pv != this->vals()->end();
++pv)
@@ -12765,7 +12800,7 @@ Array_construction_expression::do_flatte
return this;
// If this is a constant array, we don't need temporaries.
- if (this->is_constant_array())
+ if (this->is_constant_array() || this->is_static_initializer())
return this;
Location loc = this->location();
===================================================================
@@ -1842,6 +1842,9 @@ class Unary_expression : public Expressi
{ this->issue_nil_check_ = (this->op_ == OPERATOR_MULT); }
private:
+ static bool
+ base_is_static_initializer(Expression*);
+
// The unary operator to apply.
Operator op_;
// Normally true. False if this is an address expression which does
@@ -2640,6 +2643,26 @@ class Array_index_expression : public Ex
array() const
{ return this->array_; }
+ // Return the index of a simple index expression, or the start index
+ // of a slice expression.
+ Expression*
+ start()
+ { return this->start_; }
+
+ const Expression*
+ start() const
+ { return this->start_; }
+
+ // Return the end index of a slice expression. This is NULL for a
+ // simple index expression.
+ Expression*
+ end()
+ { return this->end_; }
+
+ const Expression*
+ end() const
+ { return this->end_; }
+
protected:
int
do_traverse(Traverse*);