aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2012-05-15 22:30:37 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2012-05-15 22:30:37 +0000
commit87fd4bbf208d460e523cb56a501f63d3aab47cc5 (patch)
tree2790c4b5323e69dc5c2add072f456cf78a937843 /gcc
parentefc704cb036749efaf05bcd0557e61df075b3b16 (diff)
downloadgcc-87fd4bbf208d460e523cb56a501f63d3aab47cc5.zip
gcc-87fd4bbf208d460e523cb56a501f63d3aab47cc5.tar.gz
gcc-87fd4bbf208d460e523cb56a501f63d3aab47cc5.tar.bz2
compiler: Sort array constructors by index.
From-SVN: r187560
Diffstat (limited to 'gcc')
-rw-r--r--gcc/go/gofrontend/expressions.cc58
1 files changed, 48 insertions, 10 deletions
diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc
index 56df6f6..b328548 100644
--- a/gcc/go/gofrontend/expressions.cc
+++ b/gcc/go/gofrontend/expressions.cc
@@ -11794,8 +11794,7 @@ Open_array_construction_expression::do_get_tree(Translate_context* context)
if (this->indexes() == NULL)
max_index = this->vals()->size() - 1;
else
- max_index = *std::max_element(this->indexes()->begin(),
- this->indexes()->end());
+ max_index = this->indexes()->back();
tree max_tree = size_int(max_index);
tree constructor_type = build_array_type(element_type_tree,
build_index_type(max_tree));
@@ -12546,6 +12545,17 @@ Composite_literal_expression::lower_struct(Gogo* gogo, Type* type)
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.
Expression*
@@ -12557,6 +12567,7 @@ Composite_literal_expression::lower_array(Type* type)
std::vector<unsigned long>* indexes = new std::vector<unsigned long>;
indexes->reserve(this->vals_->size());
+ bool indexes_out_of_order = false;
Expression_list* vals = new Expression_list();
vals->reserve(this->vals_->size());
unsigned long index = 0;
@@ -12627,6 +12638,9 @@ Composite_literal_expression::lower_array(Type* type)
return Expression::make_error(location);
}
+ if (!indexes->empty() && index < indexes->back())
+ indexes_out_of_order = true;
+
indexes->push_back(index);
}
@@ -12641,6 +12655,34 @@ Composite_literal_expression::lower_array(Type* type)
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);
}
@@ -12661,7 +12703,9 @@ Composite_literal_expression::make_array(
size_t size;
if (vals == NULL)
size = 0;
- else if (indexes == NULL)
+ else if (indexes != NULL)
+ size = indexes->back() + 1;
+ else
{
size = vals->size();
Integer_type* it = Type::lookup_integer_type("int")->integer_type();
@@ -12672,11 +12716,6 @@ Composite_literal_expression::make_array(
return Expression::make_error(location);
}
}
- else
- {
- size = *std::max_element(indexes->begin(), indexes->end());
- ++size;
- }
mpz_t vlen;
mpz_init_set_ui(vlen, size);
@@ -12704,8 +12743,7 @@ Composite_literal_expression::make_array(
}
else
{
- unsigned long max = *std::max_element(indexes->begin(),
- indexes->end());
+ unsigned long max = indexes->back();
if (max >= val)
{
error_at(location,