diff mbox

Go patch committed: Handle array of pointers to same array

Message ID mcr39ne14rs.fsf@google.com
State New
Headers show

Commit Message

Ian Lance Taylor Feb. 24, 2011, 3:37 a.m. UTC
This patch to the Go frontend fixes it to correctly handle an array to
pointers of the same array, as in "type T [1]*T".  This patch
unfortunately duplicate some of what build_array_type does.
Bootstrapped and ran Go testsuite on x86_64-unknown-linux-gnu.
Committed to mainline.

Ian
diff mbox

Patch

diff -r f0f60b7089c7 go/types.cc
--- a/go/types.cc	Wed Feb 23 19:00:32 2011 -0800
+++ b/go/types.cc	Wed Feb 23 19:33:50 2011 -0800
@@ -4442,33 +4442,59 @@ 
   if (this->length_ == NULL)
     {
       tree struct_type = gogo->slice_type_tree(void_type_node);
-      return this->fill_in_tree(gogo, struct_type);
+      return this->fill_in_slice_tree(gogo, struct_type);
     }
   else
     {
-      tree element_type_tree = this->element_type_->get_tree(gogo);
-      tree length_tree = this->get_length_tree(gogo);
-      if (element_type_tree == error_mark_node
-	  || length_tree == error_mark_node)
-	return error_mark_node;
-
-      length_tree = fold_convert(sizetype, length_tree);
-
-      // build_index_type takes the maximum index, which is one less
-      // than the length.
-      tree index_type = build_index_type(fold_build2(MINUS_EXPR, sizetype,
-						     length_tree,
-						     size_one_node));
-
-      return build_array_type(element_type_tree, index_type);
-    }
+      tree array_type = make_node(ARRAY_TYPE);
+      return this->fill_in_array_tree(gogo, array_type);
+    }
+}
+
+// Fill in the fields for an array type.  This is used for named array
+// types.
+
+tree
+Array_type::fill_in_array_tree(Gogo* gogo, tree array_type)
+{
+  gcc_assert(this->length_ != NULL);
+
+  tree element_type_tree = this->element_type_->get_tree(gogo);
+  tree length_tree = this->get_length_tree(gogo);
+  if (element_type_tree == error_mark_node
+      || length_tree == error_mark_node)
+    return error_mark_node;
+
+  length_tree = fold_convert(sizetype, length_tree);
+
+  // build_index_type takes the maximum index, which is one less than
+  // the length.
+  tree index_type = build_index_type(fold_build2(MINUS_EXPR, sizetype,
+						 length_tree,
+						 size_one_node));
+
+  TREE_TYPE(array_type) = element_type_tree;
+  TYPE_DOMAIN(array_type) = index_type;
+  TYPE_ADDR_SPACE(array_type) = TYPE_ADDR_SPACE(element_type_tree);
+  layout_type(array_type);
+
+  if (TYPE_STRUCTURAL_EQUALITY_P(element_type_tree)
+      || TYPE_STRUCTURAL_EQUALITY_P(index_type))
+    SET_TYPE_STRUCTURAL_EQUALITY(array_type);
+  else if (TYPE_CANONICAL(element_type_tree) != element_type_tree
+	   || TYPE_CANONICAL(index_type) != index_type)
+    TYPE_CANONICAL(array_type) =
+      build_array_type(TYPE_CANONICAL(element_type_tree),
+		       TYPE_CANONICAL(index_type));
+
+  return array_type;
 }
 
 // Fill in the fields for a slice type.  This is used for named slice
 // types.
 
 tree
-Array_type::fill_in_tree(Gogo* gogo, tree struct_type)
+Array_type::fill_in_slice_tree(Gogo* gogo, tree struct_type)
 {
   gcc_assert(this->length_ == NULL);
 
@@ -7129,15 +7155,19 @@ 
       break;
 
     case TYPE_ARRAY:
+      if (this->named_tree_ != NULL_TREE)
+	return this->named_tree_;
       if (!this->is_open_array_type())
-	t = Type::get_named_type_tree(gogo, this->type_);
+	{
+	  t = make_node(ARRAY_TYPE);
+	  this->named_tree_ = t;
+	  t = this->type_->array_type()->fill_in_array_tree(gogo, t);
+	}
       else
 	{
-	  if (this->named_tree_ != NULL_TREE)
-	    return this->named_tree_;
 	  t = gogo->slice_type_tree(void_type_node);
 	  this->named_tree_ = t;
-	  t = this->type_->array_type()->fill_in_tree(gogo, t);
+	  t = this->type_->array_type()->fill_in_slice_tree(gogo, t);
 	}
       if (t == error_mark_node)
 	return error_mark_node;
diff -r f0f60b7089c7 go/types.h
--- a/go/types.h	Wed Feb 23 19:00:32 2011 -0800
+++ b/go/types.h	Wed Feb 23 19:33:50 2011 -0800
@@ -2050,9 +2050,13 @@ 
   static Array_type*
   do_import(Import*);
 
+  // Fill in the fields for a named array type.
+  tree
+  fill_in_array_tree(Gogo*, tree);
+
   // Fill in the fields for a named slice type.
   tree
-  fill_in_tree(Gogo*, tree);
+  fill_in_slice_tree(Gogo*, tree);
 
  protected:
   int