aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2013-11-08 17:35:24 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2013-11-08 17:35:24 +0000
commit68607055124d868de0a7a9f1a3a97a8cdc2a090a (patch)
tree8e018764c60906923b4368389d32c187887c5e74 /gcc
parente15c474a348d9c9e037b1f3d62b58d1c431b8cf2 (diff)
downloadgcc-68607055124d868de0a7a9f1a3a97a8cdc2a090a.zip
gcc-68607055124d868de0a7a9f1a3a97a8cdc2a090a.tar.gz
gcc-68607055124d868de0a7a9f1a3a97a8cdc2a090a.tar.bz2
compiler: Fix bogus init loop error with struct composite literal.
This should eventually be bug482.go in the master testsuite. From-SVN: r204583
Diffstat (limited to 'gcc')
-rw-r--r--gcc/go/gofrontend/expressions.cc48
1 files changed, 45 insertions, 3 deletions
diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc
index 7269f58..aefb51c 100644
--- a/gcc/go/gofrontend/expressions.cc
+++ b/gcc/go/gofrontend/expressions.cc
@@ -13488,10 +13488,52 @@ class Composite_literal_expression : public Parser_expression
int
Composite_literal_expression::do_traverse(Traverse* traverse)
{
- if (this->vals_ != NULL
- && this->vals_->traverse(traverse) == TRAVERSE_EXIT)
+ if (Type::traverse(this->type_, traverse) == TRAVERSE_EXIT)
return TRAVERSE_EXIT;
- return Type::traverse(this->type_, traverse);
+
+ // If this is a struct composite literal with keys, then the keys
+ // are field names, not expressions. We don't want to traverse them
+ // in that case. If we do, we can give an erroneous error "variable
+ // initializer refers to itself." See bug482.go in the testsuite.
+ if (this->has_keys_ && this->vals_ != NULL)
+ {
+ // The type may not be resolvable at this point.
+ Type* type = this->type_;
+ while (true)
+ {
+ if (type->classification() == Type::TYPE_NAMED)
+ type = type->named_type()->real_type();
+ else if (type->classification() == Type::TYPE_FORWARD)
+ {
+ Type* t = type->forwarded();
+ if (t == type)
+ break;
+ type = t;
+ }
+ else
+ break;
+ }
+
+ if (type->classification() == Type::TYPE_STRUCT)
+ {
+ Expression_list::iterator p = this->vals_->begin();
+ while (p != this->vals_->end())
+ {
+ // Skip key.
+ ++p;
+ go_assert(p != this->vals_->end());
+ if (Expression::traverse(&*p, traverse) == TRAVERSE_EXIT)
+ return TRAVERSE_EXIT;
+ ++p;
+ }
+ return TRAVERSE_CONTINUE;
+ }
+ }
+
+ if (this->vals_ != NULL)
+ return this->vals_->traverse(traverse);
+
+ return TRAVERSE_CONTINUE;
}
// Lower a generic composite literal into a specific version based on