compiler: Sort array constructors by index.
authorIan Lance Taylor <ian@gcc.gnu.org>
Tue, 15 May 2012 22:30:37 +0000 (22:30 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Tue, 15 May 2012 22:30:37 +0000 (22:30 +0000)
From-SVN: r187560

gcc/go/gofrontend/expressions.cc

index 56df6f6..b328548 100644 (file)
@@ -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,