diff options
author | Ian Lance Taylor <ian@gcc.gnu.org> | 2012-05-15 22:30:37 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2012-05-15 22:30:37 +0000 |
commit | 87fd4bbf208d460e523cb56a501f63d3aab47cc5 (patch) | |
tree | 2790c4b5323e69dc5c2add072f456cf78a937843 /gcc | |
parent | efc704cb036749efaf05bcd0557e61df075b3b16 (diff) | |
download | gcc-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.cc | 58 |
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, |