From 87fd4bbf208d460e523cb56a501f63d3aab47cc5 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Tue, 15 May 2012 22:30:37 +0000 Subject: [PATCH] compiler: Sort array constructors by index. From-SVN: r187560 --- gcc/go/gofrontend/expressions.cc | 58 ++++++++++++++++++++++++++------ 1 file changed, 48 insertions(+), 10 deletions(-) diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc index 56df6f66b70..b3285480ca0 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& a, + const std::pair& 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* indexes = new std::vector; 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 > V; + + V v; + v.reserve(indexes->size()); + std::vector::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(); + 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, -- 2.30.2