aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2011-01-19 05:24:55 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2011-01-19 05:24:55 +0000
commit8386b63d3d95d4e14f220058c2c4a97044cafcc8 (patch)
treed0b7eaecff4011883b0652d507ab59ba492bc38c
parent85220919931d810f14b1acd77a402e53e828a3a8 (diff)
downloadgcc-8386b63d3d95d4e14f220058c2c4a97044cafcc8.zip
gcc-8386b63d3d95d4e14f220058c2c4a97044cafcc8.tar.gz
gcc-8386b63d3d95d4e14f220058c2c4a97044cafcc8.tar.bz2
Fix struct with field of pointer to array of same struct.
From-SVN: r168981
-rw-r--r--gcc/go/gofrontend/types.cc32
1 files changed, 29 insertions, 3 deletions
diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc
index 8bb2b72..dd0a861 100644
--- a/gcc/go/gofrontend/types.cc
+++ b/gcc/go/gofrontend/types.cc
@@ -3745,15 +3745,29 @@ Struct_type::fill_in_tree(Gogo* gogo, tree type)
{
tree field_trees = NULL_TREE;
tree* pp = &field_trees;
+ bool has_pointer = false;
for (Struct_field_list::const_iterator p = this->fields_->begin();
p != this->fields_->end();
++p)
{
std::string name = Gogo::unpack_hidden_name(p->field_name());
tree name_tree = get_identifier_with_length(name.data(), name.length());
- tree field_type_tree = p->type()->get_tree(gogo);
- if (field_type_tree == error_mark_node)
- return error_mark_node;
+
+ // Don't follow pointers yet, so that we don't get confused by a
+ // pointer to an array of this struct type.
+ tree field_type_tree;
+ if (p->type()->points_to() != NULL)
+ {
+ field_type_tree = ptr_type_node;
+ has_pointer = true;
+ }
+ else
+ {
+ field_type_tree = p->type()->get_tree(gogo);
+ if (field_type_tree == error_mark_node)
+ return error_mark_node;
+ }
+
tree field = build_decl(p->location(), FIELD_DECL, name_tree,
field_type_tree);
DECL_CONTEXT(field) = type;
@@ -3765,6 +3779,18 @@ Struct_type::fill_in_tree(Gogo* gogo, tree type)
layout_type(type);
+ if (has_pointer)
+ {
+ tree field = field_trees;
+ for (Struct_field_list::const_iterator p = this->fields_->begin();
+ p != this->fields_->end();
+ ++p, field = DECL_CHAIN(field))
+ {
+ if (p->type()->points_to() != NULL)
+ TREE_TYPE(field) = p->type()->get_tree(gogo);
+ }
+ }
+
return type;
}