Commit 87fd4bbf by Ian Lance Taylor

compiler: Sort array constructors by index.

From-SVN: r187560
parent efc704cb
...@@ -11794,8 +11794,7 @@ Open_array_construction_expression::do_get_tree(Translate_context* context) ...@@ -11794,8 +11794,7 @@ Open_array_construction_expression::do_get_tree(Translate_context* context)
if (this->indexes() == NULL) if (this->indexes() == NULL)
max_index = this->vals()->size() - 1; max_index = this->vals()->size() - 1;
else else
max_index = *std::max_element(this->indexes()->begin(), max_index = this->indexes()->back();
this->indexes()->end());
tree max_tree = size_int(max_index); tree max_tree = size_int(max_index);
tree constructor_type = build_array_type(element_type_tree, tree constructor_type = build_array_type(element_type_tree,
build_index_type(max_tree)); build_index_type(max_tree));
...@@ -12546,6 +12545,17 @@ Composite_literal_expression::lower_struct(Gogo* gogo, Type* type) ...@@ -12546,6 +12545,17 @@ Composite_literal_expression::lower_struct(Gogo* gogo, Type* type)
return ret; return ret;
} }
// Used to sort an index/value array.
class Index_value_compare
{
public:
bool
operator()(const std::pair<unsigned long, Expression*>& a,
const std::pair<unsigned long, Expression*>& b)
{ return a.first < b.first; }
};
// Lower an array composite literal. // Lower an array composite literal.
Expression* Expression*
...@@ -12557,6 +12567,7 @@ Composite_literal_expression::lower_array(Type* type) ...@@ -12557,6 +12567,7 @@ Composite_literal_expression::lower_array(Type* type)
std::vector<unsigned long>* indexes = new std::vector<unsigned long>; std::vector<unsigned long>* indexes = new std::vector<unsigned long>;
indexes->reserve(this->vals_->size()); indexes->reserve(this->vals_->size());
bool indexes_out_of_order = false;
Expression_list* vals = new Expression_list(); Expression_list* vals = new Expression_list();
vals->reserve(this->vals_->size()); vals->reserve(this->vals_->size());
unsigned long index = 0; unsigned long index = 0;
...@@ -12627,6 +12638,9 @@ Composite_literal_expression::lower_array(Type* type) ...@@ -12627,6 +12638,9 @@ Composite_literal_expression::lower_array(Type* type)
return Expression::make_error(location); return Expression::make_error(location);
} }
if (!indexes->empty() && index < indexes->back())
indexes_out_of_order = true;
indexes->push_back(index); indexes->push_back(index);
} }
...@@ -12641,6 +12655,34 @@ Composite_literal_expression::lower_array(Type* type) ...@@ -12641,6 +12655,34 @@ Composite_literal_expression::lower_array(Type* type)
indexes = NULL; indexes = NULL;
} }
if (indexes_out_of_order)
{
typedef std::vector<std::pair<unsigned long, Expression*> > V;
V v;
v.reserve(indexes->size());
std::vector<unsigned long>::const_iterator pi = indexes->begin();
for (Expression_list::const_iterator pe = vals->begin();
pe != vals->end();
++pe, ++pi)
v.push_back(std::make_pair(*pi, *pe));
std::sort(v.begin(), v.end(), Index_value_compare());
delete indexes;
delete vals;
indexes = new std::vector<unsigned long>();
indexes->reserve(v.size());
vals = new Expression_list();
vals->reserve(v.size());
for (V::const_iterator p = v.begin(); p != v.end(); ++p)
{
indexes->push_back(p->first);
vals->push_back(p->second);
}
}
return this->make_array(type, indexes, vals); return this->make_array(type, indexes, vals);
} }
...@@ -12661,7 +12703,9 @@ Composite_literal_expression::make_array( ...@@ -12661,7 +12703,9 @@ Composite_literal_expression::make_array(
size_t size; size_t size;
if (vals == NULL) if (vals == NULL)
size = 0; size = 0;
else if (indexes == NULL) else if (indexes != NULL)
size = indexes->back() + 1;
else
{ {
size = vals->size(); size = vals->size();
Integer_type* it = Type::lookup_integer_type("int")->integer_type(); Integer_type* it = Type::lookup_integer_type("int")->integer_type();
...@@ -12672,11 +12716,6 @@ Composite_literal_expression::make_array( ...@@ -12672,11 +12716,6 @@ Composite_literal_expression::make_array(
return Expression::make_error(location); return Expression::make_error(location);
} }
} }
else
{
size = *std::max_element(indexes->begin(), indexes->end());
++size;
}
mpz_t vlen; mpz_t vlen;
mpz_init_set_ui(vlen, size); mpz_init_set_ui(vlen, size);
...@@ -12704,8 +12743,7 @@ Composite_literal_expression::make_array( ...@@ -12704,8 +12743,7 @@ Composite_literal_expression::make_array(
} }
else else
{ {
unsigned long max = *std::max_element(indexes->begin(), unsigned long max = indexes->back();
indexes->end());
if (max >= val) if (max >= val)
{ {
error_at(location, error_at(location,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment